Laravel-tips del 2 – Dispatcher och cron-jobb

I stort sett varje riktig webbtjänst når någon gång punkten då saker och ting behöver automatiseras – vare sig det är filer som ska behandlas, tweets som ska skickas ut, data som ska hämtas via ett API eller någonting annat där du vill slippa göra en manuell åtgärd.

Cron-jobb är den allra vanligaste metoden att göra det här på. Kanske kör man med sin gamla trofasta crontab:

ProHockeyIQ Cron Tab Crontab från ProHockeyIQ i våras

Eller om man har någon form av hjälpverktyg t.ex. cpanel, eller kanske Forge för att underlätta lite:

Webbjobb.io Cron Tab Forge Crontab från Webbjobb.io genom Laravel Forge

För det är det stora problemet med Cron, syntaxen. Den är både relativt svår att lära sig, och är inte särskilt praktiskt om man behöver tyda vilka jobb man har schemalagda snabbt.

Jag själv brukar "fuska" genom att använda en GUI, t.ex. "Corntab" då jag alltid bladar ihop månad och dagen under en månaden (kan ställa till med ordentlig huvudvärk).

Lösningen – Dispatcher

Dispatcher gör det väldigt enkelt att programmatiskt bygga upp dina automatiserade jobb, samtidigt som den erbjuder en väldigt praktiskt överblick över dem när de väl är schemalagda.

För att sätta upp det i Laravel så är det bara att göra det klassiska; dra in biblioteket via composer:

"require": {
    "indatus/dispatcher": "~1.4"
}

Och sedan lägga till det bland ens providers:

'providers' => array(
    'Indatus\Dispatcher\ServiceProvider'
)

Det fina med Dispatcher är att det i grund och botten är ett vanligt Artisan-kommando (du använder väl kommandon för dina jobb?). Så om du redan har ett kommando som du vill använda tillsammans med Dispatcher så kan du bara lägga till följande klasser med use:

use Indatus\Dispatcher\Scheduling\ScheduledCommand;
use Indatus\Dispatcher\Scheduling\Schedulable;

Samt extend:a ScheduledCommand istället för Command:

class MyCommand extends ScheduledCommand {}

Om man vill skapa ett nytt kommando från scratch, är det bara att köra:

php artisan scheduled:make MyCommand

Som vanligt, glöm inte att registrera dina kommandon i Artisan.php:

Artisan::add(new MyCommand);

Dispatcher-kommandona fungerar identiskt med de vanliga Artisan kommandona, med undantaget att utöver fire-metoden så kan du använda schedule-metoden. Det är här magin händer.

Säg t.ex. att du har ett jobb som du vill köra varje veckodag, var tionde minut klockan 7 och klockan 8. Lite småjobbigt att pilla med stjärnorna här, inte sant? Med Dispatcher kan du enkelt uttrycka det genom:

public function schedule(Schedulable $scheduler) {
    return $scheduler->everyWeekDay()
                    ->hours(7, 8)
                    ->everyMinutes(10);
}

Svårare än så är det inte. Och om du vill ha ett argument till ditt kommando?

public function schedule(Schedulable $scheduler) {
    // Same as php artisan MyCommand task
    return $scheduler->args(array('task'))
                    ->everyWeekDay()
                    ->hours(7, 8)
                    ->everyMinutes(10);
}

Du kan nu köra php artisan scheduled:summary för att få en smidig överblick som är betydligt enklare att tyda än crontab -l.

Webbjobb.io Cron Tab Dispatcher

Men vad är det som faktiskt triggar jobben? Jo, det är php artisan scheduled:run, som du sätter ett cron-jobb på för att köra varje minut.

* * * * * php /sites/mysite.com/artisan scheduled:run

Så helt undan crontab:en kommer du inte, men i framtiden så är det bara att skapa fler kommandon om du behöver fler automatiserade jobb, utan att behöva gå in med crontab -e.

Spana in Dispatcher på GitHub. Jeffrey Way har också en bra screencast om just Dispatcher på Laracasts.