0

I have Receive Actor with switchable behaviors, switched by Become() method. To monitor child actors, I have to add Receive< Terminated > call to every state method.

For example, I have to paste it into Ready, Working1 and Working2 methods

public class SomeActor : ReceiveActor
{
    public SomeActor()
    {
        // create child actors
        Become(Ready);
    }

    private void Ready()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working1);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Working1()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working2);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Working2()
    {
        Receive<InitParcerMessage>(m =>
        {
            Become(Working1);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Terminated()
    {
        // do some stuff
    }
}
bonzaster
  • 313
  • 2
  • 12
  • 1
    It's hard to understand what actually are your trying to achieve. In akka monitoring/watching an actor is a term associated with checking it's aliveness using `Context.Watch(actorRef)`. Please, describe what do you actually want to monitor here. – Bartosz Sypytkowski Nov 11 '16 at 10:49
  • You can trigger an event and subscribe all children to it to let them know when you want to process the Terminated method at the end of the Become, in some middle point, etc – Zinov Dec 06 '16 at 13:30
  • @Zinov you mean simple c# event? – bonzaster Dec 06 '16 at 13:47
  • yes @bonzaster it should work on that way too, at the end the events are delegate types, so you can make the call – Zinov Dec 06 '16 at 13:55

1 Answers1

0

You are using a lambda to perform your action, instead you can create a private method that takes a type of Terminated as the parameter and use the MethodGroup in your Receive action.

public class SomeActor : ReceiveActor
{
    public SomeActor()
    {
        // create child actors
        Become(Ready);
    }

    private void Ready()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working1);
        });

        ConfigureReceive();
    }

    private void Working1()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working2);
        });

        ConfigureReceive();
    }

    private void Working2()
    {
        Receive<InitParcerMessage>(m =>
        {
            Become(Working1);
        });

        ConfigureReceive();
    }

    private void Terminated()
    {
        // do some stuff
    }

    private void ConfigureReceive()
    {
        // Register Receive actors here
        Receive<Terminated>(p => HandleTermination(p));
    }

    // Here's our method to perform the same job with our Terminated parameter
    private void HandleTermination(Terminated termination)
    {
        // Call our Become method
        Become(Terminated);
    }
}
ColinM
  • 2,622
  • 17
  • 29
  • Agree, but anyway I have to add this _Receive(HandleTermination);_ everywhere. Just imagine, that I want to handle more then one message types in this way, it will be much more duplicated lines – bonzaster Dec 06 '16 at 13:08
  • I've updated the code snippet. You'll have to have some code duplication somewhere, but this update trims it down to keep your `Receive` in a method so you only have to update code in one place. – ColinM Dec 06 '16 at 13:17
  • Thanks, it seems to be the answer – bonzaster Dec 06 '16 at 13:47