Replies: 2 comments 1 reply
|
You're right that the shapes line up: a Obelisk workflows are obviously replayable because the runtime holds no live guest state: with the interrupt strategy the instance is destroyed on every await point, and even with the default strategy the execution can be transparently unloaded from memory if it makes no progress for some time. Native async works the opposite way, keeping live executor continuations in guest memory, so you'd have to snapshot and reconstruct that state, which is far harder to observe and reason about than the JSON events of an execution log. That state would also likely be tied to a specific compiler + wit-bindgen version, whereas Obelisk only cares that two components produce the same events, which are human- and LLM-readable. So with a Rust execution sitting paused, an LLM could generate a JS function that emits the same events to that point, which is a viable way to ad-hoc migrate a stuck execution or clean up some buggy edge case. The nondeterminism surface also gets much bigger. The async ABI exposes a lot more of it directly to the guest (see the spec's Nondeterminism section): which waitable fires first, whether a thread blocks or continues, resume order, backpressure release order, which thread gets a cancellation. The scopes don't match either. In the async ABI a callee's lifetime is bound to the caller's task. In Obelisk a single workflow creates and closes many join sets, and closing one has its own semantics: unawaited activities and cancellable child workflows are cancelled, non-cancellable ones are awaited. More broadly, Obelisk has its own semantics around pausing and cancellation that aren't compatible with the async ABI's model. It's also a deliberate programming model. Workflows are meant to read as simple sequential programs, with async/await and callbacks kept out of workflow code; native futures would reintroduce exactly that surface. Underneath, join sets sit very close to the deterministic state machine the engine runs, which is why the extensions aren't just a convenience layer: they are its API surface. Same for |
|
I'll admit I haven't dug into the Obelisk implementation much at all. I sort of assumed it recorded calls over WIT as
Dropping a Anyway, thank you for your thoughts. I need to understand your join sets better to continue my exploration. |
Uh oh!
There was an error while loading. Please reload this page.
Hi. Interesting project.
It seems https://obeli.sk/docs/latest/concepts/extensions/ is kinda unnecessary now with the latest WIT work now having native
future<T>andstream<T>types.https://github.com/WebAssembly/component-model/blob/main/design/mvp/Concurrency.md
Interested to hear what you think about that.
All reactions