Future objects and regular awaitables, and are the building blocks for multi-step workflows.
gather — run all, wait for all
Submit multiple tasks and wait for all of them to complete:
gather also works with regular awaitables:
Future objects, gather returns task values (same as await future.value() for each future).When you pass
task.wait(...) coroutines, gather returns TaskResult objects because those awaitables resolve to TaskResult.
Handle errors gracefully
By default,gather raises on the first error. Set return_exceptions=True to collect errors as results instead:
map_tasks — fan out with concurrency control
Apply a task to a list of inputs with bounded concurrency:
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
task | TaskHandle | required | The task to execute |
inputs | list[dict] | required | List of keyword argument dicts |
concurrency | int | 10 | Maximum concurrent executions |
first_completed — race multiple tasks
Return the first result and cancel the rest:
submit_many — fire and forget in bulk
Submit multiple jobs without waiting for results:
map_tasks, submit_many returns immediately with a list of Future objects. Use it when you want to submit all jobs upfront and collect results later (or not at all).
Workflows
All of these primitives work inside nested tasks. When a parent task usesgather, map_tasks, or first_completed to coordinate child tasks, UpNext automatically tracks the parent-child lineage through the entire execution tree.
Workflows
Learn about nested tasks, lineage tracking, failure propagation, and multi-level workflow patterns.