Skip to content

Seed ThreadLocalRandom from a cryptographic source - #8377

Merged
Aaronontheweb merged 3 commits into
akkadotnet:devfrom
Aaronontheweb:fix/threadlocalrandom-seed
Jul 16, 2026
Merged

Aaronontheweb merged 3 commits into
akkadotnet:devfrom
Aaronontheweb:fix/threadlocalrandom-seed

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Member

Summary

ThreadLocalRandom seeded its per-thread base from Environment.TickCount. Processes started in the same millisecond (orchestrator-launched cluster nodes, MNTR node processes) share that base, so corresponding threads across those processes draw identical random streams. This has already manifested as identical system UIDs across MNTR node processes.

Replaces the TickCount base with a base drawn from RandomNumberGenerator.GetInt32. The per-thread Interlocked.Increment scheme is unchanged; only the shared base is now cryptographically random. Public API is unchanged.

Test plan

  • dotnet build src/core/Akka -warnaserror - clean
  • dotnet test src/core/Akka.Tests --filter FullyQualifiedName~Akka.Tests.Util x3 - 91/91 passing each run
  • dotnet test src/core/Akka.API.Tests --filter FullyQualifiedName~ApproveCore - zero API churn

TickCount-based seeding gives simultaneously-started processes correlated per-thread random streams, affecting gossip target selection, backoff/circuit-breaker jitter, and shuffles. This was observed as identical system UIDs across MNTR node processes.
@Aaronontheweb

Copy link
Copy Markdown
Member Author

Deep review found the original regression test did not exercise the reported cross-process defect: two threads in one process already received distinct Interlocked-incremented seeds before this change, and the array comparison did not provide useful coverage of the seed source.

Commit 5d95348 isolates the cryptographic seed draw, tests that repeated draws do not collapse to TickCount-style deterministic behavior, makes the ThreadLocal field readonly, and removes the inaccurate claim that random collisions are impossible. Focused result: 2/2 passed; Akka warnings-as-errors build clean.

@Aaronontheweb Aaronontheweb left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

LGTM, we should probably replace ThreadLocalRandom with Random.Shared in the near future anyway.

@Aaronontheweb
Aaronontheweb enabled auto-merge (squash) July 16, 2026 14:11
@Aaronontheweb
Aaronontheweb disabled auto-merge July 16, 2026 15:31
@Aaronontheweb
Aaronontheweb merged commit 86fdbb3 into akkadotnet:dev Jul 16, 2026
11 checks passed
@Aaronontheweb
Aaronontheweb deleted the fix/threadlocalrandom-seed branch July 16, 2026 15:31
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2026
* Seed ThreadLocalRandom from a cryptographic source

TickCount-based seeding gives simultaneously-started processes correlated per-thread random streams, affecting gossip target selection, backoff/circuit-breaker jitter, and shuffles. This was observed as identical system UIDs across MNTR node processes.

* Harden ThreadLocalRandom seed regression coverage

(cherry picked from commit 86fdbb3)
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 3, 2026
* Seed ThreadLocalRandom from a cryptographic source

TickCount-based seeding gives simultaneously-started processes correlated per-thread random streams, affecting gossip target selection, backoff/circuit-breaker jitter, and shuffles. This was observed as identical system UIDs across MNTR node processes.

* Harden ThreadLocalRandom seed regression coverage

(cherry picked from commit 86fdbb3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant