- every actor is now supervised, where the root of the tree is app.guardian, which has its supervisor field set to a special ActorRef obtained from provider.theOneWhoWalksTheBubblesOfSpaceTime (this name is meant to indicate that this ref is outside of the universe, cf. Michio Kaku) - changed all tests to obtain specially supervised children (i.e. not top-level) via (supervisor ? Props).as[ActorRef].get - add private[akka] ScalaActorRef.sendSystemMessage for sending Supervise() - everything routing or remote is broken wrt. supervision, as that was not “properly” implemented to begin with, will be tackled after app/supervision/eventbus/AkkaSpec are stabilized enough
83 lines
2.5 KiB
Scala
83 lines
2.5 KiB
Scala
/**
|
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
|
*/
|
|
|
|
package akka.remote
|
|
|
|
import akka.dispatch.PinnedDispatcher
|
|
import scala.collection.mutable
|
|
import java.net.InetSocketAddress
|
|
import akka.actor.{ LocalActorRef, Actor, ActorRef, Props, newUuid }
|
|
import akka.actor.Actor._
|
|
import akka.AkkaApplication
|
|
|
|
/**
|
|
* Stream of all kinds of network events, remote failure and connection events, cluster failure and connection events etc.
|
|
* Also provides API for channel listener management.
|
|
*
|
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
|
*/
|
|
object NetworkEventStream {
|
|
|
|
private sealed trait NetworkEventStreamEvent
|
|
|
|
private case class Register(listener: Listener, connectionAddress: InetSocketAddress)
|
|
extends NetworkEventStreamEvent
|
|
|
|
private case class Unregister(listener: Listener, connectionAddress: InetSocketAddress)
|
|
extends NetworkEventStreamEvent
|
|
|
|
/**
|
|
* Base trait for network event listener.
|
|
*/
|
|
trait Listener {
|
|
def notify(event: RemoteLifeCycleEvent)
|
|
}
|
|
|
|
/**
|
|
* Channel actor with a registry of listeners.
|
|
*/
|
|
private class Channel extends Actor {
|
|
|
|
val listeners = new mutable.HashMap[InetSocketAddress, mutable.Set[Listener]]() {
|
|
override def default(k: InetSocketAddress) = mutable.Set.empty[Listener]
|
|
}
|
|
|
|
def receive = {
|
|
case event: RemoteClientLifeCycleEvent ⇒
|
|
listeners(event.remoteAddress) foreach (_ notify event)
|
|
|
|
case event: RemoteServerLifeCycleEvent ⇒ // FIXME handle RemoteServerLifeCycleEvent
|
|
|
|
case Register(listener, connectionAddress) ⇒
|
|
listeners(connectionAddress) += listener
|
|
|
|
case Unregister(listener, connectionAddress) ⇒
|
|
listeners(connectionAddress) -= listener
|
|
|
|
case _ ⇒ //ignore other
|
|
}
|
|
}
|
|
}
|
|
|
|
class NetworkEventStream(val app: AkkaApplication) {
|
|
|
|
import NetworkEventStream._
|
|
|
|
// FIXME: check that this supervision is correct
|
|
private[akka] val channel = app.provider.actorOf(
|
|
Props[Channel].copy(dispatcher = app.dispatcherFactory.newPinnedDispatcher("NetworkEventStream")),
|
|
app.guardian, Props.randomAddress, systemService = true)
|
|
|
|
/**
|
|
* Registers a network event stream listener (asyncronously).
|
|
*/
|
|
def register(listener: Listener, connectionAddress: InetSocketAddress) =
|
|
channel ! Register(listener, connectionAddress)
|
|
|
|
/**
|
|
* Unregisters a network event stream listener (asyncronously) .
|
|
*/
|
|
def unregister(listener: Listener, connectionAddress: InetSocketAddress) =
|
|
channel ! Unregister(listener, connectionAddress)
|
|
}
|