How to use stackable trait pattern with Akka actors?

akka, scala, traits

Solution

There's a simple and concise solution:

Define a Receiving trait that chains multiple receive functions using `orElse` :

trait Receiving { 
  var receivers: Receive = Actor.emptyBehavior 
  def receiver(next: Actor.Receive) { receivers = receivers orElse next }
  def receive = receivers // Actor.receive definition
}

Using this in actors is easy:

trait PubSubActor extends Receiving {
  receiver {
    case Publish => /* I'm the first to handle messages */
  }
}

class MyActor extends PubSubActor with Receiving {
  receiver {
    case SomeMessage => /* PubSubActor didn't handle, I receive the message */ 
  }
}

First PubSubActor's receive will be called. If message wasn't handled it will be passed to MyActor's receive.

Problem

I'm trying to implement a Pub/Sub trait to mix into other akka actors using a stackable trait. Here is what I came up with: ``` trait PubSubActor extends Actor { abstract override def receive = super.receive orElse { case Subscribe(topic) => /* ... */ case Publish(topic, msg) => /* ... */ } } class MyActor extends Actor with PubSubActor { override def receive = { case SomeMessage(a, b, c) => /* ... */ } } ``` At which point, the compiler throws back an error: error: overriding method receive in trait MyActor... method receive needs `abstract override' modifiers. Can you explain to me why this isn't working? How can I fix it so it works? Thanks! UPDATE The following works: ``` trait PubSubActor extends Actor { abstract override def receive = super.receive orElse { case Subscribe(topic) => /* ... */ case Publish(topic, msg) => /* ... */ } } class MyActor extends Actor { override def receive = { case SomeMessage(a, b, c) => /* ... */ } } class MyActorImpl extends MyActor with PubSubActor ``` But why? Why can I get the behavior I want this way but not the other? Any reasons? I can't seem to figure out the underlying difference between these two samples that makes the difference.

Original source