Fix #4729: composite rebuild must not re-fire member side effects (JasperFx 2.9.13)#4733
Merged
Merged
Conversation
… effects) + regression test JasperFx 2.9.13 fixes #4729 in two parts: - #447: the optimized composite rebuild propagates the composite's ShardExecutionMode to its member executions. Members defaulted to ShardExecutionMode.Continuous (CompositeReplayExecutor only set the parent's Mode), so a composite rebuild re-fired the members' RaiseSideEffects (PublishMessage/AppendEvent) every time — unlike the classic single-stream rebuild pinned by side_effects_do_not_happen_in_rebuilds. - #448: decouples slice.Snapshot assignment from side-effect publishing in AggregationRunner so multi-stage composites still fan the upstream Updated<TDoc> events to downstream stages during a rebuild. (#447 alone left the snapshot unset off the Continuous path, so downstream stages lost the synthetic events and threw NREs — 2.9.12 is incomplete.) Adds an end-to-end regression test: a composite whose stage-2 member publishes a side-effect message must publish during continuous operation but NOT during RebuildProjectionAsync. Also corrects the now-inaccurate class comment on the #4727 sharded test (side effects are suppressed during rebuild post-#4729). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 15, 2026
Merged
This was referenced Jun 22, 2026
This was referenced Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4729.
Problem
A
CompositeProjectionForwhose stage member raises side effects (RaiseSideEffects→slice.PublishMessage/slice.AppendEvent) re-fired those side effects on every rebuild, whereas an equivalent standaloneSingleStreamProjectionrebuild does not (pinned byside_effects_in_aggregations.side_effects_do_not_happen_in_rebuilds). For a member that publishes an external message (invoice/notification), a composite rebuild re-published it every time.Fix (JasperFx 2.9.13)
This bumps the JasperFx packages 2.9.10 → 2.9.13, which carries the two-part fix:
CompositeReplayExecutoronly set theShardExecutionModeon the parent composite execution; the member executions defaulted toContinuousand were never updated, so the optimized rebuild ran members inContinuousand fired their side effects.CompositeExecutionnow propagates itsModeto every member, so members run inCatchUp/Rebuildduring a rebuild and suppress side effects — matching the classic single-stream path.slice.Snapshotassignment from side-effect publishing inAggregationRunner. After Query Documentationn update #447, multi-stage composites lost the upstreamUpdated<TDoc>fan-out during a rebuild (the snapshot was only set on theContinuouspath, and downstream stages threw NREs). The snapshot is now set in every mode; only the side effects stayContinuous-only. (2.9.12 shipped Query Documentationn update #447 alone and regressedmulti_stage_projections— this PR targets 2.9.13.)Tests
src/DaemonTests/Composites/composite_rebuild_suppresses_side_effects.cs: a composite whose stage-2 member publishes a message must publish during continuous operation but not duringRebuildProjectionAsync. Verified RED on 2.9.10 (re-published all messages during rebuild) and GREEN on 2.9.13.composite_side_effects_rebuild_under_sharded_partitioning(the Composite projection rebuild deadlocks on ProjectionUpdateBatch.CurrentMessageBatch SemaphoreSlim (side-effect PublishMessageAsync path) with parallel event slices #4727 sharded test): side effects are suppressed during a rebuild as of Side effects fire during the optimized composite rebuild (Continuous mode) but are suppressed in classic rebuilds — intended? #4729, so it stays a "rebuild completes / no deadlock" guard.DaemonTests.Composites(incl.multi_stage_projections) +side_effects_in_aggregationsgreen against published 2.9.13.🤖 Generated with Claude Code