Added option to specify class loader when deserializing RemoteActorRef

This commit is contained in:
Jonas Bonér 2010-05-25 16:11:18 +02:00
parent dbbad4633e
commit 06bff765c7
3 changed files with 44 additions and 18 deletions

View file

@ -51,18 +51,22 @@ object ActorRef {
* Deserializes the ActorRef instance from a byte array (Array[Byte]) into an ActorRef instance. * Deserializes the ActorRef instance from a byte array (Array[Byte]) into an ActorRef instance.
*/ */
def fromBinary(bytes: Array[Byte]): ActorRef = def fromBinary(bytes: Array[Byte]): ActorRef =
fromProtocol(ActorRefProtocol.newBuilder.mergeFrom(bytes).build) fromProtocol(ActorRefProtocol.newBuilder.mergeFrom(bytes).build, None)
def fromBinary(bytes: Array[Byte], loader: ClassLoader): ActorRef =
fromProtocol(ActorRefProtocol.newBuilder.mergeFrom(bytes).build, Some(loader))
/** /**
* Deserializes the ActorRef instance from a Protocol Buffers (protobuf) Message into an ActorRef instance. * Deserializes the ActorRef instance from a Protocol Buffers (protobuf) Message into an ActorRef instance.
*/ */
private[akka] def fromProtocol(protocol: ActorRefProtocol): ActorRef = private[akka] def fromProtocol(protocol: ActorRefProtocol, loader: Option[ClassLoader]): ActorRef =
RemoteActorRef( RemoteActorRef(
protocol.getUuid, protocol.getUuid,
protocol.getActorClassName, protocol.getActorClassName,
protocol.getSourceHostname, protocol.getSourceHostname,
protocol.getSourcePort, protocol.getSourcePort,
protocol.getTimeout) protocol.getTimeout,
loader)
} }
/** /**
@ -1217,13 +1221,13 @@ sealed class LocalActorRef private[akka](
*/ */
private[akka] case class RemoteActorRef private[akka] ( private[akka] case class RemoteActorRef private[akka] (
// uuid: String, className: String, hostname: String, port: Int, timeOut: Long, isOnRemoteHost: Boolean) extends ActorRef { // uuid: String, className: String, hostname: String, port: Int, timeOut: Long, isOnRemoteHost: Boolean) extends ActorRef {
uuuid: String, val className: String, val hostname: String, val port: Int, _timeout: Long) uuuid: String, val className: String, val hostname: String, val port: Int, _timeout: Long, loader: Option[ClassLoader])
extends ActorRef { extends ActorRef {
_uuid = uuuid _uuid = uuuid
timeout = _timeout timeout = _timeout
start start
lazy val remoteClient = RemoteClient.clientFor(hostname, port) lazy val remoteClient = RemoteClient.clientFor(hostname, port, loader)
def postMessageToMailbox(message: Any, senderOption: Option[ActorRef]): Unit = { def postMessageToMailbox(message: Any, senderOption: Option[ActorRef]): Unit = {
val requestBuilder = RemoteRequestProtocol.newBuilder val requestBuilder = RemoteRequestProtocol.newBuilder

View file

@ -56,26 +56,48 @@ object RemoteClient extends Logging {
// FIXME: simplify overloaded methods when we have Scala 2.8 // FIXME: simplify overloaded methods when we have Scala 2.8
def actorFor(className: String, hostname: String, port: Int): ActorRef = def actorFor(className: String, hostname: String, port: Int): ActorRef =
actorFor(className, className, 5000L, hostname, port) actorFor(className, className, 5000L, hostname, port, None)
def actorFor(actorRef: String, className: String, hostname: String, port: Int): ActorRef = def actorFor(className: String, hostname: String, port: Int, loader: ClassLoader): ActorRef =
actorFor(actorRef, className, 5000L, hostname, port) actorFor(className, className, 5000L, hostname, port, Some(loader))
def actorFor(uuid: String, className: String, hostname: String, port: Int): ActorRef =
actorFor(uuid, className, 5000L, hostname, port, None)
def actorFor(uuid: String, className: String, hostname: String, port: Int, loader: ClassLoader): ActorRef =
actorFor(uuid, className, 5000L, hostname, port, Some(loader))
def actorFor(className: String, timeout: Long, hostname: String, port: Int): ActorRef = def actorFor(className: String, timeout: Long, hostname: String, port: Int): ActorRef =
actorFor(className, className, timeout, hostname, port) actorFor(className, className, timeout, hostname, port, None)
def actorFor(actorRef: String, className: String, timeout: Long, hostname: String, port: Int): ActorRef = def actorFor(className: String, timeout: Long, hostname: String, port: Int, loader: ClassLoader): ActorRef =
RemoteActorRef(actorRef, className, hostname, port, timeout) actorFor(className, className, timeout, hostname, port, Some(loader))
def clientFor(hostname: String, port: Int): RemoteClient = clientFor(new InetSocketAddress(hostname, port), None) def actorFor(uuid: String, className: String, timeout: Long, hostname: String, port: Int): ActorRef =
RemoteActorRef(uuid, className, hostname, port, timeout, None)
def clientFor(hostname: String, port: Int, loader: ClassLoader): RemoteClient = clientFor(new InetSocketAddress(hostname, port), Some(loader)) private[akka] def actorFor(uuid: String, className: String, timeout: Long, hostname: String, port: Int, loader: ClassLoader): ActorRef =
RemoteActorRef(uuid, className, hostname, port, timeout, Some(loader))
def clientFor(address: InetSocketAddress): RemoteClient = clientFor(address, None) private[akka] def actorFor(uuid: String, className: String, timeout: Long, hostname: String, port: Int, loader: Option[ClassLoader]): ActorRef =
RemoteActorRef(uuid, className, hostname, port, timeout, loader)
def clientFor(address: InetSocketAddress, loader: ClassLoader): RemoteClient = clientFor(address, Some(loader)) def clientFor(hostname: String, port: Int): RemoteClient =
clientFor(new InetSocketAddress(hostname, port), None)
private def clientFor(address: InetSocketAddress, loader: Option[ClassLoader]): RemoteClient = synchronized { def clientFor(hostname: String, port: Int, loader: ClassLoader): RemoteClient =
clientFor(new InetSocketAddress(hostname, port), Some(loader))
def clientFor(address: InetSocketAddress): RemoteClient =
clientFor(address, None)
def clientFor(address: InetSocketAddress, loader: ClassLoader): RemoteClient =
clientFor(address, Some(loader))
private[akka] def clientFor(hostname: String, port: Int, loader: Option[ClassLoader]): RemoteClient =
clientFor(new InetSocketAddress(hostname, port), loader)
private[akka] def clientFor(address: InetSocketAddress, loader: Option[ClassLoader]): RemoteClient = synchronized {
val hostname = address.getHostName val hostname = address.getHostName
val port = address.getPort val port = address.getPort
val hash = hostname + ':' + port val hash = hostname + ':' + port

View file

@ -366,7 +366,7 @@ class RemoteServerHandler(
val message = RemoteProtocolBuilder.getMessage(request) val message = RemoteProtocolBuilder.getMessage(request)
if (request.hasSender) { if (request.hasSender) {
val sender = request.getSender val sender = request.getSender
if (sender ne null) actorRef.!(message)(Some(ActorRef.fromProtocol(sender))) if (sender ne null) actorRef.!(message)(Some(ActorRef.fromProtocol(sender, applicationLoader)))
} else { } else {
try { try {
val resultOrNone = actorRef !! message val resultOrNone = actorRef !! message