Kiki's PCNTL Daemon
Het Kiki framework kan niet alleen webpagina's genereren, maar ook achtergrondtaken uitvoeren via een heuse daemon.
Achtergrondtaken...
Websites en webpagina's dienen razendsnel te zijn. Gebruikers haken af wanneer het laden van een pagina te lang duurt.
Maar soms zijn er stukken dataverwerking nodig die nu eenmaal tijd nodig
hebben, omdat er veel gerekend dient te worden of wellicht een externe API
aangesproken moet worden. Vaak worden dit soort taken met een
cronjob
uitgevoerd, maar nadelen hiervan zijn dat ze dan slechts één
keer per minuut gedraaid kunnen worden en bij piekbelasting goed moet worden
opgelet dat een vorige draai van het script al is afgerond alvorens een
nieuwe te starten.
...achtergrondproces!
Als oplossing heeft Kiki de mogelijkheid om continu een achtergrondproces te
draaien, een zogenaamde daemon
. Hoewel gewoon een stukje PHP
gedraagt deze zich als ieder ander systeemproces: geen input of output op de
console, een nette detach naar de achtergrond en via de
PCNTL
standaard voor process control kunnen zelfs meerdere
children worden
Hiermee worden achtergrondprocessen praktisch direct uitgevoerd zonder wachttijden of opeenstapeling van processen (indien er geen taken gevonden zijn wacht de daemon één á twee seconden, na het afronden van een taak kijkt deze direct verder).
Wat een gebruiker in de daemon uitvoert kan deze uiteraard helemaal zelf bepalen, door de
abstract main()
methode te implementeren in een eigen Daemon
class die Kiki\Daemon
uitbreidt.
De daemon aanroepen is vervolgens een fluitje van een cent:
#!/usr/bin/php
<?php
namespace MyNamespace;
require_once "/var/www/kiki/lib/init.php";
$myDaemon = new Daemon();
$myDaemon->start(1);
Benieuwd naar de code?
- GitHub: lib/daemon.php
Queue Daemon / Object Queue
Voor het gemak en de meest voorkomende situaties heeft Kiki al een eigen
QueueDaemon
implementatie die eenvoudig te gebruiken is. Via
de ObjectQueue
class kunnen er voor alle classes die overerven
van BaseObject
taken in de database worden opgeslagen. De
combinatie hiervan geeft de volgende mogelijkheden:
Verschillende soorten taken per object: een
actionHandler
koppelt een taaknaam aan een eigen methode.Prioritisering: taken hebben een
priority
veld.-
Meerdere pogingen: indien een taak niet succesvol uitgevoerd of afgerond kan worden, wordt deze opnieuw ingepland. Dit kan zowel handmatig (door zelf een nieuwe tijd te kiezen) als automatisch.
Bij automatische herplanning wordt een op de Fibonacci reeks gebaseerde wachttijd gehanteerd met een maximum van veertig pogingen. De eerste herpoging volgt direct (0s), de tweede na 10s, de derde na 30s (10+20), de vierde na 60s (10+20+30), enzovoort.
- Poging 5 is na een totaal van ~2 minuten.
- Poging 10 is na een totaal van ~23 minuten.
- Poging 15 is na een totaal van ~4,5 uur.
- Poging 20 is na een totaal van ~2 dagen, bijna twee uur na de vorig poging.
- Poging 25 is na een totaal van ~23 dagen, bijna een dag na de vorige poging.
- Poging 30 is na een totaal van ~252 dagen, bijna acht maanden, meer dan een week na de vorige poging.
- Poging 35 is na een totaal van ~2796 dagen oftewel zeven-en-een-half jaar, ongeveer drie maanden na de vorige poging.
- Poging 40 is na een totaal van bijna 85 jaar (!).
Om hier gebruik van te maken gebruik je deze code:
<?php
namespace MyNamespace;
use Kiki\ObjectQueue;
class Daemon extends \Kiki\QueueDaemon
{
// Handler voor de database actie 'do_mystuff'
protected function do_mystuffAction( $o )
{
// Do stuff
if ( $manualDelay )
{
$queueTime = date( 'Y-m-d H:i:s', $whenever );
ObjectQueue::delay( $o->id, $queueTime );
return null;
}
if ( $success )
return true;
if ( $failure )
return false;
}
}
Bekijk de code voor details en inspiratie:
- GitHub: lib/queuedaemon.php
- GitHub: lib/objectqueue.php
Dit was mijn spreekbeurt over Kiki's PCNTL daemon.