15: Taken
Phlo heeft een ingebouwde cross-app cron runner. Eén systeem cron-invoer per app activeert tasks::run elke minuut; de tasks resource matcht declaratief tegen %app->tasks. Geen cron syntaxis in je app, geen externe planner.
15.1: Instellen
Drie stappen.
1. Activeer de resource in data/app.json:
{
"resources": [..., "tasks"]
}
2. Beschrijf je taken in app.phlo:
prop tasks => arr(
cleanup: arr(do: 'account::cleanup', every: '5 minutes'),
poll: arr(do: fn() => external::pull(), every: 'minute'),
backup: arr(do: 'backup::run', daily: '03:00'),
report: arr(do: 'report::weekly', weekly: 'monday 09:00'),
)
3. Eén cron-entry per app met een absoluut pad:
* * * * * php-zts <app>/www/app.php tasks::run
Plaats het in /etc/cron.d/example-tasks (systeem, 6 velden incl. gebruiker) of via crontab -u <user> (per gebruiker, 5 velden).
15.2: Schema
Kies precies één planningssleutel per taak:
| Sleutel | Formaat | Voorbeeld |
|---|---|---|
every: |
PHP-leesbare duurstring | 'minute', '5 minutes', '2 hours', '1 day' |
daily: |
'HH:MM' |
'03:00' |
weekly: |
'<weekday> HH:MM' |
'monday 09:00' |
every: 'minute' (zonder een leidend getal) wordt intern '1 minute'. Parsing via strtotime("+$every", 0).
15.3: Aanroepbaar (`do:`)
Het do: veld accepteert drie vormen:
| Type | Voorbeeld | Wordt aangeroepen als |
|---|---|---|
| Closure | fn() => external::pull() |
direct |
'Class::method' |
'account::cleanup' |
account::cleanup() |
| Resource naam | 'backup' |
phlo('backup') |
In tegenstelling tot een normale aanvraag, draait een taak buiten een HTTP-lifecycle: er is geen %req, geen %session. Schrijf je taak zodat deze zelfvoorzienend is.
15.4: Toestand op schijf (`data/tasks/`)
tasks::run maakt automatisch data/tasks/ aan en beschermt elke taak met drie bestanden:
| Bestand | Inhoud | Wanneer |
|---|---|---|
<name>.last |
ruwe unix-timestamp | Per succesvolle uitvoering, voor de due check |
<name>.json |
{schedule, return} voor het Control Center |
Per succesvolle uitvoering |
<name>.lock |
leeg (mtime telt) | Tijdens een uitvoering, TTL 1 uur |
Locks voorkomen dat een trage taak zichzelf inhaalt. De TTL is opzettelijk 1 uur: een mislukte taak wordt geparkeerd totdat de lock verloopt; andere taken blijven zoals gebruikelijk draaien.
15.5: Foutstroom
Geen try/catch in tasks::run. Een Throwable komt omhoog naar Phlo's framework exception handler en schrijft naar data/errors.json, net zoals buildfouten dat doen. Het Phlo Control Center toont ze in het taken-tabblad.
15.6: Phlo Control Center
Het Phlo Control Center detecteert data/tasks/ automatisch:
- Een Taken-tab verschijnt in de navigatie (alleen als de directory bestaat), direct na Home.
- Per taak: schema (uit JSON), laatst-uitgevoerd, retourwaarde (type-bewust: scalar / array / string), vergrendelstatus.
- Het Control Center is volledig agnostisch ten opzichte van de
tasksresource en de app, het leest puur uitdata/tasks/. Schema-informatie komt van<name>.json, niet via een app route (dat zou een HTTP-respons triggeren en de render van het Control Center verstoren).
15.7: Voorbeeld
prop tasks => arr(
heartbeat: arr(do: 'app::heartbeat', every: 'minute'),
)
static heartbeat => file_put_contents(data.'heartbeat.log', date('Y-m-d H:i:s').' tasks::run fired'.lf, FILE_APPEND | LOCK_EX)
Cron entry:
* * * * * php-zts <app>/www/app.php tasks::run
Elke minuut wordt tasks::run aangeroepen, ziet dat heartbeat every: 'minute' is en dat lastRun < 60s geleden was, en voert app::heartbeat() uit. De bestanden data/tasks/heartbeat.last, .json en .lock worden bijgewerkt; tussenliggende cron-tikken overslaan de taak terwijl deze wordt uitgevoerd.