/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2005-2013, 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 */ @deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0") object RemoteActor { private val kernels = new scala.collection.mutable.HashMap[InternalActor, 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(Scheduler) kernels(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(Scheduler)) match { case None => val serv = TcpService(TcpService.generatePort, cl) kernels(Actor.self(Scheduler)) = serv.kernel serv.kernel case Some(k) => k } kernel.register(name, a) } private def selfKernel = kernels.get(Actor.self(Scheduler)) 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 */ @deprecated("Use the akka.actor package instead. For migration from the scala.actors package refer to the Actors Migration Guide.", "2.11.0") case class Node(address: String, port: Int)