Michal Pawluk
Michal Pawluk

Reputation: 581

Akka, Generic ActorRef?

I'm rather new to Scala so this may be a trivial question. I'm trying to put together a simple project in Akka and I'm not sure how to handle a situation where I need to store a reference to an actor of a constrained type. Let's assume I have an actor trait

trait MyActorTrait extends Actor

Then somewhere else I would like to define another trait with a member

def reference: ActorRef[MyActorTrait]

That obviously doesn't work since ActorRef doesn't care about the target actor's type (or does it?). Is there any way to constrain the reference to only accept references to actors that extend MyActorTrait?

Upvotes: 0

Views: 401

Answers (3)

Michal Pawluk
Michal Pawluk

Reputation: 581

After some digging around I believe I've found a way. First I create a trait which will preserve the actor type

trait TypedActorRef[T <: Actor] {
  def reference: ActorRef
  type t = T
}

Then implement a generic apply which instantiates a private case class extending the trait

object TypedActorRef {
  private case class Ref[T <: Actor] (reference: ActorRef) extends TypedActorRef[T]
  def apply[T <: Actor](actor: T) = {
    Ref[T](actor.self)
  }
}

With that I can keep a reference which is restricted an actor of the type I want.

trait OtherActor extends Actor

trait MyActor extends Actor
{
  def otherActorsReference: TypedActorRef[OtherActor]
}

This seems OK to me, at least this seems not to upset the compiler, but I'm not sure if this solution prevents from creating other extensions of the TypedActorRef which may not respect the same constraints.

Upvotes: 0

Laksitha Ranasingha
Laksitha Ranasingha

Reputation: 4509

The way you try to reference an actor in another actor is not right. Actors form a hierarchy. So it gives you a path to refer an actor. There are mainly three ways you could reference another actor using

  • Absolute Paths
 context.actorSelection("/user/serviceA")
  • Relative Paths
context.actorSelection("../brother") ! msg
  • Querying the Logical Actor Hierarchy
context.actorSelection("../*") ! msg

You may have a look at the doc - https://doc.akka.io/docs/akka/2.5/general/addressing.html.

Upvotes: 0

Dima
Dima

Reputation: 40500

By design, there is no way you can access the underlying Actor through ActorRef (or, pretty much, any other way). So, constraining the type like you describe is pointless, there would be absolutely no difference in what you can do with ActorRef[Foo] vs. ActorRef[Bar].

Not saying, this is a good thing (few things in Akka can be characterized that way IMO), but that's just the way it is.

Upvotes: 2

Related Questions