Accepted answer

I'll assume here that you mean you need a "Message A" to arrive before you can process a "Message B". Other alternatives are:

  • You want to receive any "Message A" before a "Message B" if the queue has both -- you cannot do this;
  • You want "Message A" to be processed before "Message B" if they are sent in that order -- that is how it works already, from the same sender, and you can't do that if the senders are different.

So, having discarded these other options, here's a technique. First, define separate receive methods for the state when Message A is expected and Message B is expected:

def receivingA = Receive {
  case MessageA(x) => ...

def receivingB = Receive {
  case MessageB(y) => ...

You can set the first one as the default:

def receive = receivingA

When receiving message A, you can change the state to expect message B:

case MessageA(x) =>
  // do stuff

And on message B you can go back to the first case, but I'll skip that.

Now the only thing missing is what you are going to do with messages arriving when not expected. You can do nothing, which will send them to the error log, or you can do something by overriding this method:

def unhandled(msg: Any): Unit = message match {
  case Terminated(target) => ...
  case msg => ...

The default behavior publishes unhandled message to the system event stream, as objects of type UnhandledMessage, so you could also get them that way, though that will just reinsert them into the queue under a different type. Finally, you could receive Message B out of order and queue it, then resend them once Message A is received.

Related Query

More Query from same tag