OutlabsTaskq
API

Follow-ups

Atomic child jobs declared on the parent Task and returned with Complete.

A handler declares its finite child graph in the registry and returns typed children with its successful result. The parent settlement and every child insert commit together; the worker never receives a generic producer client.

from taskq import Complete, Followup, FollowupTarget, Task, TaskRegistry

child = Task(
    name="listing.enrich",
    queue="enrichment",
    input_model=EnrichInput,
    output_model=EnrichOutput,
    handler=enrich,
)

async def discover(payload: DiscoverInput) -> Complete:
    return Complete(
        result={"accepted": True},
        followups=(
            Followup(
                step="enrich",
                job_type=child.name,
                queue=child.queue,
                payload={"listing_id": payload.listing_id},
            ),
        ),
    )

parent = Task(
    name="listing.discover",
    queue="discovery",
    input_model=DiscoverInput,
    output_model=DiscoverOutput,
    followup_targets=(FollowupTarget(queue=child.queue, job_type=child.name),),
    handler=discover,
)

registry = TaskRegistry((parent, child))

Rules

  • Declare every child (queue, job_type) on followup_targets before the worker starts.
  • Worker construction rejects missing or queue-mismatched targets.
  • HTTP completion authorizes the parent queue, then every distinct child queue, before SQL.
  • Direct SQL retains the trusted runner-role boundary.

Shipped in migrations 0008_followups.sql (ADR-024 / ADR-025).