Skip to content

Port changes from v1.6 (dev) branch to v1.5 branch#7984

Merged
Aaronontheweb merged 13 commits into
akkadotnet:v1.5from
Arkatufus:v1.5-cherry-picks
Jan 8, 2026
Merged

Port changes from v1.6 (dev) branch to v1.5 branch#7984
Aaronontheweb merged 13 commits into
akkadotnet:v1.5from
Arkatufus:v1.5-cherry-picks

Conversation

@Arkatufus
Copy link
Copy Markdown
Contributor

Changes

Port 12 PR merges from dev branch to v1.5 branch

# PR Title
1 #7960 Skip parsing PropertyNames when empty Parameters
2 #7970 Fix TcpListener to not stop from accepting further connections on transient accept errors
3 #7981 Fix race condition in cluster sharding when entity constructor fails
4 #7980 fix(cluster.tools): fix race condition in DistributedPubSubRestartSpec actor creation
5 #7977 Fix WithinAsync timeout not propagating to EventFilter across async boundaries
6 #7975 Fix race condition in multi-producer sharding delivery test
7 #7973 Fix race condition in QueueSink causing async enumerable timeout
8 #7972 Fix timing race in BackpressureTimeout test
9 #7967 Make RemotingTerminator non-FSM to avoid racy FSM log init
10 #7964 Fix .NET 10 CLR shutdown hook breaking change
11 #7006 Akka.TestKit: configurable expect-no-message-default value
12 #7968 LogMessage GetProperties without FrozenDictionary

snakefoot and others added 13 commits January 8, 2026 01:22
* Skip parsing PropertyNames when not Parameters

* Simplify code

---------

