Skip to content

De-flake BugFix3724Spec and HubSpec: give the zero-count event filter its own 3 s window instead of the Within's remaining time - #8566

Merged
Aaronontheweb merged 1 commit into
fix/inbox-spec-receive-asyncfrom
fix/zero-count-event-filter-inside-within
Sep 10, 2026
Merged

Aaronontheweb merged 1 commit into
fix/inbox-spec-receive-asyncfrom
fix/zero-count-event-filter-inside-within

Conversation

@Aaronontheweb

@Aaronontheweb Aaronontheweb commented Sep 10, 2026 •

Copy link
Copy Markdown
Member

Stacked on #8564.

What changes

Two zero-count event filters that sit inside a WithinAsync(10s) block get an explicit 3 s window, one line each: BugFix3724Spec.Should_serialize_all_AkkaCluster_messages and HubSpec.MergeHub_must_not_log_normal_shutdown_exception. The Within blocks stay, since they are the only bound on the cluster join and the stream operations inside them. No assertion changes.

Why

Build 131327, Windows unit tests, on a PR that touched a different assembly: BugFix3724Spec failed with "Block was still running after 00:00:10.2149997, exceeding the maximum allowed duration of 00:00:10". It was the first spec of Akka.Cluster.Tests on a cold agent.

A zero-count filter with no explicit window picks the Within's remaining time before it runs the action, runs the action, then waits out that whole window to prove nothing was logged. So the block ends at start plus the action's time plus the window, which is past the Within's deadline by exactly the action's time. WithinAsync abandons a still-running block 200 ms after its deadline and, since #8516, fails the fact. The fact therefore passes only when the asynchronous part of the action finishes inside 200 ms. A standalone .NET 10 harness with no Akka in it, replicating the race and the wait loop, flips at exactly 200 ms. On a cold Windows agent with serialize-messages = on, the first cluster self-join pays JIT and serializer first-touch and does not make it.

Before #8516 the overrun was ignored silently. #7541 created the shape in April 2025 by switching the filter's default window from akka.test.filter-leeway to the Within's remaining time. Pekko's filter always uses filter-leeway, 3 s dilated, so it has no such shape. 3 s is that value: the window this spec used before #7541 and the one Pekko uses today. The block is now the join plus 3 s under a 10 s ceiling, and the quiet period asserted after the join shrinks rather than grows.

The TestKit side, a zero-count filter that eats the Within's budget by construction and an abandon timer that ignores epsilonValue, is #8565. It is not in this PR because it ships to users.

How it was checked

Both projects build with warnings as errors. BugFix3724Spec run five times: passed each time, the fact at 4 s instead of the 10 s it was forced to take before. The HubSpec class run three times: 40 passed and 1 pre-existing skip each time, the changed fact at 3 s. Test-only change. No ledger entry.

… its own 3 s window instead of the Within's remaining time

A zero-count EventFilter.ExpectAsync(0, action) with no explicit timeout,
run inside a WithinAsync(max) block, captures the Within's remaining time
as its own quiet window, runs the action, then waits out that whole window
to prove nothing was logged. The block therefore ends at
start + T_action + max by construction, while WithinAsync abandons a
still-running block at max + 200ms and fails the fact (since #8516). On a
cold CI agent the action's async part (cluster self-join in BugFix3724Spec)
doesn't leave enough margin.

Pekko's filter always uses akka.test.filter-leeway (3s, dilated) for its
quiet window, never the remaining Within time. Pass that window explicitly
via the ExpectAsync(count, timeout, action) overload in both specs so the
block runs in roughly T_action + 3s instead of racing the outer deadline.
@Aaronontheweb
Aaronontheweb force-pushed the fix/zero-count-event-filter-inside-within branch from 2be488a to 2767357 Compare September 10, 2026 14:54
@Aaronontheweb
Aaronontheweb merged commit 3432d6f into dev Sep 10, 2026
4 checks passed
@Aaronontheweb
Aaronontheweb deleted the fix/zero-count-event-filter-inside-within branch September 10, 2026 15:27
Aaronontheweb added a commit that referenced this pull request Sep 12, 2026
… its own 3 s window instead of the Within's remaining time (#8566)

A zero-count EventFilter.ExpectAsync(0, action) with no explicit timeout,
run inside a WithinAsync(max) block, captures the Within's remaining time
as its own quiet window, runs the action, then waits out that whole window
to prove nothing was logged. The block therefore ends at
start + T_action + max by construction, while WithinAsync abandons a
still-running block at max + 200ms and fails the fact (since #8516). On a
cold CI agent the action's async part (cluster self-join in BugFix3724Spec)
doesn't leave enough margin.

Pekko's filter always uses akka.test.filter-leeway (3s, dilated) for its
quiet window, never the remaining Within time. Pass that window explicitly
via the ExpectAsync(count, timeout, action) overload in both specs so the
block runs in roughly T_action + 3s instead of racing the outer deadline.

(cherry picked from commit 3432d6f)
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