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

Need to document ActorInitializationException and how it occurs in actor lifecycle #5969

Open
Aaronontheweb opened this issue May 26, 2022 · 2 comments

Comments

@Aaronontheweb
Copy link
Member

Well I learned something new today

Throwing an exception in an actor's PreStart block will not allow the actor to be restarted: https://replit.com/@Aaronontheweb/ActorsPreStart#main.cs

I'm trying to imagine if that's by design or not (it might be since the child actor can't really complete its startup sequence if it fails there.)

Either way, that means this bug is more severe than I thought. We'll get this patched right away.

Originally posted by @Aaronontheweb in #5962 (comment)


One implication of this is that the actor's PostStop method is also never called, which causes functions that depend on PostStop for cleanup such as IWithTimers to never run correctly.

@ismaelhamed
Copy link
Member

I think that's because any exception in an actor's PreStart will throw ActorInitializationException, to which the default Supervisor Strategy will react by stopping (not restarting) the actor.

If you use a supervisor with a custom-defined Supervisor Strategy that restarts on every exception, then it'll work:

public class MySupervisorActor : UntypedActor
{
    private IActorRef actor;

    protected override SupervisorStrategy SupervisorStrategy() =>
        new OneForOneStrategy(Decider.From(_ => Directive.Restart));

    protected override void PreStart()
    {
        base.PreStart();
        actor = Context.ActorOf(Props.Create<MyActor>(), "myactor");
    }

    protected override void OnReceive(object message) => actor.Forward(message);
}

public class MyActor : UntypedActor
{
    public bool _failedOnce;

    protected override void PreStart()
    {
        if (_failedOnce)
            return;

        _failedOnce = true;
        throw new ApplicationException("crashing!");
    }

    protected override void OnReceive(object message) => Context.Sender.Tell(message);
}

@Aaronontheweb
Copy link
Member Author

In that case this is working as intended, but we should probably expand on this inside the documentation: https://getakka.net/articles/actors/fault-tolerance.html

@Aaronontheweb Aaronontheweb removed this from the 1.4.40 milestone Jun 2, 2022
@Aaronontheweb Aaronontheweb changed the title Akka.Actor: error thrown in PreStart escapes supervision strategy and PostStop is never called on actor Need to document ActorInitializationException and how it occurs in actor lifecycle Jun 2, 2022
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