Implement Effect Pattern for Core APIs (ADR-033) #299
Labels
No labels
adr
automated
bug
chore
dependencies
documentation
enhancement
epic
github-actions
P1-high
P2-medium
P3-low
release
research
rust
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jwilger/eventcore#299
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement the Effect pattern described in ADR-033 (accepted 2026-02-17, PR #298). This refactors the core
execute()and projection runner internals into pure state machines that yield effects, with thin shell loops that dispatch effects to backend traits.Caller-Driven Effects (User-Facing)
Beyond the internal refactor,
execute()should support user-defined effects that surface back to the caller. This enables commands that need external I/O (LLM calls, API requests, tool invocations) during execution while preserving atomicity.Design Direction
execute()returns a three-variant enum:EffectRequestbundles the effect description with a continuation:The caller drives a loop, fulfilling effects and resuming execution:
Commands declare effect types via new associated types on
CommandLogic:Effect-free commands use
Effect = ()and never trigger theEffectvariant — backward compatible, no loop needed.Key Properties
Internal Refactor Sub-Issues
StoreEffectenum (ReadStream, AppendEvents) andProjectionEffectenum (TryAcquireLock, LoadCheckpoint, SaveCheckpoint, ReadEvents, Sleep), plus result types. Allpub(crate).ExecutePipelinestate machine -- pure state machine fromexecute()internals (stream resolution, retry loop, append). YieldsStoreEffect, accepts results viaresume().executeshell loop -- drivesExecutePipeline, dispatches effects toEventStoretrait.ProjectionLoopstate machine -- pure state machine fromProjectionRunner::run()internals (checkpoint, polling, event application, retry/skip/fatal).run_projectionshell loop -- dispatchesProjectionEffectto backend traits.Related Issues
Key Files
eventcore/src/lib.rseventcore/src/projection.rseventcore/src/effects.rseventcore-types/src/command.rs(CommandLogic trait changes)Closing this issue. The internal state machine refactor shipped in #349. The caller-driven effects feature was intentionally dropped after review (#348) — commands will receive all non-system-state inputs pre-calculated, and TOCTOU concerns with external systems are inherent regardless of framework-level mechanisms.