-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Akka.TestKit: remove ConfigureAwait(false)
from internal synchronous TestKit methods and fix Watch
/ Unwatch
bugs
#7037
Akka.TestKit: remove ConfigureAwait(false)
from internal synchronous TestKit methods and fix Watch
/ Unwatch
bugs
#7037
Conversation
Trying to reproduce some test failures discovered on the build server
ConfigureAwait(false)
from internal synchronous TestKit methods
This innocuous test is still failing, even after these changes, so it makes me think there's more async funk going on inside the TestKit that isn't completely resolved yet: akka.net/src/core/Akka.Persistence.TestKit.Tests/Bug4762FixSpec.cs Lines 67 to 85 in 0486f97
|
@akkadotnet/core not going to include this in Akka.NET v1.5.15 - too much of a hot potato and it needs time for lots of subsequent CI/CD runs to validate it before we roll out the "mission accomplished!" banner to our users |
src/core/Akka.TestKit/TestKitBase.cs
Outdated
* | ||
* "Nuke the site from orbit. It's the only way to be sure." | ||
*/ | ||
taskCompletionSource.Task.Wait(RemainingOrDefault); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nasty, decade old bug in the TestKit - Watch
and Unwatch
have always been secretly asynchronous, which is why tests like this one failed:
[Fact]
public async Task Routers_in_general_must_evict_terminated_routees()
{
var router = Sys.ActorOf(new RoundRobinPool(2).Props(Props.Create<Echo>()));
router.Tell("");
router.Tell("");
var c1 = await ExpectMsgAsync<IActorRef>();
var c2 = await ExpectMsgAsync<IActorRef>();
Watch(router);
Watch(c2);
Sys.Stop(c2);
(await ExpectTerminatedAsync(c2)).ExistenceConfirmed.Should().BeTrue();
// it might take a while until the Router has actually processed the Terminated message
await AwaitConditionAsync(async () =>
{
router.Tell("");
router.Tell("");
var res = await ReceiveWhileAsync(100.Milliseconds(), x =>
{
if (x is IActorRef actorRef)
return actorRef;
return null;
}, msgs: 2).ToListAsync();
return res.Count == 2 && res.All(c => c.Equals(c1));
});
Sys.Stop(c1);
(await ExpectTerminatedAsync(router)).ExistenceConfirmed.Should().BeTrue();
}
Failed on (await ExpectTerminatedAsync(c2)).ExistenceConfirmed.Should().BeTrue();
, which can only mean the actor was dead before the TestActor
had a chance to go through.
src/core/Akka.TestKit/TestActor.cs
Outdated
/// </summary> | ||
/// <param name="actorToWatch">TBD</param> | ||
public Watch(IActorRef actorToWatch) { _actorToWatch = actorToWatch; } | ||
public Watch(IActorRef actorToWatch, TaskCompletionSource<bool> watchCompleted) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Messaging fixes to support the Watch
and Unwatch
raciness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments about my Watch
and Unwatch
fixes.
ConfigureAwait(false)
from internal synchronous TestKit methodsConfigureAwait(false)
from internal synchronous TestKit methods and fix Watch
/ Unwatch
bugs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some concern on the Watch
and Unwatch
implementation and also how sync over async is implemented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Changes
close #7038
close #7064
Removed all internal usages of
ConfigureAwait(false)
from synchronous Akka.TestKit method implementations - this should help reduce the incidences of mysterious racy unit tests.