9

is it possible in Akka (scala) to get a reference to an existing ActorSystem?

I am working on a Spray application with another Actor for DB. I am also extending Directives to have an object per path. the directives are not actors by themselves, but they need to pass messages to the DBActor. here:

class HttpActor extends Actor with HttpService {

  val actorRefFactory = context

  def receive = runRoute(
    IndexService.route ~ 
    HostsService.route    
  )
}

object HostsService extends Directives{
  def route(implicit dm: DetachMagnet2) = {
    path("hosts") {
      get {  
        detach() {
          **dbActor ! CreateHost** 
          complete("get me hosts!")
        }
      } ~
      post {
        detach() {
          entity(as[String]) { payload =>
            complete(s"post hosts $payload")     
          }
        }
      }
    }
  }
}

is there a way for HostsService to discover the ActorSystem itself so he can find the DBActor, or must HttpActor pass it in? the latter seems less elegant, as it HostsService will need to become a class (not an object), so no longer a singleton.

Ehud Kaldor
  • 706
  • 1
  • 6
  • 19

1 Answers1

5

From here:

there was a ticket for creating such a registry, but we were not satisfied with what we got when trying to specify the semantics in detail. One part is that we removed all global state so that different parts of an application can use Akka without having to worry about each other and a global feature would break this. Another is that it would encourage get-or-create usage—my pet peeve—which would make the semantics unclear: you give a name and a config, but if the name already exists you potentially get back a differently configured system (which is usually quite fatal).

There is nothing stopping you from putting a hashmap in some central place of your application, (pre-)populate that with the actor systems you need and be done, that's basically a one-liner (which is another reason for not including it in Akka, because instead of a simple solution to a very narrow problem we'd have to think of a solution to a much more generic problem)

In your case, it's better to pass your system implicitly to the route function:

class HttpActor extends Actor with HttpService {

  implicit val actorRefFactory = context

  def receive = runRoute(
    IndexService.route ~ 
    HostsService.route    
  )
}

object HostsService extends Directives {
  def route(implicit dm: DetachMagnet2, as: ActorContext) = {...}
}
dk14
  • 21,273
  • 4
  • 45
  • 81
  • that did it, and good enough for me. now i need to get to my next problem, which is why all paths seem to be called on re-start, but when i call on addresses, all i get is the listener thread saying it is dispatching GET request to a handler that looks like a system actor (.../system/IO-TCP/selectors/...), and nothing else happens... – Ehud Kaldor Feb 09 '15 at 07:43