scala.actors.remote.RemoteActor.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-actors Show documentation
Show all versions of scala-actors Show documentation
Deprecated Actors Library for Scala
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.actors
package remote
/**
* This object provides methods for creating, registering, and
* selecting remotely accessible actors.
*
* A remote actor is typically created like this:
* {{{
* actor {
* alive(9010)
* register('myName, self)
*
* // behavior
* }
* }}}
* It can be accessed by an actor running on a (possibly)
* different node by selecting it in the following way:
* {{{
* actor {
* // ...
* val c = select(Node("127.0.0.1", 9010), 'myName)
* c ! msg
* // ...
* }
* }}}
*
* @author Philipp Haller
*/
object RemoteActor {
private val kernels = new scala.collection.mutable.HashMap[Actor, NetKernel]
/* If set to null
(default), the default class loader
* of java.io.ObjectInputStream
is used for deserializing
* objects sent as messages.
*/
private var cl: ClassLoader = null
def classLoader: ClassLoader = cl
def classLoader_=(x: ClassLoader) { cl = x }
/**
* Makes self
remotely accessible on TCP port
* port
.
*/
def alive(port: Int): Unit = synchronized {
createNetKernelOnPort(port)
}
private def createNetKernelOnPort(port: Int): NetKernel = {
val serv = TcpService(port, cl)
val kern = serv.kernel
val s = Actor.self
kernels += Pair(s, kern)
s.onTerminate {
Debug.info("alive actor "+s+" terminated")
// remove mapping for `s`
kernels -= s
// terminate `kern` when it does
// not appear as value any more
if (!kernels.valuesIterator.contains(kern)) {
Debug.info("terminating "+kern)
// terminate NetKernel
kern.terminate()
}
}
kern
}
/**
* Registers a
under name
on this
* node.
*/
def register(name: Symbol, a: Actor): Unit = synchronized {
val kernel = kernels.get(Actor.self) match {
case None =>
val serv = TcpService(TcpService.generatePort, cl)
kernels += Pair(Actor.self, serv.kernel)
serv.kernel
case Some(k) =>
k
}
kernel.register(name, a)
}
private def selfKernel = kernels.get(Actor.self) match {
case None =>
// establish remotely accessible
// return path (sender)
createNetKernelOnPort(TcpService.generatePort)
case Some(k) =>
k
}
/**
* Returns (a proxy for) the actor registered under
* name
on node
.
*/
def select(node: Node, sym: Symbol): AbstractActor = synchronized {
selfKernel.getOrCreateProxy(node, sym)
}
private[remote] def someNetKernel: NetKernel =
kernels.valuesIterator.next
}
/**
* This class represents a machine node on a TCP network.
*
* @param address the host name, or null
for the loopback address.
* @param port the port number.
*
* @author Philipp Haller
*/
case class Node(address: String, port: Int)