Skip to content

Support parent/child tasks - #60

Merged
snopoke merged 5 commits into
mainfrom
sk/parents
Aug 6, 2026
Merged

Support parent/child tasks#60
snopoke merged 5 commits into
mainfrom
sk/parents

Conversation

@snopoke

@snopoke snopoke commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

The server API now supports parent/child tasks, one level deep, set via a parent field when creating a task.

create_task/update_task/list_tasks take parent explicitly. The Celery, Procrastinate and @track integrations set it automatically for tasks enqueued while another tracked task is running — a bare create_task never picks up an ambient parent, only the integrations nest.

Worth review attention:

  • Flattening. Entering a task that already has a parent keeps offering its parent, so a task enqueued by a child becomes its sibling rather than a grandchild. This isn't cosmetic — the API rejects grandchildren outright.
  • What counts as a subtask. Retries nest under the first attempt; chain links and link callbacks don't. Celery dispatches all of these from inside trace_task after the body returns but before task_postrun, so they all look like they came from the running task. Nothing on the wire separates them, so chain/callback publishes are matched against the running task's own request.chain/request.callbacks rather than by inspecting the stack. Known edge case: if a chain's next link is also called directly from the body, that direct call won't nest.
  • The generator pin (first commit) has nothing to do with parents but was forced by regenerating the client: openapi-python-client 0.29 emits datetime.fromisoformat in place of dateutil.isoparse, which can't parse the API's Z-suffixed timestamps on Python 3.10. Without the pin, every task create/get/update breaks on 3.10. Side effect: dev typer resolves to 0.25.1, since the generator shares that dependency.

Verified against the deployed service: integration tests cover create/list/update, the one-level limit, Celery parent nesting, grandchild flattening and chain links. The flattening and chain-link tests were checked by reverting the fix and confirming they fail, rather than only that they pass. Unit suite passes on both 3.10 and 3.14.

Deliberately out of scope: a CLI --parent flag, and a client-side depth guard (the server already enforces it).

🤖 Generated with Claude Code

snopoke and others added 5 commits August 6, 2026 15:25
0.29 generates `datetime.fromisoformat` calls in place of `dateutil.isoparse`.
That can't parse the API's `Z`-suffixed timestamps before Python 3.11, and we
support 3.10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds `parent` to the task request/response models and a `parent` query filter
on task list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Also exports `list_tasks`, which the new parent filter makes the natural way
to fetch a task's children.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Celery and Procrastinate tasks enqueued while another tracked task is running
are attached to it as children, as are tasks created inside `@track`.

Nesting is one level deep, so entering a task that already has a parent keeps
offering that parent: a task enqueued by a child joins it under the root rather
than hanging off it, which the API would reject.

Replaces Procrastinate's private current-task contextvar with the shared one so
`current_task()` and parenting can't drift apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Celery dispatches the next chain link and any `link` callbacks from inside
`trace_task` after the body returns but before `task_postrun`, so the task they
follow still looks current and they were being recorded as its children.
They're successors, not subtasks.

Nothing on the wire distinguishes them from a publish the body made itself, so
this matches against the running task's own `request.chain`/`request.callbacks`
rather than inspecting the stack.

Retries still nest — a retry republishes the same task, which isn't among its
own successors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@snopoke
snopoke marked this pull request as ready for review August 6, 2026 13:54
@snopoke
snopoke merged commit 112226f into main Aug 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant