Skip to content
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

Bug: DefaultMailbox.PostSystemMessage CancellationTokenDisposed exception #1916

Closed
woksin opened this issue Jan 30, 2023 · 4 comments
Closed

Comments

@woksin
Copy link
Contributor

woksin commented Jan 30, 2023

I see that sometimes when running tests (for instance here https://github.com/asynkron/protoactor-dotnet/actions/runs/4042463067/jobs/6950198101#step:6:111 )
that the DefaultMailbox.PostSystemMessage can throw an exception when the _invoker.CancellationTokenSource is disposed.

This leads ne to the questions:

  1. Why is this CancellationTokenSourceeven exposes as an API? (I don't know if there are any reason to why, if so then it would be nice to know 😄 )
  2. Why doesn't the IMessageInvoker itself take the responsibility of cancelling its CancellationTokenSource as part of the Disposing it will eventually do whenever the ActorContext FinalizeStopAsync is inevitably called?

And please excuse my ignorance. I'm fairly new to this project and especially the code base 😆

@rogeralsing
Copy link
Contributor

Hi Sindre, good questions.
These are basically parts of the old dungeons of Proto.Actor so I have to refresh my memory on these parts.

From the mailbox code, we have this:

    public void PostSystemMessage(object msg)
    {
        _systemMessages.Push(msg);

        if (msg is Stop)
        {
            _invoker?.CancellationTokenSource?.Cancel();
        }

My guess w/o digging any deeper would be that the same actor has already received a stop message. and thus the cts is disposed.

Why is this not cancelled inside the actor context?
Let's say an actor is currently working on a long running task, it cannot consume any system messages during this time until the user message is done.
cancelling outside of the actor would allow the actor to stop the current task, and then properly consume the stop message.

But I need to have a better look at all this.

@woksin
Copy link
Contributor Author

woksin commented Jan 30, 2023

My guess w/o digging any deeper would be that the same actor has already received a stop message. and thus the cts is disposed.

Yes that's my guess as well.

Let's say an actor is currently working on a long running task, it cannot consume any system messages during this time until the user message is done.
cancelling outside of the actor would allow the actor to stop the current task, and then properly consume the stop message.

I see... That make sense in terms of what the system should do, thanks for the explanation.

From just my outsider perspective I think that the CancellationTokenSource is perhaps too low-level of an abstraction to fit on IMessageInvoker interface, and frankly what it actually does is hidden in its implementation so it's hard to tell 😄. ; My suggestion, although maybe naive, would be to eventually remove that property (could make it obsolete for now) and replace it with a method for specifically terminating the the current running task.

I also don't have too much experience using Proto.Actor extensively, but since the CancellationTokenSource is on the IMessageInvoker and ActorContext is implementing IMessageInvoker is it intended for the user of the framework to be able to interact directly with this CancellationTokenSource? To me it seems like a way to easily shoot yourself in the foot in terms of havoc you can cause? 😆

@DenizPiri
Copy link
Contributor

We experience the same issue. We have 600+ tests, each starting and shutting down a cluster; usually, 1 or 2 tests at random experience this error.

I believe this is because of the ActorContextExtras.Dispose() function doing a CancellationTokenSource.Dispose() call. CancellationTokenSource doesn't require Dispose() call when only Cancel() is used.

I will submit a PR.

DenizPiri added a commit to AhoyGames/protoactor-dotnet that referenced this issue Feb 8, 2023
…ContextExtras.Dispose().

It should fix the CancellationTokenDisposed exception issue asynkron#1916
rogeralsing pushed a commit that referenced this issue Feb 8, 2023
…ContextExtras.Dispose(). (#1920)

It should fix the CancellationTokenDisposed exception issue #1916
@woksin
Copy link
Contributor Author

woksin commented Feb 9, 2023

Should we consider this issue solved now with #1920 ?

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

No branches or pull requests

3 participants