Skip to content

Tracked session no longer completes while a handler's cascading messages are still running - #5400

Open
haefele-octoja wants to merge 1 commit into
JasperFx:mainfrom
haefele-octoja:tracked-session-misses-late-cascades
Open

haefele-octoja wants to merge 1 commit into
JasperFx:mainfrom
haefele-octoja:tracked-session-misses-late-cascades

Conversation

@haefele-octoja

Copy link
Copy Markdown

ExecuteAndWaitAsync can report Completed while cascaded messages are still running. With no conditions, TrackedSession.IsCompleted() runs _envelopes.All(x => x.IsComplete()). That enumerates the envelope histories as they were when the check started. If a handler sends its cascading messages and then finishes while the check runs, for example on the test thread's fast-path check right after the action returns, the new histories are missing from the enumeration. Every history in it is complete, so the session completes too early.

We saw this as flaky integration tests: a Marten save publishes a message through the outbox, its handler cascades more messages, and the test asserts on their side effects after ExecuteAndWaitAsync returns.

Fix

Histories are only ever added, never removed. IsCompleted() now checks again until the number of histories did not change during the check. Any cascade sent before its parent finished is then included.

Test

tracked_session_waits_for_cascades_of_durable_local_queues saves a document whose session listener publishes a root message. The root fans out to 2 messages, and each of those to 2 leaves, on durable local queues. The test loops ExecuteAndWaitAsync and asserts that every envelope succeeded.

The race needs CPU pressure. On an idle machine the test passes even without the fix. Locally with 8 busy CPU loops, at 3,000 iterations per run:

Result
Without the fix 3 of 4 runs failed, at iterations 823, 1611 and 2190
With the fix 4 of 4 runs passed

The committed test loops 500 times so it stays fast in CI (about 17 s locally).

…ges are still running

IsCompleted() checked a snapshot of the envelope histories. A handler could send its cascading
messages and finish while that check ran, so the session completed without the new histories.
Check again until no history was added during the check.

Amp-Thread-ID: https://ampcode.com/threads/T-97a14128-3d4d-4162-b764-dcd5b371d4a8
Co-authored-by: Daniel Häfele <daniel.haefele@octoja.de>
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.

1 participant