External tasks (worker-principe)¶
Liever geen PHP? Gebruik een config-gestuurde worker
De meeste workers kun je zonder PHP als JSON definiëren — zie
Dynamische workers. Schrijf alleen een PHP-handler
(hieronder) als geen enkel action-type volstaat. Eigen handlers horen in
development/handlers/; de generieke zaak-*/notify-*-handlers zijn
platform-reusables in portal.
Hoe BPMN-processen werk laten uitvoeren door het portaal, via Operaton external tasks en een dispatcher met auto-discovery.
Het idee¶
Een BPMN-service-task met type = external voert zelf geen code uit; hij zet een
job klaar op een topic. Een worker haalt die job op (fetchAndLock),
doet het werk, en meldt de taak af (complete) of laat 'm falen (failure, met
retry). Het topic is dus alleen een contract/naam — de code zit in de worker.
BPMN service task Operaton-engine Portaal (dispatcher)
type=external ──▶ job op topic ──▶ fetchAndLock(topic)
topic="notify-admin" → handler.handle()
→ complete / failure
Architectuur in dit portaal¶
Niet één worker-proces per topic, maar één dispatcher die alle handlers automatisch ontdekt:
app/Console/Commands/ExternalTaskWorkerCommand.php— de dispatcher (php artisan operaton:external-task-worker). Draait altijd als supervisord- programmaexternal-task-worker. Hij scantapp/ExternalTasks/, abonneert in éénfetchAndLockop álle topics, en stuurt elke taak naar de juiste handler.app/ExternalTasks/TopicHandler.php— het contract dat elke handler extend.app/ExternalTasks/*Handler.php— de handlers (de eigenlijke code per topic).
Gevolg: een nieuwe worker toevoegen = één handler-class erbij + deployen. Geen
wijziging aan supervisord.conf, geen extra proces, geen UI.
Een nieuwe worker maken¶
- Teken in de modeler (Beheer → Processen) een service task, zet rechts
Implementation = External en een Topic (bv.
mijn-topic). - Maak
app/ExternalTasks/MijnHandler.php:
<?php
namespace App\ExternalTasks;
class MijnHandler extends TopicHandler
{
public function topics(): array
{
return ['mijn-topic']; // één of meer topics
}
public function variables(): array
{
return ['objectUrl', 'foo']; // procesvariabelen die je nodig hebt
}
public function handle(array $task): array
{
$objectUrl = $this->var($task, 'objectUrl'); // lees een procesvariabele
// ... doe het werk (gooi een exception om de taak te laten falen) ...
return ['resultaat' => 'ok']; // procesvariabelen terug naar het proces
}
}
- Commit, push en open een PR. Na het mergen rolt de serverbeheerder de
nieuwe image uit (developers hebben geen terminaltoegang); de dispatcher pikt
mijn-topicdan automatisch op. Zie Een formulier/proces live brengen.
Submappen mogen — de discovery is recursief. Handlers zijn per domein ingedeeld; de namespace volgt het pad (PSR-4, PascalCase-mappen):
app/ExternalTasks/ ├── TopicHandler.php (de basisklasse) ├── Autorisatieverzoek/ (handlers van het autorisatieverzoek-proces) ├── Zgw/ (zaakgericht werken: zaken, documenten, ...) └── Common/ (handlers die meerdere processen delen)Zet een nieuwe handler in de passende map (of maak er een nieuwe aan); de dispatcher vindt 'm ongeacht de diepte.
Het contract (TopicHandler)¶
| Methode | Verplicht | Doel |
|---|---|---|
topics(): array |
ja | op welk(e) topic(s) de handler luistert |
handle(array $task): array |
ja | het werk; retour = procesvariabelen; throw = taak laten falen |
variables(): array |
nee | welke procesvariabelen meegehaald worden (default geen) |
lockDuration(): int |
nee | lock-duur in ms tijdens verwerking (default 60000) |
Hulpfunctie *$this*->var($task, 'naam', $default) leest een procesvariabele uit
de taak.
Afronden, falen & idempotentie¶
handle()geeft een array terug → de dispatcher doetcompleteExternalTaskmet die variabelen.- Gooit
handle()een exception →externalTaskFailuremet retries − 1 en een backoff (60s). Bij 0 retries ontstaat er een incident (zie Beheer → Incidenten). - Maak
handle()idempotent. Als het werk slaagt maar het afronden faalt, wordt de taak na de lock opnieuw opgepakt. Voorbeeld:ZaakAanmakenHandlercheckt eerst of er al een zaak bestaat voor deof_referentie.
Bestaande handlers¶
| Topic(s) | Handler | Doet |
|---|---|---|
notify-admin, notify-approved, notify-rejected |
Autorisatieverzoek/MailNotificationHandler |
verstuurt de autorisatieverzoek-mails |
zgw-zaak-aanmaken |
Zgw/ZaakAanmakenHandler |
maakt een zaak in Open Zaak uit een verzoek-inzending |
Operationeel (serverbeheerder)¶
Deze checks draaien op de server en zijn voor de serverbeheerder (developers hebben geen terminaltoegang):
- Status:
docker exec portal-portal-1 supervisorctl status→external-task-worker RUNNING. - Logs: de dispatcher logt per taak
topic: afgerondoftopic: fout - ...(docker logs portal-portal-1).
De BPMN gebruikt de camunda:-namespace (camunda:type, camunda:topic);
Operaton accepteert die. Zie Formulieren-tips voor de modeler-kant.