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

starting timer during prestart seems to sometimes cause an "ActorInitializationException: Exception during creation" #6971

Open
brah-mcdude opened this issue Oct 24, 2023 · 3 comments

Comments

@brah-mcdude
Copy link
Contributor

Cause: [akka://test/user/b#653027469]: Akka.Actor.ActorInitializationException: Exception during creation
 ---> System.InvalidOperationException: Worker in invalid state: 1
   at Akka.Actor.HashedWheelTimerScheduler.Start()
   at Akka.Actor.HashedWheelTimerScheduler.InternalSchedule(TimeSpan delay, TimeSpan interval, IRunnable action, ICancelable cancelable)
   at Akka.Actor.HashedWheelTimerScheduler.InternalScheduleTellOnce(TimeSpan delay, ICanTell receiver, Object message, IActorRef sender, ICancelable cancelable)
   at Akka.Actor.SchedulerBase.Akka.Actor.ITellScheduler.ScheduleTellOnce(TimeSpan delay, ICanTell receiver, Object message, IActorRef sender, ICancelable cancelable)
   at Akka.Actor.SchedulerExtensions.ScheduleTellOnceCancelable(IScheduler scheduler, TimeSpan delay, ICanTell receiver, Object message, IActorRef sender)
   at Akka.Actor.Scheduler.TimerScheduler.StartTimer(Object key, Object msg, TimeSpan timeout, TimeSpan initialDelay, Boolean repeat)
   at Akka.Actor.Scheduler.TimerScheduler.StartSingleTimer(Object key, Object msg, TimeSpan timeout)

Version Information
Version of Akka.NET?
1.5.13
Which Akka.NET Modules?
Akka.Actor.Scheduler.TimerScheduler
Akka.Actor.HashedWheelTimerScheduler

Describe the bug
I am running my tests. I am using the "Run Until Failure" menu item in the test explorer menu.
The tests always fail. Usually only after a few iterations (at around 70 iterations).

Last test log:
Test run finished: 119 Tests (118 Passed, 1 Failed, 0 Skipped) run in 15.9 min. Finished at iteration 127

To Reproduce
Steps to reproduce the behavior:
In my app, many things happen, but the essence of the bug (i did not write a separate test for this - so take it as an unproved theory):

  1. create actor and start timer in prestart
  2. "Run Until Failure" menu item in the test explorer menu
  3. See error after many iterations

Expected behavior
I expect this exception to NOT happen. And for the tests iterations to continue.

Actual behavior
Test stops after a few iterations.

Environment
running on Windows.
Which version of .NET?
"Welcome to .NET 7.0!
SDK Version: 7.0.403"

@Aaronontheweb
Copy link
Member

@brah-mcdude can you provide some actor code that we can look at in order to help reproduce?

@Aaronontheweb
Copy link
Member

Just for clarification: this bug affects actors who use IWithTimers and call the StartTimer method inside the actor's PreStart override

@Aaronontheweb
Copy link
Member

I tried to reproduce this @brah-mcdude

async Task Main()
{
	// Initialize Actor System
	var system = ActorSystem.Create("MySystem");

	// Create Props for the EchoActor
	var props = Props.Create<EchoActor>();

	// Create the EchoActor
	var echoActor = system.ActorOf(props, "echoActor");

	// Send 10 messages to the EchoActor
	for (int i = 0; i < 10; i++)
	{
		echoActor.Tell($"Message {i + 1}");
	}

	// Allow some time for messages to process before shutting down
	await system.WhenTerminated;
}

// Define the EchoActor class
public class EchoActor : ReceiveActor, IWithTimers
{
	private readonly ILoggingAdapter _log = Context.GetLogger();
	private int _msgCount = 0;
	public ITimerScheduler Timers { get; set; }

	public EchoActor()
	{
		NormalBehavior();
	}

	private void NormalBehavior()
	{
		ReceiveAny(message =>
		{
			_log.Info("Hit {0}", _msgCount++);
			if(_msgCount >= 10){
				Context.System.Terminate();
			}
		});
	}

	private class RecoverMarker { }

	protected override void PreRestart(Exception ex, object message)
	{
		Timers.StartPeriodicTimer("foo", "bar", TimeSpan.FromMilliseconds(100));
	}

}

Worked normally - what's the issue?

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

No branches or pull requests

2 participants