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

Checking for termination #4

Open
varghesep opened this issue Jun 28, 2015 · 3 comments
Open

Checking for termination #4

varghesep opened this issue Jun 28, 2015 · 3 comments

Comments

@varghesep
Copy link

In the line 74 of AggregateCoordinator, there is a check for the terminated message. I can presume why there is a check, because the actor has to be removed from the list.

But I don't know why there is a check for pending commands from line 81 that done inside the block. Shouldn't the actor be recreated anytime there is a command for an actor and if it does not exist? In that case, shouldn't the code be from 81 to 91 outside of the if block as shown below?

     protected override bool Receive(object message) 
     { 
         var terminated = message as Terminated; 
         if (terminated != null) 
         { 
             // if Terminated message was received, remove terminated actor from terminating children list 
             _terminatingChildren.ExceptWith(new[] { terminated.ActorRef }); 
          }
         else 
         {
             // if there were pending commands waiting to be sent to terminated actor, recreate it 
             var groups = _pendingCommands.GroupBy(cmd => cmd.PersistenceId == terminated.ActorRef.Path.Name).ToArray(); 
             _pendingCommands = groups.First(x => !x.Key).ToList(); 
             var commands = groups.First(x => x.Key); 
             foreach (var pendingCommand in commands) 
             { 
                 var child = Recreate(pendingCommand.AggregateId, pendingCommand.PersistenceId); 
                 child.Tell(pendingCommand.Command, pendingCommand.Sender); 
             } 

             return true; 
         } 

         return false; 
     } 
@Horusiath
Copy link
Owner

The sole purpose of the default AggregateCoordinator.Receive method is to react on the Terminated actor messages, nothing else. Business rules concerned with forwarding messages are handled in classes inheriting from AggregateCoordinator.

@varghesep
Copy link
Author

I'm sorry to ask this again because I don't understand why there is a special processing of waiting commands after an actor is terminated.

As I understand about the termination, there is a delay from the time an actor is asked to terminate and when the actor is really terminated and the terminated message is sent. In that duration a new command can arrive.

After an actor is terminated, can any pending commands reached before termination, during the termination and after termination consider as regular commands and recreate the actor if necessary and ask the actor to process? This way, there is no need of running the pending commands when a terminated message is arrived but outside of the if block.

Could you please clarify why you had to process the pending commands as you have done?

@Horusiath
Copy link
Owner

Each actor has it's internal mailbox to buffer incoming messages. Problem is that after sending a Stop message to actor's mailbox, there may be still some messages posted to it, before it will be terminated. When that occurs, any messages waiting inside actor's mailbox will be dropped into DeadLetters. In fact that means, they would be lost.

Therefore aggregate coordinator's role is to buffer messages send to dying children in order to resend them later after coordinator will resurrect the child. This is one of the easier implementations of a pattern called Passivate.

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

2 participants