Problems with multiple trait mixins and Actors - scala

trait A extends Actor {
private val s = Set[Int]()
override def act() {
loop {
react {
// case code that modifies s
}
}
}
}
trait B extends Actor {
private val t = Set[String]()
override def act() {
loop {
react {
// case code that modifies t
}
}
}
}
val c = new C with A with B //...?
What I really want is some sort of auto-combining of B.act() and C.act(), but with trait mix-ins, only B.act() will be called. Is there an easy way to accomplish this?
EDIT: Here is a half-solution I've found. I say 'half' because the original traits no longer extend Actor, and C with A with B needs to be defined as a class as opposed to dynamic mixing-in. Maybe I should call it a 'quarter-solution'?

Maybe you could make a trait that forwards the message on to a list of other Actors, so that you don't have to modify A or B:
trait C extends Actor {
private val acts: Seq[Actor] = Seq(new A{}, new B{})
override def act() {
acts foreach (_.start)
loop {
react { case x => acts foreach { _ ! x } }
}
}
}
You could of course leave acts abstract or override it with a different set when you instantiate this.

Extending the Actor class:
import actors.Actor
class MixableActor extends Actor {
protected var acts = List[PartialFunction[Any, Unit]]()
final override def act() {
loop {
react {
acts.reduce((a, b) => a orElse b)
}
}
}
final def receive(act: PartialFunction[Any, Unit]) {
acts = act :: acts
}
}
Sample Code:
abstract class Node extends MixableActor {
...
}
trait User extends MixableActor {
val files = scala.collection.mutable.Set[Data]()
}
trait Provider extends User {
receive({
case ("provide", file: Data) =>
provide(file)
}: PartialFunction[Any, Unit])
}
trait Consumer extends User {
receive({
case ("consume", file: Data) =>
consume(file)
}: PartialFunction[Any, Unit])
}
Sample Usage:
val provider = new Node with Provider
val consumer = new Node with Consumer
val provider_and_consumer = new Node with Provider with Consumer

Related

Inject different factories to the same actor

