IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Introducció

La forma més bàsica de programar tasques és utilitzar l'eina Cron (i les seves variants o eines que es basen en). Des de la perspectiva dels desenvolupadors però crear una tasca cron per cada tasca que hem de programar té diversos inconvenients com per exemple:

  • La programació de tasca deixa de formar part del codi de l'aplicació. Creem doncs una dependència d'un tercer (Cron)
  • Cada tasca nova em de modificar cron
  • En explotació cal accedir via SSH al servidor per afegir una tasca
  • La planificació de les tasques (entrades cron) no formen part del codi com hem dit i per tant no poden anar al nostre control de versions (CVS/Git)
  • No tenim una interfície de programació (API) per afegir tasques, executar tasques, etc.

Amb Laravel Scheduler només caldrà afegir una entrada a cron i un cop afegida aquesta entrada podrem planificar utilitzant Laravel

Instal·lació de Laravel Scheduler a cron

Cal afegir la línia:

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

Al cron. Això fa que cada minut s'executi el planificador propi de la vostra aplicació utilitzant la comanda:

$ php artisan schedule:run

Internals

El servei de planificació de tasques a Laravel l'ofereix el Service Provider:

Illuminate\Console\ScheduleServiceProvider [1] 

Si us fixeu l'únic que fa es crear una comanda a mida per a php artisan (comanda schedule:run [2]).

Aquest service provider el teniu disponible a partir del service provider (que és de tipus AggregateServiceProvider és a dir que permet agrupar múltiples proveïdors de serveis en un):

Illuminate\Foundation\Providers\ConsoleSupportServiceProvider

ConsoleSupportServiceProvider el teniu afegit per defecte al fitxer config/app.php ([3]) al vector providers.

Configuració de la planificació

La configuració es realitza al mètode schedule de la classe:

app/Console/Kernel.php

Al mètode schdule se li passa un objecte Schedule el qual us ofereix una API per executar processos de forma planificada:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        // Commands\Inspire::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
    }
}

Com podeu veure a la versió 5.2 de Laravel (el que estic utilitzant en el moment de fer aquesta documentació) teniu comentades l'execució de la comanda inspire. La comanda inspire era una comanda que estava disponible en versions anteriors de Laravel que mostrava frases inspiratories. Abans aquestes frases es mostraven a la pàgina welcome per defecte de Laravel, ara ja no s'utilitza. Segons la API:

https://laravel.com/api/5.2/Illuminate/Console/Scheduling/Schedule.html

Els mètodes principals són:

  • call( string $callback, array $parameters = array()): Permet afegir un callback o closure, és a dir una funció que serà la que s'executarà de forma planificada.schedule.
  • command( string $command, array $parameters = array()): Permet executar comandes artisan ja siguin comandes artisan per defecte de Laravel o comandes a mida
  • exec( string $command, array $parameters = array()): permet executar qualsevol comanda del sistema de forma similar al que fa la funció exec de php.

Observeu que tots tres mètode tornen un objecte de tipus Event.

$schedule->call(function () {
            DB::table('recent_users')->delete();
        })->monthly();
    }
}
$schedule->command('cache:clear')->daily();
$schedule->exec('node /home/forge/script.js')->everyFiveMinutes();

Un cop indicat el que volem executar de forma planificada observeu com tenim múltiples funcions com monthly, daily,everyFiveMinutes que permeten planificar la tasca. Consulteu la web de Laravel per veure tots els mètode de planificació que suporta el mètode Schedule:

https://laravel.com/docs/master/scheduling#schedule-frequency-options

Execució de tasques planificades amb condicions

Podeu utilitzar els mètode when o reject per executar només les tasques si es compleixen (when) o no executar si es compleixen (reject) certes condicions:

$schedule->command('emails:send')->daily()->when(function () {
    return true;
});
$schedule->command('emails:send')->daily()->reject(function () {
    return true;
});

Es poden concatenar (amb Method Chaining) múltiples condicions i s'han de complir totes!

Evitar el solapament de tasques

Per defecte les tasques s'executaran sempre inclòs si pel que sigui l'anterior tasca encara s'està executant. Es pot evitar aquest solapament amb withoutOverlapping:

$schedule->command('emails:send')->withoutOverlapping();

Control de l'output (sortida) de les comandes planificades

Hooks

Es poden definir els mètodes before i after per definir mètodes/hooks que s'executaran abans i/o després de l'execució de la tasca planificada.

$schedule->command('emails:send')
         ->daily()
         ->before(function () {
             // Task is about to start...
         })
         ->after(function () {
             // Task is complete...
         });

També es poden utilitzar els mètodes pingBefore i thenPing per crear hoosk que executin hooks remots (per exemple a una API de tercers)

$schedule->command('emails:send')
         ->daily()
         ->pingBefore($url)
         ->thenPing($url);

IMPORTANT: Aquests dos mètodes depenen de Guzzle:

$ composer require "guzzlehttp/guzzle:~5.3|~6.0"

Artisan commands

L'única comanda relacionada amb Laravel Scheduler és schedule:run

$ php artisan | grep schedule
schedule
 schedule:run        Run the scheduled commands

Si l'executeu en un projecte acabat d'instal·lar:

$ php artisan schedule:run 
No scheduled commands are ready to run.


Vegeu també

Enllaços externs