SerializableCoroutine
View Source< EffectLogger & SerializableCoroutine | Up: Effects | Index | Durable Computation > | Umbrella →
Pause-serialize-resume support for durable workflows. Wraps a coroutine
with EffectLogger installed innermost so every effect invocation is
captured in a JSON-serializable log.
Building a durable coroutine
alias Skuld.SerializableCoroutine
sc = SerializableCoroutine.new(MyWizard.run(), fn comp ->
comp |> State.with_handler(%{}) |> Yield.with_handler() |> Throw.with_handler()
end)new/2 takes your computation and a function that installs your application
handlers. EffectLogger is installed inside your handlers so it intercepts
every effect call without you wiring it explicitly.
Running
run dispatches on the input type:
# Fresh start — runs until first Yield, returns %ExternalSuspended{}
suspended = SerializableCoroutine.run(sc)
# Live resume — pass a resume value to a suspended coroutine
SerializableCoroutine.run(suspended, "Alice")
# Cold resume from a deserialised log
SerializableCoroutine.run(log, sc, "Alice")
# Cold resume from serialised JSON (deserialises then resumes)
SerializableCoroutine.run(json, sc, "Alice")The cold-resume path replays all completed effects from the log, then applies the resume value to continue where it left off.
Serializing and deserializing
# Extract the log from a suspended coroutine
log = SerializableCoroutine.get_log(suspended)
# Serialize to JSON for storage (database, S3, etc.)
json = SerializableCoroutine.serialize(log)
# Later: deserialize and cold-resume
{:ok, log} = SerializableCoroutine.deserialize(json)
SerializableCoroutine.run(log, sc, resume_value)How it works
new/2stores the computation and your handler-stack function.run(fresh) installsEffectLoggerinside your handlers, then starts aCoroutine. EffectLogger wraps every handler so each invocation is logged with its result.- When the coroutine suspends (via
Yield), the log is accessible from the environment viaget_log/1. serialize/1finalizes the log and encodes it to JSON.deserialize/1reverses this.- Cold resume replays the log:
EffectLogger.with_resume/3short-circuits completed effects with their logged values, then resumes the coroutine at the point where it left off.
< EffectLogger & SerializableCoroutine | Up: Effects | Index | Durable Computation > | Umbrella →