Skip to content

Temporal Backend #254

Description

@Krever

Might be interesting for avoiding vendor lock-in or simplify migration.

Idea

Run a WIO program inside a Temporal workflow. A new WorkflowRuntime registers a worker whose workflow function interprets the WIO AST, translating each node to a Temporal primitive. Temporal owns durability, scheduling, and signal delivery; workflows4s contributes the DSL and the declarative rendering.

High-level shape

The interpreter that already exists is pure Scala over the AST and takes now: Instant as input. Plugging it into Temporal means:

  • A TemporalRuntime implementing WorkflowRuntime, with a worker that hosts the workflow function.
  • The workflow function walks the WIO and dispatches to Temporal APIs for the few effectful nodes.
  • Time is injected via the existing clock seam (BasicEngine.now) using Temporal's deterministic clock.
  • The wakeup scheduler (KnockerUpper) is unused — Temporal's own sleep/await supersedes it.

Node mapping

(Approximate, to be verified)

  • RunIO → activity invocation
  • Timer (static or dynamic) → Workflow.sleep
  • AwaitingTimeWorkflow.sleep until target instant
  • HandleSignal → Temporal signal channel
  • ParallelAsync.function / promise composition
  • Pure / Transform / Fork / Loop / AndThen / FlatMap → in-workflow control flow (the interpreter already handles these)
  • HandleError / HandleErrorWith → exceptions in the interpreter
  • Retry → loop in the interpreter
  • Embedded → recursive interpretation of the inner WIO
  • End → workflow returns

Tradeoffs accepted

  • Event-sourced model collapses — Temporal's history is the durable record. The workflows4s event log is unused for this backend, and constructs that lean on it (Checkpoint, Recovery) need a deliberate mapping or are dropped.
  • Activity payloads need codecs.
  • The whole interpreter must stay deterministic on replay, which it already is modulo RunIO bodies — those run as activities outside workflow context, so non-determinism there is fine.

Open questions for the prototype

  • Activity identity for RunIO — each node needs a stable name so Temporal history can dispatch on replay.
  • AST evolution under replay — when a WIO definition changes while instances are in flight, history may no longer line up. Need a versioning story (Temporal's getVersion, or an AST-level identity scheme).
  • Retry coordinationWIO.Retry vs Temporal's activity-level retry policy. Probably let the WIO drive and disable Temporal's retry, but worth confirming.
  • Checkpoint / Recovery — map onto Temporal's history / continueAsNew, or drop for v1.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions