Reputation: 1371
If I have following Actor (MyActor) with a companion object.
object MyActor {
}
class MyActor extends Actor{
}
Now I want to delcare a method in a companion object like following
object MyActor{
def doStuff(id:String){
(myActor ? Message1(id)).map {
}
}
where doStuff method will be called by a caller which has no knowledge of actors etc. now doStuff needs "myActor" reference in there. since object MyActor has no actor context or anything what's the way to access "myActor" actor in there?
EDIT Initialization of MyActor happens upon application startup, by a totally different Global Object, as follow.
val system = ActorSystem("MyActorSystem")
//create all first level actors here
system.actorOf(Props[MyActor], "MyActor")
Upvotes: 0
Views: 1590
Reputation: 35463
If you really want to create your myActor
elsewhere and then be able to use it in this companion, then you could try something like this:
object MyActor {
def doStuff(id:String)(implicit sys:ActorSystem) = {
(sys.actorSelection("/user/MyActor") ? Message1(id)).map {}
}
}
By making the context an input (and it doesn't have to be an implicit, could be explicit too) different pieces of code pass it in/make it available in different ways. For example, in another actor, you already have the actor system available via context.system
but if you are outside of an actor, then you will probably have needed to make the actor system itself available on some sort of global object and then imported into scope.
Upvotes: 1
Reputation:
The thing is that, even though it is defined in the companion object of MyActor
, doStuff
can't access the reference (ActorRef
) to the instantiated actor without explicitly importing the ActorRef
myActor
.
I think it would be better to write the MyActor object as follows:
object MyActor {
val myActor = system.actorOf(Props[MyActor], "MyActor")
def doStuff(id:String) = {
(myActor ? Message1(id)).map {}
}
}
Import this object in your Global
object so that the creation of myActor
would be done as soon as the Global
object is used.
Upvotes: 0
Reputation: 6862
It sounds like you want to treat the fact that you are using an actor as an implementation detail of whatever service the companion object exposes, but you want to centralize the creation of actors (presumably to give them a supervisor). One option would be for the companion object to look up the actor.
Another would be to have the creation of the actor hidden in the companion object. The global object that creates the actors could, rather than creating MyActor directly, call an init method on the companion object with an ActorSystem argument; MyObject could save the ActorRef for later use. You'd have to make the variable @volatile
in that case.
Upvotes: 1