Co-authored-by: Gregorius Soedharmo <arkatufus@yahoo.com>
…ransient accept errors (akkadotnet#7970)

* Minimal fix to handle SocketError.ConnectionAborted in TcpListener.

* Handle more transient error cases. Handle known fatal errors explicitly.

* Join code paths for known and unknown fatal errors.

---------

Co-authored-by: Aaron Stannard <aaron@petabridge.com>
…kkadotnet#7981)

When a sharded entity's constructor throws an exception with
remember-entities enabled, HandleSupervisorStop was calling
RemoveEntity() which immediately set the entity state to NoState.
However, the actor was still in the ActorCell's TerminatingChildrenContainer.

If a new message arrived before EntityTerminated was processed, the
shard would see NoState and try to create a new entity, causing
"Actor name is not unique!" exception and crashing the shard.

Fix: Use EntityPassivating instead of RemoveEntity, which:
- Buffers messages arriving during termination
- Persists removal from store when termination completes
- Restarts entity if messages arrived (transient failure recovery)
- Stays forgotten if no messages arrive

Closes akkadotnet#7979

Co-authored-by: Gregorius Soedharmo <arkatufus@yahoo.com>
…c actor creation (akkadotnet#7980)

Move shutdown actor creation to execute immediately after the new
ActorSystem joins, before the 5-second gossip isolation verification.
This eliminates the race where First node times out waiting for Third
node to create the shutdown actor.

Changes:
- Create shutdown actor before ExpectNoMsgAsync delay on Third node
- Migrate sync-over-async methods to proper async (ExpectMsgAsync,
  RunOnAsync)
- Increase timeout margins (WithinAsync 20s→25s, ExpectMsgAsync 1s→2s)
  for better CI stability
…oundaries (akkadotnet#7977)

* Fix WithinAsync timeout not propagating to EventFilter across async boundaries

Use AsyncLocal<TimeSpan?> to properly propagate WithinAsync timeout to
EventFilter and other async operations. The previous implementation used
a plain instance field (_testState.End) which could have memory visibility
issues when accessed from different threads across await boundaries.

The fix:
- Adds AsyncLocal<TimeSpan?> field that flows through async contexts
- WithinAsync sets/restores both instance field and AsyncLocal
- Remaining and RemainingOr check AsyncLocal first, then instance field
- Preserves backward compatibility with sync code paths

* remove `static`

---------

Co-authored-by: Gregorius Soedharmo <arkatufus@yahoo.com>
…et#7975)

The test ReliableDelivery_with_Sharding_must_illustrate_Sharding_usage_with_several_producers
was experiencing intermittent failures due to a premature entity termination race condition.

Root cause: When multiple producers send messages to the same sharded entities, each
producer-entity pair maintains independent sequence numbers (1-42). The test's end condition
(seqNr >= 42) would trigger when ANY producer reached seqNr 42, causing the entity to stop
immediately, before other producers could complete their message delivery.

This resulted in the test expecting 3 Collected messages (one per entity) containing all 6
producer IDs (p1-entity-{0,1,2} and p2-entity-{0,1,2}), but entities would stop after only
receiving messages from the first producer to complete, causing timeouts.

Solution: Modified TestConsumer to track per-producer completion:
- Added expectedProducerCount parameter (defaults to 1 for backward compatibility)
- Track which producers have met the end condition in _completedProducers set
- Only stop the entity when ALL expected producers have completed
- Updated multi-producer test to pass expectedProducerCount: 2

This ensures entities properly wait for all producers to complete message delivery before
terminating, eliminating the race condition without relying on timeout adjustments.

Verified with 20 consecutive successful test runs and full test suite validation.
…adotnet#7973)

Fixed a timing-dependent race condition where RunAsAsyncEnumerable would timeout when the materializer shut down while a PullAsync() request was pending.

The QueueSink.Logic.PostStop() method now properly completes any pending TaskCompletionSource stored in _currentRequest with a StreamDetachedException before shutting down, preventing orphaned Tasks that would never complete.

This resolves intermittent test failures in AsyncEnumerableSpec.RunAsAsyncEnumerable_Throws_on_Abrupt_Stream_termination where the test would hang waiting for an exception that never arrived.
…and_arrives test (akkadotnet#7972)

The test was failing intermittently in CI/CD with "No demand signalled in the last 00:00:01" because accumulated delays (750ms) left insufficient safety margin with the 1-second timeout.

Changes:
- Increased backpressure timeout from 1s to 2s
- Reduced ExpectNoMsg delays from 250ms to 100ms per iteration

This provides 1700ms safety margin (vs 250ms previously) to handle:
- Async/await scheduling overhead
- Thread pool contention in CI/CD environments
- Timer check granularity and imprecision
- Test infrastructure processing delays

The test semantics remain unchanged - it still verifies that demand arriving within the timeout window prevents backpressure timeout errors.
…et#7967)

RemotingTerminator is initialized during Provider Start. FSM constructor
initializes the _log with `context.GetLogger()` which eventually leads into
`LogSource.FromActorRef()`. This method attempts to access
`Provider.DefaultAddress`, which is being initialized.

If Provider `Init()` loses the race, either its `RemoteInternals` is not set,
causing NRE, or if `Remoting.Start()` is not completed, the `_defaultAddress`
is not set and returns null.

This commit removes the FSM from `RemotingTerminator` and manually implements
it using `Become()` API.

Co-authored-by: Aaron Stannard <aaron@petabridge.com>
* Fix .NET 10 CLR shutdown hook breaking change

* fix global.json

* Fix warning as errors

* Install .NET SDK 8.0

* Add very targetted .NET 10 CI/CD run

* Fix CI/CD script

* Code fix

* Revert .NET 10 CI/CD integration (will be moved to a new PR)

* whitespace cleanup

---------

Co-authored-by: Aaron Stannard <aaron@petabridge.com>
…#6675 (akkadotnet#7006)

* * added config expect-no-message-default = 3s
* added this config into TestKit setting as ExpectNoMessageDefault property
* in TestKit_Expect, bounded relevant overloads of ExpectNoMsg and ExpectNoMsgAsync to the new config
* updated unit test

* Add custom testkit config validation test

* Update API Approval list

---------

Co-authored-by: Gregorius Soedharmo <arkatufus@yahoo.com>
@Aaronontheweb Aaronontheweb merged commit 45e7f45 into akkadotnet:v1.5 Jan 8, 2026
6 of 11 checks passed
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.

6 participants