Added interface for registering session actors, and adding unit test (which is failing now)
This commit is contained in:
parent
5dff29642d
commit
67cf3788f3
3 changed files with 82 additions and 0 deletions
|
|
@ -301,12 +301,14 @@ object ActorRegistry extends ListenerManagement {
|
||||||
|
|
||||||
private[akka] def actors(address: Address) = actorsFor(address).actors
|
private[akka] def actors(address: Address) = actorsFor(address).actors
|
||||||
private[akka] def actorsByUuid(address: Address) = actorsFor(address).actorsByUuid
|
private[akka] def actorsByUuid(address: Address) = actorsFor(address).actorsByUuid
|
||||||
|
private[akka] def actorsFactories(address: Address) = actorsFor(address).actorsFactories
|
||||||
private[akka] def typedActors(address: Address) = actorsFor(address).typedActors
|
private[akka] def typedActors(address: Address) = actorsFor(address).typedActors
|
||||||
private[akka] def typedActorsByUuid(address: Address) = actorsFor(address).typedActorsByUuid
|
private[akka] def typedActorsByUuid(address: Address) = actorsFor(address).typedActorsByUuid
|
||||||
|
|
||||||
private[akka] class RemoteActorSet {
|
private[akka] class RemoteActorSet {
|
||||||
private[ActorRegistry] val actors = new ConcurrentHashMap[String, ActorRef]
|
private[ActorRegistry] val actors = new ConcurrentHashMap[String, ActorRef]
|
||||||
private[ActorRegistry] val actorsByUuid = new ConcurrentHashMap[String, ActorRef]
|
private[ActorRegistry] val actorsByUuid = new ConcurrentHashMap[String, ActorRef]
|
||||||
|
private[ActorRegistry] val actorsFactories = new ConcurrentHashMap[String, () => ActorRef]
|
||||||
private[ActorRegistry] val typedActors = new ConcurrentHashMap[String, AnyRef]
|
private[ActorRegistry] val typedActors = new ConcurrentHashMap[String, AnyRef]
|
||||||
private[ActorRegistry] val typedActorsByUuid = new ConcurrentHashMap[String, AnyRef]
|
private[ActorRegistry] val typedActorsByUuid = new ConcurrentHashMap[String, AnyRef]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,17 @@ class RemoteServer extends Logging with ListenerManagement {
|
||||||
else register(id, actorRef, actors)
|
else register(id, actorRef, actors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Remote Session Actor by a specific 'id' passed as argument.
|
||||||
|
* <p/>
|
||||||
|
* NOTE: If you use this method to register your remote actor then you must unregister the actor by this ID yourself.
|
||||||
|
*/
|
||||||
|
def registerPerSession(id: String, factory: => ActorRef): Unit = synchronized {
|
||||||
|
log.debug("Registering server side remote session actor with id [%s]", id)
|
||||||
|
if (id.startsWith(UUID_PREFIX)) register(id.substring(UUID_PREFIX.length), factory, actorsByUuid)
|
||||||
|
else registerPerSession(id, () => factory, actorsFactories)
|
||||||
|
}
|
||||||
|
|
||||||
private def register[Key](id: Key, actorRef: ActorRef, registry: ConcurrentHashMap[Key, ActorRef]) {
|
private def register[Key](id: Key, actorRef: ActorRef, registry: ConcurrentHashMap[Key, ActorRef]) {
|
||||||
if (_isRunning && !registry.contains(id)) {
|
if (_isRunning && !registry.contains(id)) {
|
||||||
if (!actorRef.isRunning) actorRef.start
|
if (!actorRef.isRunning) actorRef.start
|
||||||
|
|
@ -309,6 +320,12 @@ class RemoteServer extends Logging with ListenerManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def registerPerSession[Key](id: Key, factory: () => ActorRef, registry: ConcurrentHashMap[Key,() => ActorRef]) {
|
||||||
|
if (_isRunning && !registry.contains(id)) {
|
||||||
|
registry.put(id, factory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def registerTypedActor[Key](id: Key, typedActor: AnyRef, registry: ConcurrentHashMap[Key, AnyRef]) {
|
private def registerTypedActor[Key](id: Key, typedActor: AnyRef, registry: ConcurrentHashMap[Key, AnyRef]) {
|
||||||
if (_isRunning && !registry.contains(id)) registry.put(id, typedActor)
|
if (_isRunning && !registry.contains(id)) registry.put(id, typedActor)
|
||||||
}
|
}
|
||||||
|
|
@ -341,6 +358,18 @@ class RemoteServer extends Logging with ListenerManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister Remote Actor by specific 'id'.
|
||||||
|
* <p/>
|
||||||
|
* NOTE: You need to call this method if you have registered an actor by a custom ID.
|
||||||
|
*/
|
||||||
|
def unregisterPerSession(id: String):Unit = synchronized {
|
||||||
|
if (_isRunning) {
|
||||||
|
log.info("Unregistering server side remote session actor with id [%s]", id)
|
||||||
|
actorsFactories.remove(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister Remote Typed Actor by specific 'id'.
|
* Unregister Remote Typed Actor by specific 'id'.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|
@ -358,8 +387,10 @@ class RemoteServer extends Logging with ListenerManagement {
|
||||||
|
|
||||||
protected[akka] override def notifyListeners(message: => Any): Unit = super.notifyListeners(message)
|
protected[akka] override def notifyListeners(message: => Any): Unit = super.notifyListeners(message)
|
||||||
|
|
||||||
|
|
||||||
private[akka] def actors = ActorRegistry.actors(address)
|
private[akka] def actors = ActorRegistry.actors(address)
|
||||||
private[akka] def actorsByUuid = ActorRegistry.actorsByUuid(address)
|
private[akka] def actorsByUuid = ActorRegistry.actorsByUuid(address)
|
||||||
|
private[akka] def actorsFactories = ActorRegistry.actorsFactories(address)
|
||||||
private[akka] def typedActors = ActorRegistry.typedActors(address)
|
private[akka] def typedActors = ActorRegistry.typedActors(address)
|
||||||
private[akka] def typedActorsByUuid = ActorRegistry.typedActorsByUuid(address)
|
private[akka] def typedActorsByUuid = ActorRegistry.typedActorsByUuid(address)
|
||||||
}
|
}
|
||||||
|
|
@ -429,6 +460,8 @@ class RemoteServerHandler(
|
||||||
val AW_PROXY_PREFIX = "$$ProxiedByAW".intern
|
val AW_PROXY_PREFIX = "$$ProxiedByAW".intern
|
||||||
val CHANNEL_INIT = "channel-init".intern
|
val CHANNEL_INIT = "channel-init".intern
|
||||||
|
|
||||||
|
val sessionActors = new ChannelLocal();
|
||||||
|
|
||||||
applicationLoader.foreach(MessageSerializer.setClassLoader(_))
|
applicationLoader.foreach(MessageSerializer.setClassLoader(_))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,22 @@ object ServerInitiatedRemoteActorSpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class Login(user:String);
|
||||||
|
case class GetUser();
|
||||||
|
|
||||||
|
class RemoteStatefullSessionActorSpec extends Actor {
|
||||||
|
|
||||||
|
var user : String= _;
|
||||||
|
|
||||||
|
def receive = {
|
||||||
|
case Login(user) =>
|
||||||
|
this.user = user;
|
||||||
|
case GetUser() =>
|
||||||
|
self.reply(this.user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
object RemoteActorSpecActorAsyncSender {
|
object RemoteActorSpecActorAsyncSender {
|
||||||
val latch = new CountDownLatch(1)
|
val latch = new CountDownLatch(1)
|
||||||
}
|
}
|
||||||
|
|
@ -63,6 +79,7 @@ class ServerInitiatedRemoteActorSpec extends JUnitSuite {
|
||||||
server.register(actorOf[RemoteActorSpecActorUnidirectional])
|
server.register(actorOf[RemoteActorSpecActorUnidirectional])
|
||||||
server.register(actorOf[RemoteActorSpecActorBidirectional])
|
server.register(actorOf[RemoteActorSpecActorBidirectional])
|
||||||
server.register(actorOf[RemoteActorSpecActorAsyncSender])
|
server.register(actorOf[RemoteActorSpecActorAsyncSender])
|
||||||
|
server.registerPerSession("statefull-session-actor", actorOf[RemoteStatefullSessionActorSpec])
|
||||||
|
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
}
|
}
|
||||||
|
|
@ -103,6 +120,29 @@ class ServerInitiatedRemoteActorSpec extends JUnitSuite {
|
||||||
actor.stop
|
actor.stop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
def shouldKeepSessionInformation {
|
||||||
|
val session1 = RemoteClient.actorFor(
|
||||||
|
"statefull-session-actor",
|
||||||
|
5000L,
|
||||||
|
HOSTNAME, PORT)
|
||||||
|
val session2 = RemoteClient.actorFor(
|
||||||
|
"statefull-session-actor",
|
||||||
|
5000L,
|
||||||
|
HOSTNAME, PORT)
|
||||||
|
|
||||||
|
session1 ! Login("session1");
|
||||||
|
session2 ! Login("session2");
|
||||||
|
|
||||||
|
val result1 = session1 !! GetUser();
|
||||||
|
assert("session1" === result1.get.asInstanceOf[String])
|
||||||
|
val result2 = session2 !! GetUser();
|
||||||
|
assert("session2" === result2.get.asInstanceOf[String])
|
||||||
|
|
||||||
|
session1.stop()
|
||||||
|
session2.stop()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
def shouldSendWithBangAndGetReplyThroughSenderRef {
|
def shouldSendWithBangAndGetReplyThroughSenderRef {
|
||||||
implicit val timeout = 500000000L
|
implicit val timeout = 500000000L
|
||||||
|
|
@ -205,6 +245,13 @@ class ServerInitiatedRemoteActorSpec extends JUnitSuite {
|
||||||
server.unregister("my-service-1")
|
server.unregister("my-service-1")
|
||||||
assert(server.actors.get("my-service-1") eq null, "actor unregistered")
|
assert(server.actors.get("my-service-1") eq null, "actor unregistered")
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
def shouldRegisterAndUnregisterSession {
|
||||||
|
server.registerPerSession("my-service-1", actorOf[RemoteActorSpecActorUnidirectional])
|
||||||
|
assert(server.actorsFactories.get("my-service-1") ne null, "actor registered")
|
||||||
|
server.unregisterPerSession("my-service-1")
|
||||||
|
assert(server.actorsFactories.get("my-service-1") eq null, "actor unregistered")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
def shouldRegisterAndUnregisterByUuid {
|
def shouldRegisterAndUnregisterByUuid {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue