-
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
Cluster LeaveAsync() with CancellationToken support #2501
Cluster LeaveAsync() with CancellationToken support #2501
Conversation
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 questions, but overall I think these changes are good.
@@ -192,6 +194,76 @@ public void A_cluster_must_complete_LeaveAsync_task_upon_being_removed() | |||
_cluster.LeaveAsync().IsCompleted.Should().BeTrue(); | |||
} | |||
|
|||
[Fact(Skip = "This behavior not yet supported.")] |
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.
Why isn't this behavior supported yet?
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.
Because wanted to discuss before 😄
Right now Leave()
and LeaveAsync()
do not share state with each other.
LeaveAsync()
memoizes the _leaveTask
, therefore two subsequent calls of LeaveAsync()
won't result in double sending of the leave request.
But Leave()
doesn't take the _leaveTask
into account. So, if cluster have been left by the Leave()
method (or is in state of leaving) , LeaveAsync()
doesn't know about it and will be waiting for the MemberRemoved event.
Here is how we can change the Leave()
method to support that:
public void Leave(Address address)
{
if (address == SelfAddress)
{
LeaveSelf();
}
else
ClusterCore.Tell(new ClusterUserAction.Leave(FillLocal(address)));
}
I just wanted to check before, to be sure that it won't make any negative effect on anything.
Plus the self address comparison looks questionable.
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.
Might need to compare the output of FillLocal(address)
to SelfAddress
, although I'd need to look at the FillLocal
function again to say for that sure :p
if (tcs.Task.IsCompleted) | ||
return tcs.Task; | ||
// It's assumed here that once the member left the cluster, it won't get back again. | ||
// So, the member removal event being memoized in TaskCompletionSource and never reset. |
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.
Makes sense
/// <param name="task">The original task.</param> | ||
/// <param name="cancellationToken">The cancellation token.</param> | ||
/// <returns>The task which completes with result of original task or with cancelled state.</returns> | ||
public static Task WithCancellation(this Task task, CancellationToken cancellationToken) |
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.
Nice, I like it, although maybe we should mark this as internal
? cc @alexvaluyskiy
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.
The TaskExtensions
and Cluster
are in different assemblies.
I found this extensions class and decided to add the WithCancellation()
method here, but I can move it into another place if you know a better location.
Is the name WithCancellation
sounds good, BTW?
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.
@kostrse actually it's probably fine to leave this public
. WithCancellation
sounds great 👍
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.
The TaskExtensions and Cluster are in different assemblies.
We are using [InternalVisibleToAttribute]. So, It does not matter that these classes are situated in different assemblies
private Task LeaveSelf() | ||
{ | ||
var tcs = new TaskCompletionSource<object>(); | ||
var leaveTask = Interlocked.CompareExchange(ref _leaveTask, tcs.Task, null); |
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.
Nice solution
Note: windows-unit-tests are failing due to Api Approval. |
@kostrse for fixing the public API issue: http://getakka.net/docs/akka-developers/public-api-changes |
Thanks, will finalize the code review soon.
…----- Original message -----
From: Aaron Stannard <notifications@github.com>
To: "akkadotnet/akka.net" <akka.net@noreply.github.com>
Cc: Sergey Kostrukov <kostrse@gmail.com>, Mention <mention@noreply.github.com>
Subject: Re: [akkadotnet/akka.net] Cluster LeaveAsync() with CancellationToken support (#2501)
Date: Tue, 07 Feb 2017 08:55:46 -0800
@kostrse[1] for fixing the public API issue:
http://getakka.net/docs/akka-developers/public-api-changes
— You are receiving this because you were mentioned. Reply to this email
directly, view it on GitHub[2], or mute the thread[3].
Links:
1. https://github.com/kostrse
2. #2501 (comment)
3. https://github.com/notifications/unsubscribe-auth/ABFC9a8796xcTUTamCjps2UQDgspC2Blks5raKISgaJpZM4L3Jmm
|
@kostrse have you had a chance to update this yet? |
Sorry for delay, working on it now |
The test
I don't know yet the TestKit very well to track down the problem :( |
@kostrse would you mind handling the merge conflict here? |
Yes, sorry, will take a look now. |
the |
I added overload of the LeaveAsync() method with support of CancellationToken.
Cancellation token support should be useful assurance to avoid unexpected hang of application if member removal confirmation didn't come for some reason.
I also made the leave logic by LeaveAsync() to be triggered only once (via Interlocked). This is probably not critical for the cluster daemon, but just in case 😺 (related to #2498)
Usage example:
Related issues: #2280, #2498
Also:
Leave()
andLeaveAsync()
do not cooperate now, but it's possible to make Leave() callLeaveSelf()
to share state between them: