Skip to main content

Workers

A worker connects to the Cadence server, polls a task list for workflow and activity tasks, and executes them. Three objects work together: Client, Registry, and Worker.

Samples​

Runnable worker samples:

SampleDescriptionCode
Minimal workerCreates a client and starts a worker with a workflow registryrun_worker.py
Agent workflow workerHosts human-in-the-loop agent workflowsmain.py

Client​

Client connects to the Cadence frontend over gRPC. It is an async context manager.

from cadence.client import Client

CADENCE_TARGET = "localhost:7833" # replace with your Cadence frontend address

async with Client(domain="my-domain", target=CADENCE_TARGET) as client:
# client is ready here
...
OptionDescription
domainCadence domain (required)
targetCadence frontend address as host:port (required)
identityIdentity string shown in workflow history (default: auto-generated)
data_converterCustom data converter for serializing workflow arguments
service_nameCadence service name sent in RPC metadata (default: cadence-frontend)
caller_nameCaller name sent in RPC metadata (default: cadence-client)
metrics_emitterMetrics backend; defaults to NoOpMetricsEmitter
context_propagatorsSequence of context propagators used for workflow headers
credentialsOptional gRPC channel credentials
compressiongRPC compression mode
interceptorsAdditional gRPC async client interceptors
channel_argumentsAdditional gRPC channel arguments

Registry​

Registry holds workflow and activity definitions. Create one per worker process (or share one across multiple workers).

from cadence.worker import Registry

registry = Registry()

Register workflows and activities on the registry using decorators:

@registry.workflow()
class MyWorkflow:
@workflow.run
async def run(self, name: str) -> str:
...

@registry.activity()
async def my_activity(input: str) -> str:
...

You can also register definitions imperatively:

registry.register_activity(my_activity)

Worker​

Worker is an async context manager that polls the task list and dispatches tasks.

from cadence.worker import Worker

async with Client(domain="my-domain", target=CADENCE_TARGET) as client:
async with Worker(client, "my-task-list", registry):
# Worker is polling; keep alive until interrupted
await asyncio.Event().wait()

Worker runs two pollers internally: one for decision (workflow) tasks and one for activity tasks. Both run concurrently.

Worker options​

async with Worker(
client,
"my-task-list",
registry,
max_concurrent_activity_execution_size=200,
max_concurrent_decision_task_execution_size=100,
activity_task_pollers=4,
decision_task_pollers=4,
):
await asyncio.Event().wait()
OptionDescriptionDefault
max_concurrent_activity_execution_sizeMaximum concurrently executing activities1000
max_concurrent_decision_task_execution_sizeMaximum concurrently executing decision tasks1000
task_list_activities_per_secondActivity dispatch rate limit for the task list; 0.0 leaves it unlimited0.0
activity_task_pollersNumber of activity pollers2
decision_task_pollersNumber of decision pollers2
disable_activity_workerDisable activity pollingFalse
disable_workflow_workerDisable decision-task pollingFalse
identityWorker identity recorded by CadenceGenerated from the client identity and task list
metrics_emitterMetrics backendInherited from the client
context_propagatorsContext propagatorsInherited from the client

Disabling one poller​

Worker(client, "my-task-list", registry, disable_activity_worker=True)
Worker(client, "my-task-list", registry, disable_workflow_worker=True)

Full example​

import asyncio
from cadence.client import Client
from cadence.worker import Worker, Registry
from cadence import workflow

CADENCE_TARGET = "localhost:7833" # replace with your Cadence frontend address

registry = Registry()

@registry.workflow()
class GreetingWorkflow:
@workflow.run
async def run(self, name: str) -> str:
return f"Hello, {name}!"

async def main():
async with Client(domain="my-domain", target=CADENCE_TARGET) as client:
print("Worker running, press Ctrl-C to stop")
async with Worker(client, "my-task-list", registry):
await asyncio.Event().wait()

if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass