0

I have to create a set of persistent actors and route messages to them by some id. When I do this, in my router actor I look up the target one using something like:

context.child(id) getOrElse create(id) - creating actors by context.actorOf()

and after the router has found the child, it forwards the message (otherwise creates the child first).

To save the space, I'm also using some sort of custom passivation for the child actors by calling on them - setReceiveTimeout => ReceiveTimeout => send the actor to be passivated a custom Shutdown message, on receiving which it calls context.stop(self).

What if the actual actor shutdown occurs just after the parent actor has obtained the ActorRef to the child which is already in progress of stopping, but before it forwards the message? Would the message be lost?

I thought this problem is handled in akka sharding (by ShardRegion, probably) by saving the incoming messages and replaying them on actor reactivation.

The problem is due to requirements I cannot use Akka Sharding. Is there a ready solution or a pattern to the problem of handling messages for passivating actors?

Thanks

kiwi
  • 31
  • 3

1 Answers1

0

The router and the child actor are running async, so there's always a chance that when the child call context.stop(self) there are still messages pending in mailbox. In that case, those messages will be lost (routed to deadletter)

To avoid message lost, child cannot shutdown on it's own and need to coordinate with the router. E.g.:

  1. child: setReceiveTimeout
  2. child: on receiving ReceiveTimeout, send a custom Stopping message to router
  3. router: on receiving Stopping, stop routing message to child and send custom Stop message (or PoisonPill) to child
  4. child: on receiving Stop, call context.stop(self)

In step 3, router might need to maintain it's own map of children instead of relying on context.child

And in step 4, since the order of messages between two actors are guaranteed, the Stop message will always be the last from router thus safe to stop.

PH88
  • 1,796
  • 12
  • 12
  • So do I also need to stash/save to a map the message which cannot be delivered, and then unstash it ? Since the passivated actor needs to be activated on the first incoming message anyway. – kiwi Jul 07 '18 at 22:40
  • As to sending the PoisonPill - not sure it works well with persistent actors (as in my case) – kiwi Jul 07 '18 at 22:52