Handler Routing

How the worker matches executions to handlers using payload.task.

How routing works

When the worker receives an execution, it looks at payload.task and matches it to a handler in the YAML config:

Execution payload: {"task": "draft-linkedin", ...}
                        ↓
Worker config handler:  draft-linkedin:
                          cmd: "python3 linkedin_agent.py"

Routing rules

  1. payload.task must exactly match a handler key in the config
  2. If no handler matches, the execution is skipped (not claimed)
  3. The worker only claims executions it can handle
  4. Multiple workers can have different handler sets

Example

Config:

yaml
handlers:
  draft-linkedin:
    cmd: "python3 linkedin_agent.py"
    timeout: 300
 
  sync-data:
    cmd: "/scripts/sync.sh"
    timeout: 60
Payload taskMatched handlerResult
draft-linkedindraft-linkedinClaimed and executed
sync-datasync-dataClaimed and executed
unknown-task(none)Skipped

Filtering at the API level

The worker uses the ?task= query parameter when polling to only fetch relevant executions:

GET /v1/executions/claimable?task=draft-linkedin,sync-data

This reduces unnecessary polling and network traffic.

Multiple workers

You can run multiple workers with different handler sets:

Worker A (content pipeline):

yaml
handlers:
  draft-linkedin:
    cmd: "python3 linkedin_agent.py"
  draft-twitter:
    cmd: "python3 twitter_agent.py"

Worker B (data tasks):

yaml
handlers:
  sync-data:
    cmd: "/scripts/sync.sh"
  generate-report:
    cmd: "python3 report.py"

Each worker only claims executions matching its handlers.