Structured concurrency
TypeScript Promise.all / Promise.race, Python gather / race, and Rust join / race compile to the same durable join operations. Each requires the durable.concurrent_group capability. The continuation stores the durable join state rather than a host promise or Python awaitable.
TypeScript await Promise.all / await Promise.racePython await gather / await raceRust join / raceAll Fork + JoinAll / JoinAnyjoin(effect("a", || 1.0), effect("b", || 2.0)) has the same durable semantics as await Promise.all([effect("a", () => 1), effect("b", () => 2)]). The Rust frontend accepts exactly two arguments, while the engine supports groups of 1–32 branches.
The supported forms for each language are documented under TypeScript, Python, and Rust.
Examples
Section titled “Examples”import { effect, sleep, waitForEvent } from "@trigora/sdk";
const [left, right] = await Promise.all([ effect("left", async () => 1), effect("right", async () => 2),]);
const winner = await Promise.race([ waitForEvent("ready"), sleep(60_000),]);from trigora import effect, gather, race, sleep, wait_for_event
found = await gather( effect("left", lambda: 1), effect("right", lambda: 2),)
winner = await race( wait_for_event("ready"), sleep(60_000),)A group has 1 to 32 branches. Each branch is effect, waitForEvent / wait_for_event, sleep, or invoke. Rust join and race take exactly two of those calls.
What stays durable
Section titled “What stays durable”Branches remain durable across suspension and recovery. Registration is one branch at a time. A crash between registrations resumes the group. It does not start a second copy of a branch that already registered.
Promise.all, gather, and join return the branch values in input order, including when completions arrive in another order.
Promise.race and race persist the first durably accepted winner. That is the first completion the engine commits after every branch is registered, not wall-clock order. When several effects finish during registration, the lowest branch index wins. A crash before that commit can still accept a different winner. A crash after it cannot.
After a race commits a winner, the other branches detach and can no longer affect the parent result. Effects and child Executions that have already started are not cancelled. Sibling-branch cancellation is not supported.
If a branch fails, the all-join fail-fasts into the surrounding try / catch or try / except after that failure is committed. Later sibling completions cannot change the outcome. A race throws when the accepted winner fails, and the same handler runs once.
Promise.all, Promise.race, gather, and race are not themselves durable operations. The durable operations inside them are. See Durable operations.