I'm new to Akka and Guice, and just started to explore it.
I'm trying to make a father actor, that produce child actors from one specific type, to be more generic- so it'll produce many kind of child actors with different types.
Currently- I inject to the father-actor a Factory of one specific type of actor,
I don't want to add more cases to the father actor, I'd like to solve this problem in more elegant way.
so now I have 2 child actors, and I want to Inject their factory to the father-actor, to do so i thought that maybe I should create the father-actor twice, and each time to inject a different type of Factory.
what I would want to achieve is something like this code
(this code is not working, but this is the idea):
Base Factory trait:
trait BaseFactory {
apply(id: Int) : Actor
}
object FirstActor {
trait Factory extends BaseFactory
}
class FirstActor (#Assisted id: Int) extends Actor with InjectedActorSupport {
....
}
object SecondActor {
trait Factory extends BaseFactory
}
class SecondActor (#Assisted id: Int) extends Actor with InjectedActorSupport {
....
}
class Father #Inject()(factory: BaseFactory, name: String) extends Actor with InjectedActorSupport {
override def receive: Receive = {
case Command =>
...
val actor = context.child(id)
.getOrElse(injectedChild(factory(id), name, _.withMailbox("deque-mailbox")))
}
}
And then the module:
(this part is not compiling since I can't pass the Factories to props as a trait definition and not an instance)
class Module extends AkkaGuiceSupport {
def configure(): Unit = {
bindActor[ExecutorsOffice]("FirstFather", Props(new Father(FirstActor.Factory)))
bindActor[ExecutorsOffice]("SecondFather", Props(new Father(SecondActor.Factory)))
bindActorFactory[FirstActor, FirstActor.Factory]
bindActorFactory[SecondActor, SecondActor.Factory]
}
I'll be happy to hear your thoughts, and your solutions (other solutions will be great also!)
I'm not sure why you'd need Guice-injection.
type PropsCreator = String => Props
object ParentActor {
def props(childPropsCreator: PropsCreator) = Props(classOf[ParentActor], childPropsCreator)
}
class ParentActor(childPropsCreator: PropsCreator) extends Actor {
// yadda yadda yadda
def receive(): Receive = {
case x: Command =>
// yadda yadda yadda
val child = context.child(id)
.getOrElse(context.actorOf(childPropsCreator(id), id))
child.forward(x)
}
}
object DdvRenderProcessManager {
def props(id: String) = Props(classOf[DdvRenderProcessManager], id)
}
class DdvRenderProcessManager(id: String) extends Actor {
// definition omitted
}
object UpdateProcessManager {
def props(id: String) = Props(classOf[UpdateProcessManager], id)
}
class UpdateProcessManager(id: String) extends Actor {
// definition omitted
}
Then you'd create parents like
val ddvRenderParent = system.actorOf(ParentActor.props(DdvRenderProcessManager.props _), "ddvRenderParent")
val updateParent = system.actorOf(ParentActor.props(UpdateProcessManager.props _), "updateParent")
If you wanted to, for instance have all the DdvRenderProcessManagers have a certain dynamic value:
object DdvRenderProcessManager {
// could also express as
// def props(x: Int)(id: String): Props
// and curry, but this expression is clearer about intent
def propsFor(x: Int): String => Props = { (id: String) =>
Props(classOf[DdvRenderProcessManager], id, x)
}
}
class DdvRenderProcessManager(id: String, x: Int) extends Actor {
// definition omitted
}
And then
val ddvRenderParent = system.actorOf(ParentActor.props(DdvRenderProcessManager.propsFor(42)), "ddvRenderParent")
You could even make the dynamic value implicit to allow for something very-close to compile-time DI.

Injecting Akka's TestProbe in place of child actors

I have a parent actor named "manager" which creates several child actors.
These child actors then send back their response via "sender tell", i.e directly back to "manager".
I want to create a unit test for this manager actor, and therefore need to inject a probe to forward the messages from the manager to its children.
I used the following post:
http://www.superloopy.io/articles/2013/injecting-akka-testprobe.html
However i'm still having some trouble getting this done correctly.
In order to simplify the situation, attached is code describing the actors and unit test i wrote for just one child.
Manager class:
trait ManagerChildProvider {
def createTimestampPointChild: Actor
}
trait ProductionManagerChildProvider extends ManagerChildProvider {
def createTimestampPointChild = new TimeDifferenceCalculationActor
}
object Manager {
def apply() = new Manager("cid1") with ProductionManagerChildProvider
}
class Manager(name: String) extends Actor with ActorLogging {
this: ManagerChildProvider =>
#Autowired private val modelParams = new ModelParams //list of parameters
val timeDifference = context.actorOf(Props(createTimestampPointChild))
def receive = {
case p#TimePoint(tPoint) =>
timeDifference ! p
case _ =>
log.error("Unknown message type")
}
}
Child class:
class TimeDifferenceCalculationActor extends Actor with ActorLogging {
var previousTimestamp: Long = -1
def receive = {
case tPoint(timestamp) =>
if (previousTimestamp != -1) {
sender ! Result(1)
}
case _ =>
log.error("Unknown message type")
}
}
Test class:
object BarSpec {
class Wrapper(target: ActorRef) extends Actor {
def receive = {
case x => target forward x
}
}
}
trait ChildrenProvider {
def newFoo: Actor
}
class BarSpec extends TestKitSpec("BarSpec") {
import Manager._
import BarSpec._
trait TestCase {
val probe = TestProbe()
trait TestChildrenProvider extends ManagerChildProvider {
def newBar = new Wrapper(probe.ref)
}
val actor = system.actorOf(Props(new Manager(componentId = "cid1") with TestChildrenProvider))
}
"Bar" should {
"involve child in doing something" in new TestCase {
actor ! tPoint(1)
actor ! tPoint(2)
probe.expectMsg(tPoint(1))
//probe.reply("ReplyFromChild")
//expectMsg("ReplyFromParent")
}
}
}
Additional test class:
abstract class TestKitSpec(name: String) extends TestKit(ActorSystem(name)) with MustMatchers with BeforeAndAfterAll with ImplicitSender with WordSpecLike{
override def afterAll() {
system.shutdown()
}
}
Currently i get the following errors:
Error:(36, 42) object creation impossible, since method > createTimestampPointChild in trait ManagerChildProvider of > type => akka.actor.Actor is not defined
val actor = system.actorOf(Props(new Manager(componentId = "cid1") with TestChildrenProvider))
Error:(11, 16) overriding method run in trait BeforeAndAfterAll of type > (testName: Option[String], args: > org.scalatest.Args)org.scalatest.Status;
method run in trait WordSpecLike of type (testName: Option[String], > args: org.scalatest.Args)org.scalatest.Status needs `abstract override' > modifiers
abstract class TestKitSpec(name: String) extends > TestKit(ActorSystem(name))
any help with these specific errors or with the task in general would be highly appreciated

Call body of all traits inherited

Say I have the below:
type Receive = PartialFunction[Any, Unit]
trait Functionality {
/**
* A set containing all Receive functions
*/
var allReceives: Set[Receive] = Set[Receive]()
}
Now other trait's can extend Functionality and do awesome stuff. Example:
trait LoadBalancer extends Functionality{
def body:Receive = {
case ...
}
allReceives += body
}
And ultimately my class:
class Main with LoadBalancer with SecurityFunctionality
with OtherFunctionality with Functionality{
def receive = {
case x if allReceives.foldLeft(false) { (z, f) => if (f isDefinedAt x) { f(x); true } else z } == true => ()
}
def body: Receive = {
}
allReceives += body
}
Question: What I wish to do is, in Main I need to call body function of all the traits that I have inherited. This way my code can be loosely coupled and I can add/remove functionality at a go.
The above works, but I do not like it as the compiler cannot guarantee that any trait that extends Functionality should add its body to allReceives.
I cannot declare def body:Receive in Functionality as then my implementation in Main will override body implementations of other traits. I am sure there should be a smarter way!
On second thought, composition really might be a better option here. This is a simpler solution, without any funny "abstract override"s:
object Main {
type Receive = PartialFunction[Any, Unit]
trait Receiver {
def receive: Receive
}
class LoadBalancer extends Receiver {
override def receive: Receive = {
case "one" => println("LoadBalancer received one")
}
}
class OtherFunctionality extends Receiver {
override def receive: Receive = {
case "two" => println("OtherFunctionality received two")
}
}
class MainFunctionality extends Receiver {
override def receive: Receive = {
case "three" => println("MainFunctionality received three")
}
}
class CompositeReceiver(receivers: List[Receiver]) extends Receiver {
override def receive: Receive = {
case msg =>
receivers.find(_.receive.isDefinedAt(msg)) map (_.receive(msg))
}
}
def main(args: Array[String]) {
val main = new CompositeReceiver(List(new OtherFunctionality, new LoadBalancer, new MainFunctionality))
main.receive("one")
main.receive("two")
main.receive("three")
}
}
This does not really answer your question, but here is a solution using the stackable traits pattern. Alas you still need to call super.receive as the last case in each trait, but I could not find a way around that yet.
object Main {
type Receive = PartialFunction[Any, Unit]
trait Receiver {
def receive: Receive
}
trait LoadBalancer extends Receiver {
abstract override def receive: Receive = {
case "one" => println("LoadBalancer received one")
case msg => super.receive(msg)
}
}
trait OtherFunctionality extends Receiver {
abstract override def receive: Receive = {
case "two" => println("OtherFunctionality received two")
case msg => super.receive(msg)
}
}
class Main extends Receiver {
override def receive: Receive = {
case "three" => println("Main received three")
}
}
def main(args: Array[String]) {
val main = new Main with OtherFunctionality with LoadBalancer
main.receive("one")
main.receive("two")
main.receive("three")
}
}

Reduce code duplication by abstracting mixing class

I have to actor classes which looks similar to this form:
class ActorSupervisorOne(prop: Prop) extends Actor {
val dbSuper = context.actorOf(prop)
val subActor = context.actorOf(Props(new SubActorClass(dbSuper) with **SomeHandlersOne**))
def receive = {
case msg =>
subActor forward msg
}
}
class ActorSupervisorTwo(prop: Prop) extends Actor {
val dbSuper = context.actorOf(prop)
val subActor = context.actorOf(Props(new SubActorClass(dbSuper) with **SomeHandlersTwo**))
def receive = {
case msg =>
subActor forward msg
}
}
The only difference between them in mixing trait. Abstract it with type parameter or abstract type member won't work. I've tried the following solution, but it looks ugly and still have code duplication:
abstract class Super extends Actor {
_: {
val handler: Props
} =>
lazy val actor = context.actorOf(handler)
def receive = {
case msg =>
actor forward msg
}
}
class ActorSupervisorOne(val dbSuper: ActorRef) extends Super {
val handler = Props(new SubActorClass(dbSuper) with SomeHandlersOne)
actor
}
class ActorSupervisorTwo(val dbSuper: ActorRef) extends Super {
val handler = Props(new SubActorClass(dbSuper) with SomeHandlersTwo)
actor
}
But in this case i have to call actor to initialize it correctly or it won't work. Are there any other solution how this can be reduced?
You could probably use reflection to choose the SomeHandlersXYZ at runtime, but if you don't want to resort to reflection then I don't think that there is a way of achieving what you want without at least duplicating the subactor instantiation code (see this answer of mine for an explanation). You could do it the following way (sketched), where you basically pass in a factory function:
class ActorSupervisor(prop: Prop, getSubActor: Actor => SubActorClass) extends Actor {
val dbSuper = context.actorOf(prop)
val subActor = context.actorOf(Props(getSubActor(dbSuper)))
def receive = {
case msg =>
subActor forward msg
}
}
val asOne = new ActorSupervisor(..., a => new SubActorClass(a) with SomeHandlersOne)
val asTwo = new ActorSupervisor(..., a => new SubActorClass(a) with SomeHandlersTwo)
What about this solution:
class ActorSupervisor(subActor: => Actor) extends Actor {
val actor = context.actorOf(Props(statsProps))
def receive = {
case msg =>
actor forward msg
}
}
and then, like in Malte Schwerhoff you can create new actor like this:
val first = new ActorSupervisor(new SubActorClass(...) with SomeHandlersOne)
I think that more elegant colution can be achived with macros, but i'm not good at them
You can pass the puck on onReceive.
class ClassMixed(params: Options*)
extends BaseClass(params: _*)
with Mixin {
override def receive =
mixinReceive orElse receive
}
where Mixin has a method called mixinReceive and BaseClass overrides receive

Composing trait behavior in Scala in an Akka receive method

Consider these two traits:
trait Poked extends Actor {
override def receive = {
case Poke(port, x) => ReceivePoke(port, x)
}
def ReceivePoke(port: String, x: Any)
}
trait Peeked extends Actor {
override def receive = {
case Peek(port) => ReceivePeek(port)
}
def ReceivePeek(port: String)
}
Now consider I can create a new Actor that implements both traits:
val peekedpoked = actorRef(new Actor extends Poked with Peeked)
How do I compose the receive handlers? i.e., the receiver should be something like the following code, though "automatically generated" (i.e., all traits should compose):
def receive = (Poked.receive: Receive) orElse (Peeked.receive: Receive) orElse ...
You can use super[T] to reference members of particular super classes/traits.
For example:
trait IntActor extends Actor {
def receive = {
case i: Int => println("Int!")
}
}
trait StringActor extends Actor {
def receive = {
case s: String => println("String!")
}
}
class IntOrString extends Actor with IntActor with StringActor {
override def receive = super[IntActor].receive orElse super[StringActor].receive
}
val a = actorOf[IntOrString].start
a ! 5 //prints Int!
a ! "Hello" //prints String!
Edit:
In response to Hugo's comment, here's a solution that allows you to compose the mixins without having to manually wire their receives together. Essentially it involves a base trait with a mutable List[Receive], and each mixed-in trait calls a method to add its own receive to the list.
trait ComposableActor extends Actor {
private var receives: List[Receive] = List()
protected def registerReceive(receive: Receive) {
receives = receive :: receives
}
def receive = receives reduce {_ orElse _}
}
trait IntActor extends ComposableActor {
registerReceive {
case i: Int => println("Int!")
}
}
trait StringActor extends ComposableActor {
registerReceive {
case s: String => println("String!")
}
}
val a = actorOf(new ComposableActor with IntActor with StringActor).start
a ! 5 //prints Int!
a ! "test" //prints String!
The only thing to keep in mind is that the order of the receives should not be important, since you won't be able to easily predict which one is first in the chain, though you could solve that by using a mutable hashmap instead of a list.
You can use empty Receive in base actor class and chain receives in their definitions.
Sample for Akka 2.0-M2:
import akka.actor.Actor
import akka.actor.Props
import akka.event.Logging
import akka.actor.ActorSystem
class Logger extends Actor {
val log = Logging(context.system, this)
override def receive = new Receive {
def apply(any: Any) = {}
def isDefinedAt(any: Any) = false
}
}
trait Errors extends Logger {
override def receive = super.receive orElse {
case "error" => log.info("received error")
}
}
trait Warns extends Logger {
override def receive = super.receive orElse {
case "warn" => log.info("received warn")
}
}
object Main extends App {
val system = ActorSystem("mysystem")
val actor = system.actorOf(Props(new Logger with Errors with Warns), name = "logger")
actor ! "error"
actor ! "warn"
}