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

ReceiveAsync paired with Timers results in actors never stopping from idle timeout #6653

Closed
aplant-sb opened this issue Apr 19, 2023 · 10 comments · Fixed by #6718
Closed

ReceiveAsync paired with Timers results in actors never stopping from idle timeout #6653

aplant-sb opened this issue Apr 19, 2023 · 10 comments · Fixed by #6718

Comments

@aplant-sb
Copy link

aplant-sb commented Apr 19, 2023

Version Information
Version of Akka.NET?
1.4.47
Which Akka.NET Modules?
Akka Dependency Injection (also 1.4.47)

Describe the bug
When setting up a periodic timer for an actor with a message that inherits INotInfluenceReceiveTimeout, the actor from which the timers were set is never stopped from inactivity, even when only these timed messages have been arriving beyond the receive timeout. This only happens when the message the timer sends is handled by ReceiveAsync, instead of Receive.

This seems to be due to the fact ReceiveAsync resets any pending ReceiveTimeout messages as part of it's flow, and so if the timer is producing messages more frequently than the ReceiveTimeout for the actor, it will never stop. The relevant code is in the ActorTaskScheduler class in the RunTask method. This calls into the actor context CheckReceiveTimeout() method, which appears to cancel any pending ReceiveTimeout messages and schedules a new one to be sent after the actors Receive Timeout amount has elapsed

To Reproduce
Steps to reproduce the behavior:

  1. Setup a Periodic Timer in a ReceiveActor (StartPeriodicTimer)
  2. Ensure the ReceiveTimeout is set on the actor, but at a duration that is higher than the frequency of the periodic timer
  3. Register an async method for the object being sent from the periodic timer in the actor (e.g. ReceiveAsync)
  4. Add appropriate logging and note that the actor will never stop from inactivity

Expected behavior
I would expect that given we are inheriting from INotInfluenceReceiveTimeout, the timed messages should not reset the inactive duration for the actor, and that the actor should eventually be sent a ReceiveTimeout message.

Actual behavior
Actor continues running due to the timer indirectly causing the inactive duration to reset through the ReceiveAsync method

Environment
Running Windows and .NET 6.0

Additional context
This may be expected and understood behavior from the ReceiveAsync method - I just couldn't find any documentation explaining it as thus, and this setup also feels like a gotcha in terms of perceived behavior and actual behavior.

Would be interested in the thoughts around this, and if there's other ways around doing a timer in an actor who's message is handled asynchronously from within the Akka library, without resorting to a custom implementation.

@ismaelhamed
Copy link
Member

@Aaronontheweb I wonder if ActorTaskSchedulerMessage, issued by the ActorTaskScheduler.RunTask(), should implement INotInfluenceReceiveTimeout?

@Aaronontheweb
Copy link
Member

@Aaronontheweb I wonder if ActorTaskSchedulerMessage, issued by the ActorTaskScheduler.RunTask(), should implement INotInfluenceReceiveTimeout?

I think that's all handled through the system messages pipeline, so that shouldn't affect the IWithTimers and ReceiveTimeout bits as though all reside inside the user messages pipeline.

@Aaronontheweb
Copy link
Member

This seems to be due to the fact ReceiveAsync resets any pending ReceiveTimeout messages as part of it's flow

If this is the case, then @ismaelhamed is correct and this should be easy to reproduce and fix.

@Aaronontheweb
Copy link
Member

@aplant-sb thanks for taking the time to file this bug report - we'll look into it. If we issue a patch, are you able to upgrade to Akka.NET v1.5? Saw that you're using v1.4.

@Aaronontheweb
Copy link
Member

Worst case scenario: we could backport a fix to v1.4 if it was totally necessary. Our branching strategy allows that.

@aplant-sb
Copy link
Author

Yep that should be fine I believe @Aaronontheweb - thanks for looking into this for us!

@Aaronontheweb Aaronontheweb modified the milestones: 1.5.4, 1.5.5 Apr 25, 2023
@josel-sportsbet
Copy link

@Aaronontheweb Just checking in to see if there is any update?

@Aaronontheweb
Copy link
Member

Not yet, but we'll look at it today. @josel-sportsbet @aplant-sb

@Aaronontheweb
Copy link
Member

Possible solution area for this: #6461 - mark those messages as INoInfluenceReceiveTimeout

@Aaronontheweb
Copy link
Member

This will be fixed in v1.5.5, which we will release today or tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants