15: Taken

Phlo heeft een ingebouwde taakuitvoerder voor meerdere apps. Iets activeert tasks::run elke minuut, een systeem cron-invoer of de Phlo Daemon; de tasks resource matcht declaratief met %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. Trigger tasks::run elke minuut. Met de Phlo Daemon kun je de app in zijn hostmap opsommen en de daemon voert tasks::run voor je uit, zonder enige cron-regel:

require('./phlo-daemon.js')(3001, php, { '<host>': { app: '<app>/www/app.php', build: false } })

Zonder de daemon doet een systeem cron-invoer hetzelfde:

* * * * * php-zts <app>/www/app.php tasks::run

Plaats het in /etc/cron.d/example-tasks (systeem, 6 velden inclusief gebruiker) of via crontab -u <user> (per gebruiker, 5 velden). Hoe dan ook blijft de planning zelf in %app->tasks; de trigger levert alleen de minuut-tik.

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:

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-invoer:

* * * * * 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 ticks slaan de taak over terwijl deze aan het draaien is.

15.8: Planning zonder cron

Als de Phlo Daemon draait, voert hij tasks::run elke minuut voor je uit, zodat je geen cron-invoer per app nodig hebt. Elke app in de hostmap van de daemon krijgt de minuut-tik:

require('./phlo-daemon.js')(3001, '/usr/bin/php-zts', {
	'example.com': { app: '/var/www/example/www/app.php', build: false },
})

De daemon tikt tasks::run eenmaal per minuut; jouw %app->tasks schema (de every: op elke taak) bepaalt wat er daadwerkelijk wordt uitgevoerd, precies zoals de cron-tik. De rest is identiek: dezelfde %app->tasks matching, dezelfde due-check, dezelfde data/tasks/ status. Cron blijft de fallback voor hosts zonder een daemon; kies één trigger, niet beide.

We gebruiken essentiële cookies om deze site te laten werken. Met uw toestemming gebruiken we ook analytics om de site te verbeteren.