Craft CMS is een populair CMS onder webdevelopers en digitale bureaus. Het biedt veel vrijheid bij het ontwikkelen van websites, met uitgebreide mogelijkheden voor contentbeheer, plugins en maatwerk.
Net als andere moderne PHP-applicaties gebruikt Craft CMS een queue om werkzaamheden op de achtergrond uit te voeren.
De standaardmanier waarop Craft CMS deze queue verwerkt, heeft een bijzonderheid waar veel developers niet van op de hoogte zijn: zonder aanvullende configuratie kan het verwerken van jobs afhankelijk zijn van iemand die het controlpanel bezoekt.
Waarvoor gebruikt Craft CMS een queue?
Wanneer je in Craft CMS een pagina opslaat, gebeurt er vaak meer dan alleen het wegschrijven van content naar de database.
Craft kan bijvoorbeeld op de achtergrond zoekindexen bijwerken, wijzigingen doorvoeren bij gerelateerde entries of oude revisies opruimen. Ook plugins kunnen de queue gebruiken, bijvoorbeeld wanneer de populaire caching-plugin Blitz de cache ververst.
Craft CMS gebruikt hiervoor het queuesysteem van Yii (binnenkort Laravel). Standaard worden de jobs opgeslagen in de database, waarna een queue-runner ze één voor één kan uitvoeren.
Maar... dan moet je die queue-runner wel starten.
De bijzondere standaardinstelling van Craft CMS
Craft CMS heeft een configuratieoptie met de naam runQueueAutomatically. Deze staat standaard op true.
->runQueueAutomatically(true)
Daarmee probeert Craft automatisch wachtende jobs uit te voeren wanneer iemand het controlpanel bezoekt.
Dat is een praktische standaardinstelling voor kleine websites en ontwikkelomgevingen. Er hoeven immers geen aparte achtergrondprocessen te worden geconfigureerd. Craft kan zelf het verwerken van jobs in gang zetten.
Maar stel dat jullie een website beheren waarop men slechts enkele keren per week inlogt. Op maandag wordt via een externe integratie een nieuwe job toegevoegd. Laten we zeggen om gegevens te synchroniseren met een ander systeem.
De website wordt ondertussen gewoon bezocht. Alles lijkt te werken. Maar niemand opent het Craft-controlpanel.
Dan wordt de job gewoon niet uitgevoerd. Sterker nog: in de Craft-documentatie wordt hier expliciet voor gewaarschuwd:
Critical tasks, however, should not necessarily be entrusted to the queue. A default Craft install will have runQueueAutomatically enabled and be reliant on a control panel browser session to trigger the queue. This could result in queue processing delays for infrequently-accessed sites.
Bron: Craft CMS: Queue Jobs
Waarom dit in productie een probleem kan zijn
Bij sommige jobs is het niet zo erg wanneer ze een paar minuten later worden verwerkt. Denk aan het opruimen van oude revisies of het bijwerken van een zoekindex.
Maar als jullie Craft CMS gebruiken voor een webshop, een klantportaal of een uitgebreide integratie met andere systemen, dan zijn jobs een belangrijk onderdeel van de bedrijfsprocessen van de klant.
Stel dat een plugin een bestelling doorstuurt naar een extern systeem. De bestelling wordt opgeslagen en de bijbehorende job komt in de queue terecht. Als de verwerking daarvan afhankelijk is van een volgend bezoek aan het controlpanel, kan het even duren voordat die bestelling daadwerkelijk wordt doorgestuurd.
Hetzelfde geldt voor andere werkzaamheden, zoals het verwerken van gegevens uit externe API’s, het versturen van notificaties of het synchroniseren van voorraden.
De oplossing: een eigen queue-worker
Voor productieomgevingen adviseert Craft CMS om een afzonderlijke queue-runner te configureren.
Dat kan bijvoorbeeld met een cronjob die iedere minuut wordt uitgevoerd:
* * * * * /path/to/project/craft queue/run
Voor applicaties die voortdurend jobs moeten verwerken, is een langlopend achtergrondproces vaak een betere keuze.
Craft ondersteunt hiervoor het commando:
php craft queue/listen
Daarmee starten jullie een worker die blijft luisteren naar nieuwe jobs. Zodra een job beschikbaar is, kan deze worden uitgevoerd, zonder dat iemand daarvoor het controlpanel hoeft te openen.
Zo’n worker moet natuurlijk ook na een serverherstart beschikbaar zijn. Daarvoor kunnen jullie een procesmanager zoals systemd of Supervisor gebruiken. Die zorgt ervoor dat het proces automatisch wordt gestart en opnieuw wordt gestart wanneer het onverwacht stopt.
Wanneer jullie een eigen queue-worker gebruiken, schakelen jullie de automatische queue-runner van Craft uit:
->runQueueAutomatically(false)
Of via een omgevingsvariabele:
CRAFT_RUN_QUEUE_AUTOMATICALLY=false
Zo voorkomen jullie dat Craft daarnaast nog probeert jobs via het controlpanel te verwerken.
Op Cyberfusion Core configureren we de queue-daemon automatisch
Een queue-worker configureren is op zichzelf niet bijzonder ingewikkeld. Maar het is wel iets waar jullie als developers aan moeten denken.
De juiste commando’s moeten worden geconfigureerd, de worker moet onder de juiste UNIX-user draaien en na -bijvoorbeeld- een serverherstart automatisch terugkomen.
Op Cyberfusion Core gaat dit vanzelf.
Wanneer jullie een Craft CMS-project aanmaken, configureert Core automatisch de bijbehorende queue-daemon. Jullie hoeven dus niet zelf een systemd-service of Supervisor-configuratie aan te maken.
Dat is échte managed hosting: veelvoorkomende taken rondom het draaien van applicaties automatiseren, zodat developers zich kunnen richten op development.