Skip to content

arazzo: make the retry sleeper injectable via EngineConfig.SleepFunc#600

Open
khalidDaoud wants to merge 1 commit into
pb33f:mainfrom
khalidDaoud:feat/arazzo-injectable-sleeper
Open

arazzo: make the retry sleeper injectable via EngineConfig.SleepFunc#600
khalidDaoud wants to merge 1 commit into
pb33f:mainfrom
khalidDaoud:feat/arazzo-injectable-sleeper

Conversation

@khalidDaoud

Copy link
Copy Markdown

What

Adds an optional SleepFunc func(ctx context.Context, d time.Duration) error to arazzo.EngineConfig, used for the wait between retry attempts (a failure action's retryAfter). nil preserves the existing sleepWithContext behavior exactly; a returned error aborts the workflow the same way a cancelled context does today.

Why

The engine is a great fit for embedding in durable workflow runtimes (Temporal, DBOS, Restate): its control flow is deterministic given the Executor responses, so a host can journal each Execute call and replay through the engine after a crash. The one wall-clock primitive in the loop is the retry sleep (engine.gosleepWithContext), which such hosts must substitute with their own replay-safe durable timer — a real time.Timer inside a replayed workflow body blocks the scheduler (Temporal's deadlock detector) or re-sleeps on recovery.

It also lets tests exercise retryAfter paths with a recording fake instead of a real wait.

Notes

  • No behavior change for existing users (nil field ⇒ current default).
  • Tests cover both the substitution (recorded duration, no real sleep) and error propagation (sleeper error fails the workflow with the cause on WorkflowResult.Error).

Context: we're using the arazzo engine inside a durable workflow engine (perflow), with each Executor.Execute journaled as an exactly-once step — this field is the last piece needed for fully replay-safe embedding.

The engine waits between retry attempts (a failure action's retryAfter)
with a real context-aware timer. That default is right for standalone use,
but hosts embedding the engine need to substitute their own wait: durable
workflow runtimes (Temporal, DBOS, Restate) must use their replay-safe
durable sleep — a real time.Timer inside a replayed workflow body blocks
the scheduler or breaks determinism — and tests want a recording fake
instead of a real wait.

EngineConfig gains SleepFunc(ctx, d) error; nil keeps the existing
sleepWithContext behavior, and a returned error aborts the workflow
exactly as a cancelled context does today.

@daveshanley daveshanley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice upgrade! thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants