diff options
Diffstat (limited to 'test/files/presentation/akka/src')
55 files changed, 0 insertions, 10729 deletions
diff --git a/test/files/presentation/akka/src/akka/AkkaException.scala b/test/files/presentation/akka/src/akka/AkkaException.scala deleted file mode 100644 index 155a7a16b5..0000000000 --- a/test/files/presentation/akka/src/akka/AkkaException.scala +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka - -import akka.actor.newUuid -import java.net.{ InetAddress, UnknownHostException } - -/** - * Akka base Exception. Each Exception gets: - * <ul> - * <li>a uuid for tracking purposes</li> - * <li>toString that includes exception name, message, uuid, and the stacktrace</li> - * </ul> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class AkkaException(message: String = "", cause: Throwable = null) extends RuntimeException(message, cause) with Serializable { - val uuid = "%s_%s".format(AkkaException.hostname, newUuid) - - override lazy val toString = - "%s: %s\n[%s]\n%s".format(getClass.getName, message, uuid, stackTraceToString) - - def stackTraceToString = { - val trace = getStackTrace - val sb = new StringBuffer - for (i ← 0 until trace.length) - sb.append("\tat %s\n" format trace(i)) - sb.toString - } -} - -object AkkaException { - val hostname = try { - InetAddress.getLocalHost.getHostName - } catch { - case e: UnknownHostException => "unknown" - } -} diff --git a/test/files/presentation/akka/src/akka/actor/Actor.scala b/test/files/presentation/akka/src/akka/actor/Actor.scala deleted file mode 100644 index b955c4c38b..0000000000 --- a/test/files/presentation/akka/src/akka/actor/Actor.scala +++ /dev/null @@ -1,503 +0,0 @@ -/** Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import akka.dispatch._ -import akka.config.Config._ -import akka.util.Helpers.{ narrow, narrowSilently } -import akka.util.ListenerManagement -import akka.AkkaException - -import scala.beans.BeanProperty -import akka.util.{ ReflectiveAccess, Duration } -import akka.remoteinterface.RemoteSupport -import akka.japi.{ Creator, Procedure } -import java.lang.reflect.InvocationTargetException - -/** Life-cycle messages for the Actors - */ -sealed trait LifeCycleMessage extends Serializable - -/* Marker trait to show which Messages are automatically handled by Akka */ -sealed trait AutoReceivedMessage { self: LifeCycleMessage => } - -case class HotSwap(code: ActorRef => Actor.Receive, discardOld: Boolean = true) - extends AutoReceivedMessage with LifeCycleMessage { - - /** Java API - */ - def this(code: akka.japi.Function[ActorRef, Procedure[Any]], discardOld: Boolean) = - this((self: ActorRef) => { - val behavior = code(self) - val result: Actor.Receive = { case msg => behavior(msg) } - result - }, discardOld) - - /** Java API with default non-stacking behavior - */ - def this(code: akka.japi.Function[ActorRef, Procedure[Any]]) = this(code, true) -} - -case object RevertHotSwap extends AutoReceivedMessage with LifeCycleMessage - -case class Restart(reason: Throwable) extends AutoReceivedMessage with LifeCycleMessage - -case class Exit(dead: ActorRef, killer: Throwable) extends AutoReceivedMessage with LifeCycleMessage - -case class Link(child: ActorRef) extends AutoReceivedMessage with LifeCycleMessage - -case class Unlink(child: ActorRef) extends AutoReceivedMessage with LifeCycleMessage - -case class UnlinkAndStop(child: ActorRef) extends AutoReceivedMessage with LifeCycleMessage - -case object PoisonPill extends AutoReceivedMessage with LifeCycleMessage - -case object Kill extends AutoReceivedMessage with LifeCycleMessage - -case object ReceiveTimeout extends LifeCycleMessage - -case class MaximumNumberOfRestartsWithinTimeRangeReached( - @BeanProperty val victim: ActorRef, - @BeanProperty val maxNrOfRetries: Option[Int], - @BeanProperty val withinTimeRange: Option[Int], - @BeanProperty val lastExceptionCausingRestart: Throwable) extends LifeCycleMessage - -// Exceptions for Actors -class ActorStartException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) -class IllegalActorStateException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) -class ActorKilledException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) -class ActorInitializationException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) -class ActorTimeoutException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) -class InvalidMessageException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) - -/** This message is thrown by default when an Actors behavior doesn't match a message - */ -case class UnhandledMessageException(msg: Any, ref: ActorRef) extends Exception { - override def getMessage() = "Actor %s does not handle [%s]".format(ref, msg) - override def fillInStackTrace() = this //Don't waste cycles generating stack trace -} - -/** Actor factory module with factory methods for creating various kinds of Actors. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Actor extends ListenerManagement { - - /** Add shutdown cleanups - */ - private[akka] lazy val shutdownHook = { - val hook = new Runnable { - override def run { - // Clear Thread.subclassAudits - val tf = classOf[java.lang.Thread].getDeclaredField("subclassAudits") - tf.setAccessible(true) - val subclassAudits = tf.get(null).asInstanceOf[java.util.Map[_, _]] - subclassAudits synchronized { subclassAudits.clear } - } - } - Runtime.getRuntime.addShutdownHook(new Thread(hook)) - hook - } - - val registry = new ActorRegistry - - lazy val remote: RemoteSupport = { - ReflectiveAccess - .Remote - .defaultRemoteSupport - .map(_()) - .getOrElse(throw new UnsupportedOperationException("You need to have akka-remote.jar on classpath")) - } - - private[akka] val TIMEOUT = Duration(config.getInt("akka.actor.timeout", 5), TIME_UNIT).toMillis - private[akka] val SERIALIZE_MESSAGES = config.getBool("akka.actor.serialize-messages", false) - - /** A Receive is a convenience type that defines actor message behavior currently modeled as - * a PartialFunction[Any, Unit]. - */ - type Receive = PartialFunction[Any, Unit] - - private[actor] val actorRefInCreation = new ThreadLocal[Option[ActorRef]] { - override def initialValue = None - } - - /** Creates an ActorRef out of the Actor with type T. - * <pre> - * import Actor._ - * val actor = actorOf[MyActor] - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf[MyActor].start() - * </pre> - */ - def actorOf[T <: Actor: Manifest]: ActorRef = actorOf(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]]) - - /** Creates an ActorRef out of the Actor of the specified Class. - * <pre> - * import Actor._ - * val actor = actorOf(classOf[MyActor]) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf(classOf[MyActor]).start() - * </pre> - */ - def actorOf(clazz: Class[_ <: Actor]): ActorRef = new LocalActorRef(() => { - import ReflectiveAccess.{ createInstance, noParams, noArgs } - createInstance[Actor](clazz.asInstanceOf[Class[_]], noParams, noArgs) match { - case Right(actor) => actor - case Left(exception) => - val cause = exception match { - case i: InvocationTargetException => i.getTargetException - case _ => exception - } - - throw new ActorInitializationException( - "Could not instantiate Actor of " + clazz + - "\nMake sure Actor is NOT defined inside a class/trait," + - "\nif so put it outside the class/trait, f.e. in a companion object," + - "\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'.", cause) - } - - }, None) - - /** Creates an ActorRef out of the Actor. Allows you to pass in a factory function - * that creates the Actor. Please note that this function can be invoked multiple - * times if for example the Actor is supervised and needs to be restarted. - * <p/> - * This function should <b>NOT</b> be used for remote actors. - * <pre> - * import Actor._ - * val actor = actorOf(new MyActor) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf(new MyActor).start() - * </pre> - */ - def actorOf(factory: => Actor): ActorRef = new LocalActorRef(() => factory, None) - - /** Creates an ActorRef out of the Actor. Allows you to pass in a factory (Creator<Actor>) - * that creates the Actor. Please note that this function can be invoked multiple - * times if for example the Actor is supervised and needs to be restarted. - * <p/> - * This function should <b>NOT</b> be used for remote actors. - * JAVA API - */ - def actorOf(creator: Creator[Actor]): ActorRef = new LocalActorRef(() => creator.create, None) - - /** Use to spawn out a block of code in an event-driven actor. Will shut actor down when - * the block has been executed. - * <p/> - * NOTE: If used from within an Actor then has to be qualified with 'Actor.spawn' since - * there is a method 'spawn[ActorType]' in the Actor trait already. - * Example: - * <pre> - * import Actor.{spawn} - * - * spawn { - * ... // do stuff - * } - * </pre> - */ - def spawn(body: => Unit)(implicit dispatcher: MessageDispatcher = Dispatchers.defaultGlobalDispatcher): Unit = { - case object Spawn - actorOf(new Actor() { - self.dispatcher = dispatcher - def receive = { - case Spawn => try { body } finally { self.stop() } - } - }).start() ! Spawn - } - - /** Implicitly converts the given Option[Any] to a AnyOptionAsTypedOption which offers the method <code>as[T]</code> - * to convert an Option[Any] to an Option[T]. - */ - implicit def toAnyOptionAsTypedOption(anyOption: Option[Any]) = new AnyOptionAsTypedOption(anyOption) - - /** Implicitly converts the given Future[_] to a AnyOptionAsTypedOption which offers the method <code>as[T]</code> - * to convert an Option[Any] to an Option[T]. - * This means that the following code is equivalent: - * (actor !! "foo").as[Int] (Deprecated) - * and - * (actor !!! "foo").as[Int] (Recommended) - */ - implicit def futureToAnyOptionAsTypedOption(anyFuture: Future[_]) = new AnyOptionAsTypedOption({ - try { anyFuture.await } catch { case t: FutureTimeoutException => } - anyFuture.resultOrException - }) -} - -/** Actor base trait that should be extended by or mixed to create an Actor with the semantics of the 'Actor Model': - * <a href="http://en.wikipedia.org/wiki/Actor_model">http://en.wikipedia.org/wiki/Actor_model</a> - * <p/> - * An actor has a well-defined (non-cyclic) life-cycle. - * <pre> - * => NEW (newly created actor) - can't receive messages (yet) - * => STARTED (when 'start' is invoked) - can receive messages - * => SHUT DOWN (when 'exit' is invoked) - can't do anything - * </pre> - * - * <p/> - * The Actor's API is available in the 'self' member variable. - * - * <p/> - * Here you find functions like: - * - !, !!, !!! and forward - * - link, unlink, startLink, spawnLink etc - * - makeRemote etc. - * - start, stop - * - etc. - * - * <p/> - * Here you also find fields like - * - dispatcher = ... - * - id = ... - * - lifeCycle = ... - * - faultHandler = ... - * - trapExit = ... - * - etc. - * - * <p/> - * This means that to use them you have to prefix them with 'self', like this: <tt>self ! Message</tt> - * - * However, for convenience you can import these functions and fields like below, which will allow you do - * drop the 'self' prefix: - * <pre> - * class MyActor extends Actor { - * import self._ - * id = ... - * dispatcher = ... - * spawnLink[OtherActor] - * ... - * } - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait Actor { - - /** Type alias because traits cannot have companion objects. - */ - type Receive = Actor.Receive - - /* - * Some[ActorRef] representation of the 'self' ActorRef reference. - * <p/> - * Mainly for internal use, functions as the implicit sender references when invoking - * the 'forward' function. - */ - @transient - implicit val someSelf: Some[ActorRef] = { - val optRef = Actor.actorRefInCreation.get - if (optRef.isEmpty) throw new ActorInitializationException( - "ActorRef for instance of actor [" + getClass.getName + "] is not in scope." + - "\n\tYou can not create an instance of an actor explicitly using 'new MyActor'." + - "\n\tYou have to use one of the factory methods in the 'Actor' object to create a new actor." + - "\n\tEither use:" + - "\n\t\t'val actor = Actor.actorOf[MyActor]', or" + - "\n\t\t'val actor = Actor.actorOf(new MyActor(..))'") - Actor.actorRefInCreation.set(None) - optRef.asInstanceOf[Some[ActorRef]].get.id = getClass.getName //FIXME: Is this needed? - optRef.asInstanceOf[Some[ActorRef]] - } - - /* - * Option[ActorRef] representation of the 'self' ActorRef reference. - * <p/> - * Mainly for internal use, functions as the implicit sender references when invoking - * one of the message send functions ('!', '!!' and '!!!'). - */ - implicit def optionSelf: Option[ActorRef] = someSelf - - /** The 'self' field holds the ActorRef for this actor. - * <p/> - * Can be used to send messages to itself: - * <pre> - * self ! message - * </pre> - * Here you also find most of the Actor API. - * <p/> - * For example fields like: - * <pre> - * self.dispatcher = ... - * self.trapExit = ... - * self.faultHandler = ... - * self.lifeCycle = ... - * self.sender - * </pre> - * <p/> - * Here you also find methods like: - * <pre> - * self.reply(..) - * self.link(..) - * self.unlink(..) - * self.start(..) - * self.stop(..) - * </pre> - */ - @transient - val self: ScalaActorRef = someSelf.get - - /** User overridable callback/setting. - * <p/> - * Partial function implementing the actor logic. - * To be implemented by concrete actor class. - * <p/> - * Example code: - * <pre> - * def receive = { - * case Ping => - * println("got a 'Ping' message") - * self.reply("pong") - * - * case OneWay => - * println("got a 'OneWay' message") - * - * case unknown => - * println("unknown message: " + unknown) - * } - * </pre> - */ - protected def receive: Receive - - /** User overridable callback. - * <p/> - * Is called when an Actor is started by invoking 'actor.start()'. - */ - def preStart() {} - - /** User overridable callback. - * <p/> - * Is called when 'actor.stop()' is invoked. - */ - def postStop() {} - - /** User overridable callback. - * <p/> - * Is called on a crashed Actor right BEFORE it is restarted to allow clean up of resources before Actor is terminated. - */ - def preRestart(reason: Throwable) {} - - /** User overridable callback. - * <p/> - * Is called right AFTER restart on the newly created Actor to allow reinitialization after an Actor crash. - */ - def postRestart(reason: Throwable) {} - - /** User overridable callback. - * <p/> - * Is called when a message isn't handled by the current behavior of the actor - * by default it throws an UnhandledMessageException - */ - def unhandled(msg: Any) { - throw new UnhandledMessageException(msg, self) - } - - /** Is the actor able to handle the message passed in as arguments? - */ - def isDefinedAt(message: Any): Boolean = { - val behaviorStack = self.hotswap - message match { //Same logic as apply(msg) but without the unhandled catch-all - case l: AutoReceivedMessage => true - case msg if behaviorStack.nonEmpty && - behaviorStack.head.isDefinedAt(msg) => true - case msg if behaviorStack.isEmpty && - processingBehavior.isDefinedAt(msg) => true - case _ => false - } - } - - /** Changes the Actor's behavior to become the new 'Receive' (PartialFunction[Any, Unit]) handler. - * Puts the behavior on top of the hotswap stack. - * If "discardOld" is true, an unbecome will be issued prior to pushing the new behavior to the stack - */ - def become(behavior: Receive, discardOld: Boolean = true) { - if (discardOld) unbecome() - self.hotswap = self.hotswap.push(behavior) - } - - /** Reverts the Actor behavior to the previous one in the hotswap stack. - */ - def unbecome(): Unit = { - val h = self.hotswap - if (h.nonEmpty) self.hotswap = h.pop - } - - // ========================================= - // ==== INTERNAL IMPLEMENTATION DETAILS ==== - // ========================================= - - private[akka] final def apply(msg: Any) = { - if (msg.isInstanceOf[AnyRef] && (msg.asInstanceOf[AnyRef] eq null)) - throw new InvalidMessageException("Message from [" + self.sender + "] to [" + self.toString + "] is null") - val behaviorStack = self.hotswap - msg match { - case l: AutoReceivedMessage => autoReceiveMessage(l) - case msg if behaviorStack.nonEmpty && - behaviorStack.head.isDefinedAt(msg) => behaviorStack.head.apply(msg) - case msg if behaviorStack.isEmpty && - processingBehavior.isDefinedAt(msg) => processingBehavior.apply(msg) - case unknown => unhandled(unknown) //This is the only line that differs from processingbehavior - } - } - - private final def autoReceiveMessage(msg: AutoReceivedMessage): Unit = msg match { - case HotSwap(code, discardOld) => become(code(self), discardOld) - case RevertHotSwap => unbecome() - case Exit(dead, reason) => self.handleTrapExit(dead, reason) - case Link(child) => self.link(child) - case Unlink(child) => self.unlink(child) - case UnlinkAndStop(child) => self.unlink(child); child.stop() - case Restart(reason) => throw reason - case Kill => throw new ActorKilledException("Kill") - case PoisonPill => - val f = self.senderFuture - self.stop() - if (f.isDefined) f.get.completeWithException(new ActorKilledException("PoisonPill")) - } - - private lazy val processingBehavior = receive //ProcessingBehavior is the original behavior -} - -private[actor] class AnyOptionAsTypedOption(anyOption: Option[Any]) { - - /** Convenience helper to cast the given Option of Any to an Option of the given type. Will throw a ClassCastException - * if the actual type is not assignable from the given one. - */ - def as[T]: Option[T] = narrow[T](anyOption) - - /** Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible - * ClassCastException and return None in that case. - */ - def asSilently[T: Manifest]: Option[T] = narrowSilently[T](anyOption) -} - -/** Marker interface for proxyable actors (such as typed actor). - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait Proxyable { - private[actor] def swapProxiedActor(newInstance: Actor) -} - -/** Represents the different Actor types. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -sealed trait ActorType -object ActorType { - case object ScalaActor extends ActorType - case object TypedActor extends ActorType -} diff --git a/test/files/presentation/akka/src/akka/actor/ActorRef.scala b/test/files/presentation/akka/src/akka/actor/ActorRef.scala deleted file mode 100644 index 07fa358744..0000000000 --- a/test/files/presentation/akka/src/akka/actor/ActorRef.scala +++ /dev/null @@ -1,1433 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import akka.event.EventHandler -import akka.dispatch._ -import akka.config.Supervision._ -import akka.util._ -import ReflectiveAccess._ - -import java.net.InetSocketAddress -import java.util.concurrent.atomic.AtomicReference -import java.util.concurrent.{ ScheduledFuture, ConcurrentHashMap, TimeUnit } -import java.util.{ Map => JMap } - -import scala.beans.BeanProperty -import scala.collection.immutable.Stack -import scala.annotation.tailrec - -private[akka] object ActorRefInternals { - - /** - * LifeCycles for ActorRefs. - */ - private[akka] sealed trait StatusType - object UNSTARTED extends StatusType - object RUNNING extends StatusType - object BEING_RESTARTED extends StatusType - object SHUTDOWN extends StatusType -} - -/** - * Abstraction for unification of sender and senderFuture for later reply. - * Can be stored away and used at a later point in time. - */ -abstract class Channel[T] { - - /** - * Scala API. <p/> - * Sends the specified message to the channel. - */ - def !(msg: T): Unit - - /** - * Java API. <p/> - * Sends the specified message to the channel. - */ - def sendOneWay(msg: T): Unit = this.!(msg) -} - -/** - * ActorRef is an immutable and serializable handle to an Actor. - * <p/> - * Create an ActorRef for an Actor by using the factory method on the Actor object. - * <p/> - * Here is an example on how to create an actor with a default constructor. - * <pre> - * import Actor._ - * - * val actor = actorOf[MyActor] - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * - * You can also create and start actors like this: - * <pre> - * val actor = actorOf[MyActor].start() - * </pre> - * - * Here is an example on how to create an actor with a non-default constructor. - * <pre> - * import Actor._ - * - * val actor = actorOf(new MyActor(...)) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait ActorRef extends ActorRefShared with java.lang.Comparable[ActorRef] { scalaRef: ScalaActorRef => - // Only mutable for RemoteServer in order to maintain identity across nodes - @volatile - protected[akka] var _uuid = newUuid - @volatile - protected[this] var _status: ActorRefInternals.StatusType = ActorRefInternals.UNSTARTED - - /** - * User overridable callback/setting. - * <p/> - * Identifier for actor, does not have to be a unique one. Default is the 'uuid'. - * <p/> - * This field is used for logging, AspectRegistry.actorsFor(id), identifier for remote - * actor in RemoteServer etc.But also as the identifier for persistence, which means - * that you can use a custom name to be able to retrieve the "correct" persisted state - * upon restart, remote restart etc. - */ - @BeanProperty - @volatile - var id: String = _uuid.toString - - /** - * User overridable callback/setting. - * <p/> - * Defines the default timeout for '!!' and '!!!' invocations, - * e.g. the timeout for the future returned by the call to '!!' and '!!!'. - */ - @deprecated("Will be replaced by implicit-scoped timeout on all methods that needs it, will default to timeout specified in config", "1.1") - @BeanProperty - @volatile - var timeout: Long = Actor.TIMEOUT - - /** - * User overridable callback/setting. - * <p/> - * Defines the default timeout for an initial receive invocation. - * When specified, the receive function should be able to handle a 'ReceiveTimeout' message. - */ - @volatile - var receiveTimeout: Option[Long] = None - - /** - * Akka Java API. <p/> - * Defines the default timeout for an initial receive invocation. - * When specified, the receive function should be able to handle a 'ReceiveTimeout' message. - */ - def setReceiveTimeout(timeout: Long) = this.receiveTimeout = Some(timeout) - def getReceiveTimeout(): Option[Long] = receiveTimeout - - /** - * Akka Java API. <p/> - * A faultHandler defines what should be done when a linked actor signals an error. - * <p/> - * Can be one of: - * <pre> - * getContext().setFaultHandler(new AllForOneStrategy(new Class[]{Throwable.class},maxNrOfRetries, withinTimeRange)); - * </pre> - * Or: - * <pre> - * getContext().setFaultHandler(new OneForOneStrategy(new Class[]{Throwable.class},maxNrOfRetries, withinTimeRange)); - * </pre> - */ - def setFaultHandler(handler: FaultHandlingStrategy) - def getFaultHandler(): FaultHandlingStrategy - - /** - * Akka Java API. <p/> - * A lifeCycle defines whether the actor will be stopped on error (Temporary) or if it can be restarted (Permanent) - * <p/> - * Can be one of: - * - * import static akka.config.Supervision.*; - * <pre> - * getContext().setLifeCycle(permanent()); - * </pre> - * Or: - * <pre> - * getContext().setLifeCycle(temporary()); - * </pre> - */ - def setLifeCycle(lifeCycle: LifeCycle): Unit - def getLifeCycle(): LifeCycle - - /** - * Akka Java API. <p/> - * The default dispatcher is the <tt>Dispatchers.globalExecutorBasedEventDrivenDispatcher</tt>. - * This means that all actors will share the same event-driven executor based dispatcher. - * <p/> - * You can override it so it fits the specific use-case that the actor is used for. - * See the <tt>akka.dispatch.Dispatchers</tt> class for the different - * dispatchers available. - * <p/> - * The default is also that all actors that are created and spawned from within this actor - * is sharing the same dispatcher as its creator. - */ - def setDispatcher(dispatcher: MessageDispatcher) = this.dispatcher = dispatcher - def getDispatcher(): MessageDispatcher = dispatcher - - /** - * Returns on which node this actor lives if None it lives in the local ActorRegistry - */ - @deprecated("Remoting will become fully transparent in the future", "1.1") - def homeAddress: Option[InetSocketAddress] - - /** - * Java API. <p/> - */ - @deprecated("Remoting will become fully transparent in the future", "1.1") - def getHomeAddress(): InetSocketAddress = homeAddress getOrElse null - - /** - * Holds the hot swapped partial function. - */ - @volatile - protected[akka] var hotswap = Stack[PartialFunction[Any, Unit]]() - - /** - * This is a reference to the message currently being processed by the actor - */ - @volatile - protected[akka] var currentMessage: MessageInvocation = null - - /** - * Comparison only takes uuid into account. - */ - def compareTo(other: ActorRef) = this.uuid compareTo other.uuid - - /** - * Returns the uuid for the actor. - */ - def getUuid() = _uuid - def uuid = _uuid - - /** - * Akka Java API. <p/> - * The reference sender Actor of the last received message. - * Is defined if the message was sent from another Actor, else None. - */ - def getSender(): Option[ActorRef] = sender - - /** - * Akka Java API. <p/> - * The reference sender future of the last received message. - * Is defined if the message was sent with sent with '!!' or '!!!', else None. - */ - def getSenderFuture(): Option[CompletableFuture[Any]] = senderFuture - - /** - * Is the actor being restarted? - */ - def isBeingRestarted: Boolean = _status == ActorRefInternals.BEING_RESTARTED - - /** - * Is the actor running? - */ - def isRunning: Boolean = _status match { - case ActorRefInternals.BEING_RESTARTED | ActorRefInternals.RUNNING => true - case _ => false - } - - /** - * Is the actor shut down? - */ - def isShutdown: Boolean = _status == ActorRefInternals.SHUTDOWN - - /** - * Is the actor ever started? - */ - def isUnstarted: Boolean = _status == ActorRefInternals.UNSTARTED - - /** - * Is the actor able to handle the message passed in as arguments? - */ - @deprecated("Will be removed without replacement, it's just not reliable in the face of `become` and `unbecome`", "1.1") - def isDefinedAt(message: Any): Boolean = actor.isDefinedAt(message) - - /** - * Only for internal use. UUID is effectively final. - */ - protected[akka] def uuid_=(uid: Uuid) = _uuid = uid - - /** - * Akka Java API. <p/> - * Sends a one-way asynchronous message. E.g. fire-and-forget semantics. - * <p/> - * <pre> - * actor.sendOneWay(message); - * </pre> - * <p/> - */ - def sendOneWay(message: AnyRef): Unit = sendOneWay(message, null) - - /** - * Akka Java API. <p/> - * Sends a one-way asynchronous message. E.g. fire-and-forget semantics. - * <p/> - * Allows you to pass along the sender of the message. - * <p/> - * <pre> - * actor.sendOneWay(message, context); - * </pre> - * <p/> - */ - def sendOneWay(message: AnyRef, sender: ActorRef): Unit = this.!(message)(Option(sender)) - - /** - * Akka Java API. <p/> - * @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef) - * Uses the default timeout of the Actor (setTimeout()) and omits the sender reference - */ - def sendRequestReply(message: AnyRef): AnyRef = sendRequestReply(message, timeout, null) - - /** - * Akka Java API. <p/> - * @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef) - * Uses the default timeout of the Actor (setTimeout()) - */ - def sendRequestReply(message: AnyRef, sender: ActorRef): AnyRef = sendRequestReply(message, timeout, sender) - - /** - * Akka Java API. <p/> - * Sends a message asynchronously and waits on a future for a reply message under the hood. - * <p/> - * It waits on the reply either until it receives it or until the timeout expires - * (which will throw an ActorTimeoutException). E.g. send-and-receive-eventually semantics. - * <p/> - * <b>NOTE:</b> - * Use this method with care. In most cases it is better to use 'sendOneWay' together with 'getContext().getSender()' to - * implement request/response message exchanges. - * <p/> - * If you are sending messages using <code>sendRequestReply</code> then you <b>have to</b> use <code>getContext().reply(..)</code> - * to send a reply message to the original sender. If not then the sender will block until the timeout expires. - */ - def sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef): AnyRef = { - !!(message, timeout)(Option(sender)).getOrElse(throw new ActorTimeoutException( - "Message [" + message + - "]\n\tsent to [" + actorClassName + - "]\n\tfrom [" + (if (sender ne null) sender.actorClassName else "nowhere") + - "]\n\twith timeout [" + timeout + - "]\n\ttimed out.")) - .asInstanceOf[AnyRef] - } - - /** - * Akka Java API. <p/> - * @see sendRequestReplyFuture(message: AnyRef, sender: ActorRef): Future[_] - * Uses the Actors default timeout (setTimeout()) and omits the sender - */ - def sendRequestReplyFuture[T <: AnyRef](message: AnyRef): Future[T] = sendRequestReplyFuture(message, timeout, null).asInstanceOf[Future[T]] - - /** - * Akka Java API. <p/> - * @see sendRequestReplyFuture(message: AnyRef, sender: ActorRef): Future[_] - * Uses the Actors default timeout (setTimeout()) - */ - def sendRequestReplyFuture[T <: AnyRef](message: AnyRef, sender: ActorRef): Future[T] = sendRequestReplyFuture(message, timeout, sender).asInstanceOf[Future[T]] - - /** - * Akka Java API. <p/> - * Sends a message asynchronously returns a future holding the eventual reply message. - * <p/> - * <b>NOTE:</b> - * Use this method with care. In most cases it is better to use 'sendOneWay' together with the 'getContext().getSender()' to - * implement request/response message exchanges. - * <p/> - * If you are sending messages using <code>sendRequestReplyFuture</code> then you <b>have to</b> use <code>getContext().reply(..)</code> - * to send a reply message to the original sender. If not then the sender will block until the timeout expires. - */ - def sendRequestReplyFuture[T <: AnyRef](message: AnyRef, timeout: Long, sender: ActorRef): Future[T] = !!!(message, timeout)(Option(sender)).asInstanceOf[Future[T]] - - /** - * Akka Java API. <p/> - * Forwards the message specified to this actor and preserves the original sender of the message - */ - def forward(message: AnyRef, sender: ActorRef): Unit = - if (sender eq null) throw new IllegalArgumentException("The 'sender' argument to 'forward' can't be null") - else forward(message)(Some(sender)) - - /** - * Akka Java API. <p/> - * Use <code>getContext().replyUnsafe(..)</code> to reply with a message to the original sender of the message currently - * being processed. - * <p/> - * Throws an IllegalStateException if unable to determine what to reply to. - */ - def replyUnsafe(message: AnyRef) = reply(message) - - /** - * Akka Java API. <p/> - * Use <code>getContext().replySafe(..)</code> to reply with a message to the original sender of the message currently - * being processed. - * <p/> - * Returns true if reply was sent, and false if unable to determine what to reply to. - */ - def replySafe(message: AnyRef): Boolean = reply_?(message) - - /** - * Returns the class for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def actorClass: Class[_ <: Actor] - - /** - * Akka Java API. <p/> - * Returns the class for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def getActorClass(): Class[_ <: Actor] = actorClass - - /** - * Returns the class name for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def actorClassName: String - - /** - * Akka Java API. <p/> - * Returns the class name for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def getActorClassName(): String = actorClassName - - /** - * Sets the dispatcher for this actor. Needs to be invoked before the actor is started. - */ - def dispatcher_=(md: MessageDispatcher): Unit - - /** - * Get the dispatcher for this actor. - */ - def dispatcher: MessageDispatcher - - /** - * Starts up the actor and its message queue. - */ - def start(): ActorRef - - /** - * Shuts down the actor its dispatcher and message queue. - * Alias for 'stop'. - */ - def exit() = stop() - - /** - * Shuts down the actor its dispatcher and message queue. - */ - def stop(): Unit - - /** - * Links an other actor to this actor. Links are unidirectional and means that a the linking actor will - * receive a notification if the linked actor has crashed. - * <p/> - * If the 'trapExit' member field of the 'faultHandler' has been set to at contain at least one exception class then it will - * 'trap' these exceptions and automatically restart the linked actors according to the restart strategy - * defined by the 'faultHandler'. - */ - def link(actorRef: ActorRef): Unit - - /** - * Unlink the actor. - */ - def unlink(actorRef: ActorRef): Unit - - /** - * Atomically start and link an actor. - */ - def startLink(actorRef: ActorRef): Unit - - /** - * Atomically create (from actor class) and start an actor. - * <p/> - * To be invoked from within the actor itself. - */ - @deprecated("Will be removed after 1.1, use Actor.actorOf instead", "1.1") - def spawn(clazz: Class[_ <: Actor]): ActorRef - - /** - * Atomically create (from actor class), make it remote and start an actor. - * <p/> - * To be invoked from within the actor itself. - */ - @deprecated("Will be removed after 1.1, client managed actors will be removed", "1.1") - def spawnRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long): ActorRef - - /** - * Atomically create (from actor class), link and start an actor. - * <p/> - * To be invoked from within the actor itself. - */ - @deprecated("Will be removed after 1.1, use use Actor.remote.actorOf instead and then link on success", "1.1") - def spawnLink(clazz: Class[_ <: Actor]): ActorRef - - /** - * Atomically create (from actor class), make it remote, link and start an actor. - * <p/> - * To be invoked from within the actor itself. - */ - @deprecated("Will be removed after 1.1, client managed actors will be removed", "1.1") - def spawnLinkRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long): ActorRef - - /** - * Returns the mailbox size. - */ - def mailboxSize = dispatcher.mailboxSize(this) - - /** - * Akka Java API. <p/> - * Returns the mailbox size. - */ - def getMailboxSize(): Int = mailboxSize - - /** - * Returns the supervisor, if there is one. - */ - def supervisor: Option[ActorRef] - - /** - * Akka Java API. <p/> - * Returns the supervisor, if there is one. - */ - def getSupervisor(): ActorRef = supervisor getOrElse null - - /** - * Returns an unmodifiable Java Map containing the linked actors, - * please note that the backing map is thread-safe but not immutable - */ - def linkedActors: JMap[Uuid, ActorRef] - - /** - * Java API. <p/> - * Returns an unmodifiable Java Map containing the linked actors, - * please note that the backing map is thread-safe but not immutable - */ - def getLinkedActors(): JMap[Uuid, ActorRef] = linkedActors - - /** - * Abstraction for unification of sender and senderFuture for later reply - */ - def channel: Channel[Any] = { - if (senderFuture.isDefined) { - new Channel[Any] { - val future = senderFuture.get - def !(msg: Any) = future completeWithResult msg - } - } else if (sender.isDefined) { - val someSelf = Some(this) - new Channel[Any] { - val client = sender.get - def !(msg: Any) = client.!(msg)(someSelf) - } - } else throw new IllegalActorStateException("No channel available") - } - - /** - * Java API. <p/> - * Abstraction for unification of sender and senderFuture for later reply - */ - def getChannel: Channel[Any] = channel - - protected[akka] def invoke(messageHandle: MessageInvocation): Unit - - protected[akka] def postMessageToMailbox(message: Any, senderOption: Option[ActorRef]): Unit - - protected[akka] def postMessageToMailboxAndCreateFutureResultWithTimeout[T]( - message: Any, - timeout: Long, - senderOption: Option[ActorRef], - senderFuture: Option[CompletableFuture[T]]): CompletableFuture[T] - - protected[akka] def actorInstance: AtomicReference[Actor] - - protected[akka] def actor: Actor = actorInstance.get - - protected[akka] def supervisor_=(sup: Option[ActorRef]): Unit - - protected[akka] def mailbox: AnyRef - protected[akka] def mailbox_=(value: AnyRef): AnyRef - - protected[akka] def handleTrapExit(dead: ActorRef, reason: Throwable): Unit - - protected[akka] def restart(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]): Unit - - protected[akka] def restartLinkedActors(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]): Unit - - protected[akka] def registerSupervisorAsRemoteActor: Option[Uuid] - - override def hashCode: Int = HashCode.hash(HashCode.SEED, uuid) - - override def equals(that: Any): Boolean = { - that.isInstanceOf[ActorRef] && - that.asInstanceOf[ActorRef].uuid == uuid - } - - override def toString = "Actor[" + id + ":" + uuid + "]" -} - -/** - * Local (serializable) ActorRef that is used when referencing the Actor on its "home" node. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class LocalActorRef private[akka] ( - private[this] val actorFactory: () => Actor, - val homeAddress: Option[InetSocketAddress], - val clientManaged: Boolean = false) - extends ActorRef with ScalaActorRef { - protected[akka] val guard = new ReentrantGuard - - @volatile - protected[akka] var _futureTimeout: Option[ScheduledFuture[AnyRef]] = None - @volatile - private[akka] lazy val _linkedActors = new ConcurrentHashMap[Uuid, ActorRef] - @volatile - private[akka] var _supervisor: Option[ActorRef] = None - @volatile - private var maxNrOfRetriesCount: Int = 0 - @volatile - private var restartsWithinTimeRangeTimestamp: Long = 0L - @volatile - private var _mailbox: AnyRef = _ - @volatile - private[akka] var _dispatcher: MessageDispatcher = Dispatchers.defaultGlobalDispatcher - - protected[akka] val actorInstance = guard.withGuard { new AtomicReference[Actor](newActor) } - - //If it was started inside "newActor", initialize it - if (isRunning) initializeActorInstance - - // used only for deserialization - private[akka] def this( - __uuid: Uuid, - __id: String, - __timeout: Long, - __receiveTimeout: Option[Long], - __lifeCycle: LifeCycle, - __supervisor: Option[ActorRef], - __hotswap: Stack[PartialFunction[Any, Unit]], - __factory: () => Actor, - __homeAddress: Option[InetSocketAddress]) = { - this(__factory, __homeAddress) - _uuid = __uuid - id = __id - timeout = __timeout - receiveTimeout = __receiveTimeout - lifeCycle = __lifeCycle - _supervisor = __supervisor - hotswap = __hotswap - setActorSelfFields(actor, this) - start - } - - /** - * Returns whether this actor ref is client-managed remote or not - */ - private[akka] final def isClientManaged_? = clientManaged && homeAddress.isDefined && isRemotingEnabled - - // ========= PUBLIC FUNCTIONS ========= - - /** - * Returns the class for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def actorClass: Class[_ <: Actor] = actor.getClass.asInstanceOf[Class[_ <: Actor]] - - /** - * Returns the class name for the Actor instance that is managed by the ActorRef. - */ - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def actorClassName: String = actorClass.getName - - /** - * Sets the dispatcher for this actor. Needs to be invoked before the actor is started. - */ - def dispatcher_=(md: MessageDispatcher): Unit = guard.withGuard { - if (!isBeingRestarted) { - if (!isRunning) _dispatcher = md - else throw new ActorInitializationException( - "Can not swap dispatcher for " + toString + " after it has been started") - } - } - - /** - * Get the dispatcher for this actor. - */ - def dispatcher: MessageDispatcher = _dispatcher - - /** - * Starts up the actor and its message queue. - */ - def start(): ActorRef = guard.withGuard { - if (isShutdown) throw new ActorStartException( - "Can't restart an actor that has been shut down with 'stop' or 'exit'") - if (!isRunning) { - dispatcher.attach(this) - - _status = ActorRefInternals.RUNNING - - // If we are not currently creating this ActorRef instance - if ((actorInstance ne null) && (actorInstance.get ne null)) - initializeActorInstance - - if (isClientManaged_?) - Actor.remote.registerClientManagedActor(homeAddress.get.getAddress.getHostAddress, homeAddress.get.getPort, uuid) - - checkReceiveTimeout //Schedule the initial Receive timeout - } - this - } - - /** - * Shuts down the actor its dispatcher and message queue. - */ - def stop() = guard.withGuard { - if (isRunning) { - receiveTimeout = None - cancelReceiveTimeout - dispatcher.detach(this) - _status = ActorRefInternals.SHUTDOWN - try { - actor.postStop - } finally { - currentMessage = null - Actor.registry.unregister(this) - if (isRemotingEnabled) { - if (isClientManaged_?) - Actor.remote.unregisterClientManagedActor(homeAddress.get.getAddress.getHostAddress, homeAddress.get.getPort, uuid) - Actor.remote.unregister(this) - } - setActorSelfFields(actorInstance.get, null) - } - } //else if (isBeingRestarted) throw new ActorKilledException("Actor [" + toString + "] is being restarted.") - } - - /** - * Links an other actor to this actor. Links are unidirectional and means that a the linking actor will - * receive a notification if the linked actor has crashed. - * <p/> - * If the 'trapExit' member field of the 'faultHandler' has been set to at contain at least one exception class then it will - * 'trap' these exceptions and automatically restart the linked actors according to the restart strategy - * defined by the 'faultHandler'. - * <p/> - * To be invoked from within the actor itself. - */ - def link(actorRef: ActorRef): Unit = guard.withGuard { - val actorRefSupervisor = actorRef.supervisor - val hasSupervisorAlready = actorRefSupervisor.isDefined - if (hasSupervisorAlready && actorRefSupervisor.get.uuid == uuid) return // we already supervise this guy - else if (hasSupervisorAlready) throw new IllegalActorStateException( - "Actor can only have one supervisor [" + actorRef + "], e.g. link(actor) fails") - else { - _linkedActors.put(actorRef.uuid, actorRef) - actorRef.supervisor = Some(this) - } - } - - /** - * Unlink the actor. - * <p/> - * To be invoked from within the actor itself. - */ - def unlink(actorRef: ActorRef) = guard.withGuard { - if (_linkedActors.remove(actorRef.uuid) eq null) - throw new IllegalActorStateException("Actor [" + actorRef + "] is not a linked actor, can't unlink") - - actorRef.supervisor = None - } - - /** - * Atomically start and link an actor. - * <p/> - * To be invoked from within the actor itself. - */ - def startLink(actorRef: ActorRef): Unit = guard.withGuard { - link(actorRef) - actorRef.start() - } - - /** - * Atomically create (from actor class) and start an actor. - * <p/> - * To be invoked from within the actor itself. - */ - def spawn(clazz: Class[_ <: Actor]): ActorRef = - Actor.actorOf(clazz).start() - - /** - * Atomically create (from actor class), start and make an actor remote. - * <p/> - * To be invoked from within the actor itself. - */ - def spawnRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long = Actor.TIMEOUT): ActorRef = { - ensureRemotingEnabled - val ref = Actor.remote.actorOf(clazz, hostname, port) - ref.timeout = timeout - ref.start() - } - - /** - * Atomically create (from actor class), start and link an actor. - * <p/> - * To be invoked from within the actor itself. - */ - def spawnLink(clazz: Class[_ <: Actor]): ActorRef = { - val actor = spawn(clazz) - link(actor) - actor.start() - actor - } - - /** - * Atomically create (from actor class), start, link and make an actor remote. - * <p/> - * To be invoked from within the actor itself. - */ - def spawnLinkRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long = Actor.TIMEOUT): ActorRef = { - ensureRemotingEnabled - val actor = Actor.remote.actorOf(clazz, hostname, port) - actor.timeout = timeout - link(actor) - actor.start() - actor - } - - /** - * Returns the mailbox. - */ - def mailbox: AnyRef = _mailbox - - protected[akka] def mailbox_=(value: AnyRef): AnyRef = { _mailbox = value; value } - - /** - * Returns the supervisor, if there is one. - */ - def supervisor: Option[ActorRef] = _supervisor - - // ========= AKKA PROTECTED FUNCTIONS ========= - - protected[akka] def supervisor_=(sup: Option[ActorRef]): Unit = _supervisor = sup - - protected[akka] def postMessageToMailbox(message: Any, senderOption: Option[ActorRef]): Unit = - if (isClientManaged_?) { - Actor.remote.send[Any]( - message, senderOption, None, homeAddress.get, timeout, true, this, None, ActorType.ScalaActor, None) - } else - dispatcher dispatchMessage new MessageInvocation(this, message, senderOption, None) - - protected[akka] def postMessageToMailboxAndCreateFutureResultWithTimeout[T]( - message: Any, - timeout: Long, - senderOption: Option[ActorRef], - senderFuture: Option[CompletableFuture[T]]): CompletableFuture[T] = { - if (isClientManaged_?) { - val future = Actor.remote.send[T]( - message, senderOption, senderFuture, homeAddress.get, timeout, false, this, None, ActorType.ScalaActor, None) - if (future.isDefined) future.get - else throw new IllegalActorStateException("Expected a future from remote call to actor " + toString) - } else { - val future = if (senderFuture.isDefined) senderFuture else Some(new DefaultCompletableFuture[T](timeout)) - dispatcher dispatchMessage new MessageInvocation( - this, message, senderOption, future.asInstanceOf[Some[CompletableFuture[Any]]]) - future.get - } - } - - /** - * Callback for the dispatcher. This is the single entry point to the user Actor implementation. - */ - protected[akka] def invoke(messageHandle: MessageInvocation): Unit = { - guard.lock.lock - try { - if (!isShutdown) { - currentMessage = messageHandle - try { - try { - cancelReceiveTimeout // FIXME: leave this here? - actor(messageHandle.message) - currentMessage = null // reset current message after successful invocation - } catch { - case e: InterruptedException => - currentMessage = null // received message while actor is shutting down, ignore - case e => - handleExceptionInDispatch(e, messageHandle.message) - } - finally { - checkReceiveTimeout // Reschedule receive timeout - } - } catch { - case e => - EventHandler.error(e, this, messageHandle.message.toString) - throw e - } - } - } finally { guard.lock.unlock } - } - - protected[akka] def handleTrapExit(dead: ActorRef, reason: Throwable) { - faultHandler match { - case AllForOneStrategy(trapExit, maxRetries, within) if trapExit.exists(_.isAssignableFrom(reason.getClass)) => - restartLinkedActors(reason, maxRetries, within) - - case OneForOneStrategy(trapExit, maxRetries, within) if trapExit.exists(_.isAssignableFrom(reason.getClass)) => - dead.restart(reason, maxRetries, within) - - case _ => - if (_supervisor.isDefined) notifySupervisorWithMessage(Exit(this, reason)) - else dead.stop() - } - } - - private def requestRestartPermission(maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]): Boolean = { - val denied = if (maxNrOfRetries.isEmpty && withinTimeRange.isEmpty) { //Immortal - false - } else if (withinTimeRange.isEmpty) { // restrict number of restarts - maxNrOfRetriesCount += 1 //Increment number of retries - maxNrOfRetriesCount > maxNrOfRetries.get - } else { // cannot restart more than N within M timerange - maxNrOfRetriesCount += 1 //Increment number of retries - val windowStart = restartsWithinTimeRangeTimestamp - val now = System.currentTimeMillis - val retries = maxNrOfRetriesCount - //We are within the time window if it isn't the first restart, or if the window hasn't closed - val insideWindow = if (windowStart == 0) false - else (now - windowStart) <= withinTimeRange.get - - //The actor is dead if it dies X times within the window of restart - val unrestartable = insideWindow && retries > maxNrOfRetries.getOrElse(1) - - if (windowStart == 0 || !insideWindow) //(Re-)set the start of the window - restartsWithinTimeRangeTimestamp = now - - if (windowStart != 0 && !insideWindow) //Reset number of restarts if window has expired - maxNrOfRetriesCount = 1 - - unrestartable - } - - denied == false //If we weren't denied, we have a go - } - - protected[akka] def restart(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]) { - def performRestart() { - val failedActor = actorInstance.get - - failedActor match { - case p: Proxyable => - failedActor.preRestart(reason) - failedActor.postRestart(reason) - case _ => - failedActor.preRestart(reason) - val freshActor = newActor - setActorSelfFields(failedActor, null) // Only null out the references if we could instantiate the new actor - actorInstance.set(freshActor) // Assign it here so if preStart fails, we can null out the sef-refs next call - freshActor.preStart - freshActor.postRestart(reason) - } - } - - def tooManyRestarts() { - _supervisor.foreach { sup => - // can supervisor handle the notification? - val notification = MaximumNumberOfRestartsWithinTimeRangeReached(this, maxNrOfRetries, withinTimeRange, reason) - if (sup.isDefinedAt(notification)) notifySupervisorWithMessage(notification) - } - stop - } - - @tailrec - def attemptRestart() { - val success = if (requestRestartPermission(maxNrOfRetries, withinTimeRange)) { - guard.withGuard[Boolean] { - _status = ActorRefInternals.BEING_RESTARTED - - lifeCycle match { - case Temporary => - shutDownTemporaryActor(this) - true - - case _ => // either permanent or none where default is permanent - val success = try { - performRestart() - true - } catch { - case e => - EventHandler.error(e, this, "Exception in restart of Actor [%s]".format(toString)) - false // an error or exception here should trigger a retry - } - finally { - currentMessage = null - } - if (success) { - _status = ActorRefInternals.RUNNING - dispatcher.resume(this) - restartLinkedActors(reason, maxNrOfRetries, withinTimeRange) - } - success - } - } - } else { - tooManyRestarts() - true // done - } - - if (success) () // alles gut - else attemptRestart() - } - - attemptRestart() // recur - } - - protected[akka] def restartLinkedActors(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]) = { - val i = _linkedActors.values.iterator - while (i.hasNext) { - val actorRef = i.next - actorRef.lifeCycle match { - // either permanent or none where default is permanent - case Temporary => shutDownTemporaryActor(actorRef) - case _ => actorRef.restart(reason, maxNrOfRetries, withinTimeRange) - } - } - } - - protected[akka] def registerSupervisorAsRemoteActor: Option[Uuid] = guard.withGuard { - ensureRemotingEnabled - if (_supervisor.isDefined) { - if (homeAddress.isDefined) Actor.remote.registerSupervisorForActor(this) - Some(_supervisor.get.uuid) - } else None - } - - def linkedActors: JMap[Uuid, ActorRef] = java.util.Collections.unmodifiableMap(_linkedActors) - - // ========= PRIVATE FUNCTIONS ========= - - private[this] def newActor: Actor = { - try { - Actor.actorRefInCreation.set(Some(this)) - val a = actorFactory() - if (a eq null) throw new ActorInitializationException("Actor instance passed to ActorRef can not be 'null'") - a - } finally { - Actor.actorRefInCreation.set(None) - } - } - - private def shutDownTemporaryActor(temporaryActor: ActorRef) { - temporaryActor.stop() - _linkedActors.remove(temporaryActor.uuid) // remove the temporary actor - // if last temporary actor is gone, then unlink me from supervisor - if (_linkedActors.isEmpty) notifySupervisorWithMessage(UnlinkAndStop(this)) - true - } - - private def handleExceptionInDispatch(reason: Throwable, message: Any) = { - EventHandler.error(reason, this, message.toString) - - //Prevent any further messages to be processed until the actor has been restarted - dispatcher.suspend(this) - - senderFuture.foreach(_.completeWithException(reason)) - - if (supervisor.isDefined) notifySupervisorWithMessage(Exit(this, reason)) - else { - lifeCycle match { - case Temporary => shutDownTemporaryActor(this) - case _ => dispatcher.resume(this) //Resume processing for this actor - } - } - } - - private def notifySupervisorWithMessage(notification: LifeCycleMessage) = { - // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client - _supervisor.foreach { sup => - if (sup.isShutdown) { // if supervisor is shut down, game over for all linked actors - //Scoped stop all linked actors, to avoid leaking the 'i' val - { - val i = _linkedActors.values.iterator - while (i.hasNext) { - i.next.stop() - i.remove - } - } - //Stop the actor itself - stop - } else sup ! notification // else notify supervisor - } - } - - private def setActorSelfFields(actor: Actor, value: ActorRef) { - - @tailrec - def lookupAndSetSelfFields(clazz: Class[_], actor: Actor, value: ActorRef): Boolean = { - val success = try { - val selfField = clazz.getDeclaredField("self") - val someSelfField = clazz.getDeclaredField("someSelf") - selfField.setAccessible(true) - someSelfField.setAccessible(true) - selfField.set(actor, value) - someSelfField.set(actor, if (value ne null) Some(value) else null) - true - } catch { - case e: NoSuchFieldException => false - } - - if (success) true - else { - val parent = clazz.getSuperclass - if (parent eq null) - throw new IllegalActorStateException(toString + " is not an Actor since it have not mixed in the 'Actor' trait") - lookupAndSetSelfFields(parent, actor, value) - } - } - - lookupAndSetSelfFields(actor.getClass, actor, value) - } - - private def initializeActorInstance = { - actor.preStart // run actor preStart - Actor.registry.register(this) - } - - protected[akka] def checkReceiveTimeout = { - cancelReceiveTimeout - if (receiveTimeout.isDefined && dispatcher.mailboxSize(this) <= 0) { //Only reschedule if desired and there are currently no more messages to be processed - _futureTimeout = Some(Scheduler.scheduleOnce(this, ReceiveTimeout, receiveTimeout.get, TimeUnit.MILLISECONDS)) - } - } - - protected[akka] def cancelReceiveTimeout = { - if (_futureTimeout.isDefined) { - _futureTimeout.get.cancel(true) - _futureTimeout = None - } - } -} - -/** - * System messages for RemoteActorRef. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object RemoteActorSystemMessage { - val Stop = "RemoteActorRef:stop".intern -} - -/** - * Remote ActorRef that is used when referencing the Actor on a different node than its "home" node. - * This reference is network-aware (remembers its origin) and immutable. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -private[akka] case class RemoteActorRef private[akka] ( - classOrServiceName: String, - val actorClassName: String, - val hostname: String, - val port: Int, - _timeout: Long, - loader: Option[ClassLoader], - val actorType: ActorType = ActorType.ScalaActor) - extends ActorRef with ScalaActorRef { - - ensureRemotingEnabled - - val homeAddress = Some(new InetSocketAddress(hostname, port)) - - //protected def clientManaged = classOrServiceName.isEmpty //If no class or service name, it's client managed - id = classOrServiceName - //id = classOrServiceName.getOrElse("uuid:" + uuid) //If we're a server-managed we want to have classOrServiceName as id, or else, we're a client-managed and we want to have our uuid as id - - timeout = _timeout - - start - - def postMessageToMailbox(message: Any, senderOption: Option[ActorRef]): Unit = - Actor.remote.send[Any](message, senderOption, None, homeAddress.get, timeout, true, this, None, actorType, loader) - - def postMessageToMailboxAndCreateFutureResultWithTimeout[T]( - message: Any, - timeout: Long, - senderOption: Option[ActorRef], - senderFuture: Option[CompletableFuture[T]]): CompletableFuture[T] = { - val future = Actor.remote.send[T]( - message, senderOption, senderFuture, - homeAddress.get, timeout, - false, this, None, - actorType, loader) - if (future.isDefined) future.get - else throw new IllegalActorStateException("Expected a future from remote call to actor " + toString) - } - - def start: ActorRef = synchronized { - _status = ActorRefInternals.RUNNING - this - } - - def stop: Unit = synchronized { - if (_status == ActorRefInternals.RUNNING) { - _status = ActorRefInternals.SHUTDOWN - postMessageToMailbox(RemoteActorSystemMessage.Stop, None) - } - } - - protected[akka] def registerSupervisorAsRemoteActor: Option[Uuid] = None - - // ==== NOT SUPPORTED ==== - @deprecated("Will be removed without replacement, doesn't make any sense to have in the face of `become` and `unbecome`", "1.1") - def actorClass: Class[_ <: Actor] = unsupported - def dispatcher_=(md: MessageDispatcher): Unit = unsupported - def dispatcher: MessageDispatcher = unsupported - def link(actorRef: ActorRef): Unit = unsupported - def unlink(actorRef: ActorRef): Unit = unsupported - def startLink(actorRef: ActorRef): Unit = unsupported - def spawn(clazz: Class[_ <: Actor]): ActorRef = unsupported - def spawnRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long): ActorRef = unsupported - def spawnLink(clazz: Class[_ <: Actor]): ActorRef = unsupported - def spawnLinkRemote(clazz: Class[_ <: Actor], hostname: String, port: Int, timeout: Long): ActorRef = unsupported - def supervisor: Option[ActorRef] = unsupported - def linkedActors: JMap[Uuid, ActorRef] = unsupported - protected[akka] def mailbox: AnyRef = unsupported - protected[akka] def mailbox_=(value: AnyRef): AnyRef = unsupported - protected[akka] def handleTrapExit(dead: ActorRef, reason: Throwable): Unit = unsupported - protected[akka] def restart(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]): Unit = unsupported - protected[akka] def restartLinkedActors(reason: Throwable, maxNrOfRetries: Option[Int], withinTimeRange: Option[Int]): Unit = unsupported - protected[akka] def invoke(messageHandle: MessageInvocation): Unit = unsupported - protected[akka] def supervisor_=(sup: Option[ActorRef]): Unit = unsupported - protected[akka] def actorInstance: AtomicReference[Actor] = unsupported - private def unsupported = throw new UnsupportedOperationException("Not supported for RemoteActorRef") -} - -/** - * This trait represents the common (external) methods for all ActorRefs - * Needed because implicit conversions aren't applied when instance imports are used - * - * i.e. - * var self: ScalaActorRef = ... - * import self._ - * //can't call ActorRef methods here unless they are declared in a common - * //superclass, which ActorRefShared is. - */ -trait ActorRefShared { - /** - * Returns the uuid for the actor. - */ - def uuid: Uuid -} - -/** - * This trait represents the Scala Actor API - * There are implicit conversions in ../actor/Implicits.scala - * from ActorRef -> ScalaActorRef and back - */ -trait ScalaActorRef extends ActorRefShared { ref: ActorRef => - - /** - * Identifier for actor, does not have to be a unique one. Default is the 'uuid'. - * <p/> - * This field is used for logging, AspectRegistry.actorsFor(id), identifier for remote - * actor in RemoteServer etc.But also as the identifier for persistence, which means - * that you can use a custom name to be able to retrieve the "correct" persisted state - * upon restart, remote restart etc. - */ - def id: String - - def id_=(id: String): Unit - - /** - * User overridable callback/setting. - * <p/> - * Defines the life-cycle for a supervised actor. - */ - @volatile - @BeanProperty - var lifeCycle: LifeCycle = UndefinedLifeCycle - - /** - * User overridable callback/setting. - * <p/> - * Don't forget to supply a List of exception types to intercept (trapExit) - * <p/> - * Can be one of: - * <pre> - * faultHandler = AllForOneStrategy(trapExit = List(classOf[Exception]), maxNrOfRetries, withinTimeRange) - * </pre> - * Or: - * <pre> - * faultHandler = OneForOneStrategy(trapExit = List(classOf[Exception]), maxNrOfRetries, withinTimeRange) - * </pre> - */ - @volatile - @BeanProperty - var faultHandler: FaultHandlingStrategy = NoFaultHandlingStrategy - - /** - * The reference sender Actor of the last received message. - * Is defined if the message was sent from another Actor, else None. - */ - def sender: Option[ActorRef] = { - val msg = currentMessage - if (msg eq null) None - else msg.sender - } - - /** - * The reference sender future of the last received message. - * Is defined if the message was sent with sent with '!!' or '!!!', else None. - */ - def senderFuture(): Option[CompletableFuture[Any]] = { - val msg = currentMessage - if (msg eq null) None - else msg.senderFuture - } - - /** - * Sends a one-way asynchronous message. E.g. fire-and-forget semantics. - * <p/> - * - * If invoked from within an actor then the actor reference is implicitly passed on as the implicit 'sender' argument. - * <p/> - * - * This actor 'sender' reference is then available in the receiving actor in the 'sender' member variable, - * if invoked from within an Actor. If not then no sender is available. - * <pre> - * actor ! message - * </pre> - * <p/> - */ - def !(message: Any)(implicit sender: Option[ActorRef] = None): Unit = { - if (isRunning) postMessageToMailbox(message, sender) - else throw new ActorInitializationException( - "Actor has not been started, you need to invoke 'actor.start()' before using it") - } - - /** - * Sends a message asynchronously and waits on a future for a reply message. - * <p/> - * It waits on the reply either until it receives it (in the form of <code>Some(replyMessage)</code>) - * or until the timeout expires (which will return None). E.g. send-and-receive-eventually semantics. - * <p/> - * <b>NOTE:</b> - * Use this method with care. In most cases it is better to use '!' together with the 'sender' member field to - * implement request/response message exchanges. - * If you are sending messages using <code>!!</code> then you <b>have to</b> use <code>self.reply(..)</code> - * to send a reply message to the original sender. If not then the sender will block until the timeout expires. - */ - def !!(message: Any, timeout: Long = this.timeout)(implicit sender: Option[ActorRef] = None): Option[Any] = { - if (isRunning) { - val future = postMessageToMailboxAndCreateFutureResultWithTimeout[Any](message, timeout, sender, None) - val isMessageJoinPoint = if (isTypedActorEnabled) TypedActorModule.resolveFutureIfMessageIsJoinPoint(message, future) - else false - try { - future.await - } catch { - case e: FutureTimeoutException => - if (isMessageJoinPoint) { - EventHandler.error(e, this, e.getMessage) - throw e - } else None - } - future.resultOrException - } else throw new ActorInitializationException( - "Actor has not been started, you need to invoke 'actor.start()' before using it") - } - - /** - * Sends a message asynchronously returns a future holding the eventual reply message. - * <p/> - * <b>NOTE:</b> - * Use this method with care. In most cases it is better to use '!' together with the 'sender' member field to - * implement request/response message exchanges. - * If you are sending messages using <code>!!!</code> then you <b>have to</b> use <code>self.reply(..)</code> - * to send a reply message to the original sender. If not then the sender will block until the timeout expires. - */ - def !!![T](message: Any, timeout: Long = this.timeout)(implicit sender: Option[ActorRef] = None): Future[T] = { - if (isRunning) postMessageToMailboxAndCreateFutureResultWithTimeout[T](message, timeout, sender, None) - else throw new ActorInitializationException( - "Actor has not been started, you need to invoke 'actor.start()' before using it") - } - - /** - * Forwards the message and passes the original sender actor as the sender. - * <p/> - * Works with '!', '!!' and '!!!'. - */ - def forward(message: Any)(implicit sender: Some[ActorRef]) = { - if (isRunning) { - if (sender.get.senderFuture.isDefined) - postMessageToMailboxAndCreateFutureResultWithTimeout(message, timeout, sender.get.sender, sender.get.senderFuture) - else - postMessageToMailbox(message, sender.get.sender) - } else throw new ActorInitializationException("Actor has not been started, you need to invoke 'actor.start()' before using it") - } - - /** - * Use <code>self.reply(..)</code> to reply with a message to the original sender of the message currently - * being processed. - * <p/> - * Throws an IllegalStateException if unable to determine what to reply to. - */ - def reply(message: Any) = if (!reply_?(message)) throw new IllegalActorStateException( - "\n\tNo sender in scope, can't reply. " + - "\n\tYou have probably: " + - "\n\t\t1. Sent a message to an Actor from an instance that is NOT an Actor." + - "\n\t\t2. Invoked a method on an TypedActor from an instance NOT an TypedActor." + - "\n\tElse you might want to use 'reply_?' which returns Boolean(true) if succes and Boolean(false) if no sender in scope") - - /** - * Use <code>reply_?(..)</code> to reply with a message to the original sender of the message currently - * being processed. - * <p/> - * Returns true if reply was sent, and false if unable to determine what to reply to. - */ - def reply_?(message: Any): Boolean = { - if (senderFuture.isDefined) { - senderFuture.get completeWithResult message - true - } else if (sender.isDefined) { - //TODO: optimize away this allocation, perhaps by having implicit self: Option[ActorRef] in signature - sender.get.!(message)(Some(this)) - true - } else false - } - - /** - * Atomically create (from actor class) and start an actor. - */ - def spawn[T <: Actor: Manifest]: ActorRef = - spawn(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]]) - - /** - * Atomically create (from actor class), start and make an actor remote. - */ - def spawnRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = { - ensureRemotingEnabled - spawnRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout) - } - - /** - * Atomically create (from actor class), start and link an actor. - */ - def spawnLink[T <: Actor: Manifest]: ActorRef = - spawnLink(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]]) - - /** - * Atomically create (from actor class), start, link and make an actor remote. - */ - def spawnLinkRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = { - ensureRemotingEnabled - spawnLinkRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout) - } -} diff --git a/test/files/presentation/akka/src/akka/actor/ActorRegistry.scala b/test/files/presentation/akka/src/akka/actor/ActorRegistry.scala deleted file mode 100644 index df335dc8b4..0000000000 --- a/test/files/presentation/akka/src/akka/actor/ActorRegistry.scala +++ /dev/null @@ -1,389 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import scala.collection.mutable.{ ListBuffer, Map } -import scala.reflect.Manifest - -import java.util.concurrent.{ ConcurrentSkipListSet, ConcurrentHashMap } -import java.util.{ Set => JSet } - -import annotation.tailrec -import akka.util.ReflectiveAccess._ -import akka.util.{ ReflectiveAccess, ReadWriteGuard, ListenerManagement } - -/** - * Base trait for ActorRegistry events, allows listen to when an actor is added and removed from the ActorRegistry. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -sealed trait ActorRegistryEvent -case class ActorRegistered(actor: ActorRef) extends ActorRegistryEvent -case class ActorUnregistered(actor: ActorRef) extends ActorRegistryEvent - -/** - * Registry holding all Actor instances in the whole system. - * Mapped by: - * <ul> - * <li>the Actor's UUID</li> - * <li>the Actor's id field (which can be set by user-code)</li> - * <li>the Actor's class</li> - * <li>all Actors that are subtypes of a specific type</li> - * <ul> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ - -final class ActorRegistry private[actor] () extends ListenerManagement { - - private val actorsByUUID = new ConcurrentHashMap[Uuid, ActorRef] - private val actorsById = new Index[String, ActorRef] - private val guard = new ReadWriteGuard - - /** - * Returns all actors in the system. - */ - def actors: Array[ActorRef] = filter(_ => true) - - /** - * Returns the number of actors in the system. - */ - def size: Int = actorsByUUID.size - - /** - * Invokes a function for all actors. - */ - def foreach(f: (ActorRef) => Unit) = { - val elements = actorsByUUID.elements - while (elements.hasMoreElements) f(elements.nextElement) - } - - /** - * Invokes the function on all known actors until it returns Some - * Returns None if the function never returns Some - */ - def find[T](f: PartialFunction[ActorRef, T]): Option[T] = { - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val element = elements.nextElement - if (f isDefinedAt element) return Some(f(element)) - } - None - } - - /** - * Finds all actors that are subtypes of the class passed in as the Manifest argument and supporting passed message. - */ - def actorsFor[T <: Actor](message: Any)(implicit manifest: Manifest[T]): Array[ActorRef] = - filter(a => manifest.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message)) - - /** - * Finds all actors that satisfy a predicate. - */ - def filter(p: ActorRef => Boolean): Array[ActorRef] = { - val all = new ListBuffer[ActorRef] - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val actorId = elements.nextElement - if (p(actorId)) all += actorId - } - all.toArray - } - - /** - * Finds all actors that are subtypes of the class passed in as the Manifest argument. - */ - def actorsFor[T <: Actor](implicit manifest: Manifest[T]): Array[ActorRef] = - actorsFor[T](manifest.erasure.asInstanceOf[Class[T]]) - - /** - * Finds any actor that matches T. Very expensive, traverses ALL alive actors. - */ - def actorFor[T <: Actor](implicit manifest: Manifest[T]): Option[ActorRef] = - find({ case a: ActorRef if manifest.erasure.isAssignableFrom(a.actor.getClass) => a }) - - /** - * Finds all actors of type or sub-type specified by the class passed in as the Class argument. - */ - def actorsFor[T <: Actor](clazz: Class[T]): Array[ActorRef] = - filter(a => clazz.isAssignableFrom(a.actor.getClass)) - - /** - * Finds all actors that has a specific id. - */ - def actorsFor(id: String): Array[ActorRef] = actorsById values id - - /** - * Finds the actor that has a specific UUID. - */ - def actorFor(uuid: Uuid): Option[ActorRef] = Option(actorsByUUID get uuid) - - /** - * Returns all typed actors in the system. - */ - def typedActors: Array[AnyRef] = filterTypedActors(_ => true) - - /** - * Invokes a function for all typed actors. - */ - def foreachTypedActor(f: (AnyRef) => Unit) = { - TypedActorModule.ensureEnabled - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val proxy = typedActorFor(elements.nextElement) - if (proxy.isDefined) f(proxy.get) - } - } - - /** - * Invokes the function on all known typed actors until it returns Some - * Returns None if the function never returns Some - */ - def findTypedActor[T](f: PartialFunction[AnyRef, T]): Option[T] = { - TypedActorModule.ensureEnabled - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val proxy = typedActorFor(elements.nextElement) - if (proxy.isDefined && (f isDefinedAt proxy)) return Some(f(proxy)) - } - None - } - - /** - * Finds all typed actors that satisfy a predicate. - */ - def filterTypedActors(p: AnyRef => Boolean): Array[AnyRef] = { - TypedActorModule.ensureEnabled - val all = new ListBuffer[AnyRef] - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val proxy = typedActorFor(elements.nextElement) - if (proxy.isDefined && p(proxy.get)) all += proxy.get - } - all.toArray - } - - /** - * Finds all typed actors that are subtypes of the class passed in as the Manifest argument. - */ - def typedActorsFor[T <: AnyRef](implicit manifest: Manifest[T]): Array[AnyRef] = { - TypedActorModule.ensureEnabled - typedActorsFor[T](manifest.erasure.asInstanceOf[Class[T]]) - } - - /** - * Finds any typed actor that matches T. - */ - def typedActorFor[T <: AnyRef](implicit manifest: Manifest[T]): Option[AnyRef] = { - TypedActorModule.ensureEnabled - def predicate(proxy: AnyRef): Boolean = { - val actorRef = TypedActorModule.typedActorObjectInstance.get.actorFor(proxy) - actorRef.isDefined && manifest.erasure.isAssignableFrom(actorRef.get.actor.getClass) - } - findTypedActor({ case a: Some[AnyRef] if predicate(a.get) => a }) - } - - /** - * Finds all typed actors of type or sub-type specified by the class passed in as the Class argument. - */ - def typedActorsFor[T <: AnyRef](clazz: Class[T]): Array[AnyRef] = { - TypedActorModule.ensureEnabled - def predicate(proxy: AnyRef): Boolean = { - val actorRef = TypedActorModule.typedActorObjectInstance.get.actorFor(proxy) - actorRef.isDefined && clazz.isAssignableFrom(actorRef.get.actor.getClass) - } - filterTypedActors(predicate) - } - - /** - * Finds all typed actors that have a specific id. - */ - def typedActorsFor(id: String): Array[AnyRef] = { - TypedActorModule.ensureEnabled - val actorRefs = actorsById values id - actorRefs.flatMap(typedActorFor(_)) - } - - /** - * Finds the typed actor that has a specific UUID. - */ - def typedActorFor(uuid: Uuid): Option[AnyRef] = { - TypedActorModule.ensureEnabled - val actorRef = actorsByUUID get uuid - if (actorRef eq null) None - else typedActorFor(actorRef) - } - - /** - * Get the typed actor proxy for a given typed actor ref. - */ - private def typedActorFor(actorRef: ActorRef): Option[AnyRef] = { - TypedActorModule.typedActorObjectInstance.get.proxyFor(actorRef) - } - - /** - * Registers an actor in the ActorRegistry. - */ - private[akka] def register(actor: ActorRef) { - val id = actor.id - val uuid = actor.uuid - - actorsById.put(id, actor) - actorsByUUID.put(uuid, actor) - - // notify listeners - notifyListeners(ActorRegistered(actor)) - } - - /** - * Unregisters an actor in the ActorRegistry. - */ - private[akka] def unregister(actor: ActorRef) { - val id = actor.id - val uuid = actor.uuid - - actorsByUUID remove uuid - actorsById.remove(id, actor) - - // notify listeners - notifyListeners(ActorUnregistered(actor)) - } - - /** - * Shuts down and unregisters all actors in the system. - */ - def shutdownAll() { - if (TypedActorModule.isEnabled) { - val elements = actorsByUUID.elements - while (elements.hasMoreElements) { - val actorRef = elements.nextElement - val proxy = typedActorFor(actorRef) - if (proxy.isDefined) TypedActorModule.typedActorObjectInstance.get.stop(proxy.get) - else actorRef.stop() - } - } else foreach(_.stop()) - if (Remote.isEnabled) { - Actor.remote.clear //TODO: REVISIT: Should this be here? - } - actorsByUUID.clear - actorsById.clear - } -} - -/** - * An implementation of a ConcurrentMultiMap - * Adds/remove is serialized over the specified key - * Reads are fully concurrent <-- el-cheapo - * - * @author Viktor Klang - */ -class Index[K <: AnyRef, V <: AnyRef: Manifest] { - private val Naught = Array[V]() //Nil for Arrays - private val container = new ConcurrentHashMap[K, JSet[V]] - private val emptySet = new ConcurrentSkipListSet[V] - - /** - * Associates the value of type V with the key of type K - * @return true if the value didn't exist for the key previously, and false otherwise - */ - def put(key: K, value: V): Boolean = { - //Tailrecursive spin-locking put - @tailrec - def spinPut(k: K, v: V): Boolean = { - var retry = false - var added = false - val set = container get k - - if (set ne null) { - set.synchronized { - if (set.isEmpty) retry = true //IF the set is empty then it has been removed, so signal retry - else { //Else add the value to the set and signal that retry is not needed - added = set add v - retry = false - } - } - } else { - val newSet = new ConcurrentSkipListSet[V] - newSet add v - - // Parry for two simultaneous putIfAbsent(id,newSet) - val oldSet = container.putIfAbsent(k, newSet) - if (oldSet ne null) { - oldSet.synchronized { - if (oldSet.isEmpty) retry = true //IF the set is empty then it has been removed, so signal retry - else { //Else try to add the value to the set and signal that retry is not needed - added = oldSet add v - retry = false - } - } - } else added = true - } - - if (retry) spinPut(k, v) - else added - } - - spinPut(key, value) - } - - /** - * @return a _new_ array of all existing values for the given key at the time of the call - */ - def values(key: K): Array[V] = { - val set: JSet[V] = container get key - val result = if (set ne null) set toArray Naught else Naught - result.asInstanceOf[Array[V]] - } - - /** - * @return Some(value) for the first matching value where the supplied function returns true for the given key, - * if no matches it returns None - */ - def findValue(key: K)(f: (V) => Boolean): Option[V] = { - import scala.collection.JavaConversions._ - val set = container get key - if (set ne null) set.iterator.find(f) - else None - } - - /** - * Applies the supplied function to all keys and their values - */ - def foreach(fun: (K, V) => Unit) { - import scala.collection.JavaConversions._ - container.entrySet foreach { (e) => - e.getValue.foreach(fun(e.getKey, _)) - } - } - - /** - * Disassociates the value of type V from the key of type K - * @return true if the value was disassociated from the key and false if it wasn't previously associated with the key - */ - def remove(key: K, value: V): Boolean = { - val set = container get key - - if (set ne null) { - set.synchronized { - if (set.remove(value)) { //If we can remove the value - if (set.isEmpty) //and the set becomes empty - container.remove(key, emptySet) //We try to remove the key if it's mapped to an empty set - - true //Remove succeeded - } else false //Remove failed - } - } else false //Remove failed - } - - /** - * @return true if the underlying containers is empty, may report false negatives when the last remove is underway - */ - def isEmpty: Boolean = container.isEmpty - - /** - * Removes all keys and all values - */ - def clear = foreach { case (k, v) => remove(k, v) } -} diff --git a/test/files/presentation/akka/src/akka/actor/Actors.java b/test/files/presentation/akka/src/akka/actor/Actors.java deleted file mode 100644 index a5ec9f37dc..0000000000 --- a/test/files/presentation/akka/src/akka/actor/Actors.java +++ /dev/null @@ -1,108 +0,0 @@ -package akka.actor; - -import akka.japi.Creator; -import akka.remoteinterface.RemoteSupport; - -/** - * JAVA API for - * - creating actors, - * - creating remote actors, - * - locating actors - */ -public class Actors { - /** - * - * @return The actor registry - */ - public static ActorRegistry registry() { - return Actor$.MODULE$.registry(); - } - - /** - * - * @return - * @throws UnsupportedOperationException If remoting isn't configured - * @throws ModuleNotAvailableException If the class for the remote support cannot be loaded - */ - public static RemoteSupport remote() { - return Actor$.MODULE$.remote(); - } - - /** - * NOTE: Use this convenience method with care, do NOT make it possible to get a reference to the - * UntypedActor instance directly, but only through its 'ActorRef' wrapper reference. - * <p/> - * Creates an ActorRef out of the Actor. Allows you to pass in the instance for the UntypedActor. - * Only use this method when you need to pass in constructor arguments into the 'UntypedActor'. - * <p/> - * You use it by implementing the UntypedActorFactory interface. - * Example in Java: - * <pre> - * ActorRef actor = Actors.actorOf(new UntypedActorFactory() { - * public UntypedActor create() { - * return new MyUntypedActor("service:name", 5); - * } - * }); - * actor.start(); - * actor.sendOneWay(message, context); - * actor.stop(); - * </pre> - */ - public static ActorRef actorOf(final Creator<Actor> factory) { - return Actor$.MODULE$.actorOf(factory); - } - - /** - * Creates an ActorRef out of the Actor type represented by the class provided. - * Example in Java: - * <pre> - * ActorRef actor = Actors.actorOf(MyUntypedActor.class); - * actor.start(); - * actor.sendOneWay(message, context); - * actor.stop(); - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = Actors.actorOf(MyActor.class).start(); - * </pre> - */ - public static ActorRef actorOf(final Class<? extends Actor> type) { - return Actor$.MODULE$.actorOf(type); - } - - /** - * The message that is sent when an Actor gets a receive timeout. - * <pre> - * if( message == receiveTimeout() ) { - * //Timed out - * } - * </pre> - * @return the single instance of ReceiveTimeout - */ - public final static ReceiveTimeout$ receiveTimeout() { - return ReceiveTimeout$.MODULE$; - } - - /** - * The message that when sent to an Actor kills it by throwing an exception. - * <pre> - * actor.sendOneWay(kill()); - * </pre> - * @return the single instance of Kill - */ - public final static Kill$ kill() { - return Kill$.MODULE$; - } - - - /** - * The message that when sent to an Actor shuts it down by calling 'stop'. - * <pre> - * actor.sendOneWay(poisonPill()); - * </pre> - * @return the single instance of PoisonPill - */ - public final static PoisonPill$ poisonPill() { - return PoisonPill$.MODULE$; - } -} diff --git a/test/files/presentation/akka/src/akka/actor/BootableActorLoaderService.scala b/test/files/presentation/akka/src/akka/actor/BootableActorLoaderService.scala deleted file mode 100644 index a54fca9ac7..0000000000 --- a/test/files/presentation/akka/src/akka/actor/BootableActorLoaderService.scala +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import java.io.File -import java.net.{ URL, URLClassLoader } -import java.util.jar.JarFile - -import akka.util.{ Bootable } -import akka.config.Config._ - -/** - * Handles all modules in the deploy directory (load and unload) - */ -trait BootableActorLoaderService extends Bootable { - - val BOOT_CLASSES = config.getList("akka.boot") - lazy val applicationLoader: Option[ClassLoader] = createApplicationClassLoader - - protected def createApplicationClassLoader: Option[ClassLoader] = Some({ - if (HOME.isDefined) { - val DEPLOY = HOME.get + "/deploy" - val DEPLOY_DIR = new File(DEPLOY) - if (!DEPLOY_DIR.exists) { - System.exit(-1) - } - val filesToDeploy = DEPLOY_DIR.listFiles.toArray.toList - .asInstanceOf[List[File]].filter(_.getName.endsWith(".jar")) - var dependencyJars: List[URL] = Nil - filesToDeploy.map { file => - val jarFile = new JarFile(file) - val en = jarFile.entries - while (en.hasMoreElements) { - val name = en.nextElement.getName - if (name.endsWith(".jar")) dependencyJars ::= new File( - String.format("jar:file:%s!/%s", jarFile.getName, name)).toURI.toURL - } - } - val toDeploy = filesToDeploy.map(_.toURI.toURL) - val allJars = toDeploy ::: dependencyJars - - new URLClassLoader(allJars.toArray, Thread.currentThread.getContextClassLoader) - } else Thread.currentThread.getContextClassLoader - }) - - abstract override def onLoad = { - super.onLoad - - for (loader ← applicationLoader; clazz ← BOOT_CLASSES) { - loader.loadClass(clazz).newInstance - } - } - - abstract override def onUnload = { - super.onUnload - Actor.registry.shutdownAll() - } -} diff --git a/test/files/presentation/akka/src/akka/actor/FSM.scala b/test/files/presentation/akka/src/akka/actor/FSM.scala deleted file mode 100644 index d9cd9a9ca2..0000000000 --- a/test/files/presentation/akka/src/akka/actor/FSM.scala +++ /dev/null @@ -1,527 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ -package akka.actor - -import akka.util._ -import akka.event.EventHandler - -import scala.collection.mutable -import java.util.concurrent.ScheduledFuture - -object FSM { - - object NullFunction extends PartialFunction[Any, Nothing] { - def isDefinedAt(o: Any) = false - def apply(o: Any) = sys.error("undefined") - } - - case class CurrentState[S](fsmRef: ActorRef, state: S) - case class Transition[S](fsmRef: ActorRef, from: S, to: S) - case class SubscribeTransitionCallBack(actorRef: ActorRef) - case class UnsubscribeTransitionCallBack(actorRef: ActorRef) - - sealed trait Reason - case object Normal extends Reason - case object Shutdown extends Reason - case class Failure(cause: Any) extends Reason - - case object StateTimeout - case class TimeoutMarker(generation: Long) - - case class Timer(name: String, msg: AnyRef, repeat: Boolean, generation: Int) { - private var ref: Option[ScheduledFuture[AnyRef]] = _ - - def schedule(actor: ActorRef, timeout: Duration) { - if (repeat) { - ref = Some(Scheduler.schedule(actor, this, timeout.length, timeout.length, timeout.unit)) - } else { - ref = Some(Scheduler.scheduleOnce(actor, this, timeout.length, timeout.unit)) - } - } - - def cancel { - if (ref.isDefined) { - ref.get.cancel(true) - ref = None - } - } - } - - /* - * This extractor is just convenience for matching a (S, S) pair, including a - * reminder what the new state is. - */ - object -> { - def unapply[S](in: (S, S)) = Some(in) - } - - /* - * With these implicits in scope, you can write "5 seconds" anywhere a - * Duration or Option[Duration] is expected. This is conveniently true - * for derived classes. - */ - implicit def d2od(d: Duration): Option[Duration] = Some(d) -} - -/** - * Finite State Machine actor trait. Use as follows: - * - * <pre> - * object A { - * trait State - * case class One extends State - * case class Two extends State - * - * case class Data(i : Int) - * } - * - * class A extends Actor with FSM[A.State, A.Data] { - * import A._ - * - * startWith(One, Data(42)) - * when(One) { - * case Event(SomeMsg, Data(x)) => ... - * case Ev(SomeMsg) => ... // convenience when data not needed - * } - * when(Two, stateTimeout = 5 seconds) { ... } - * initialize - * } - * </pre> - * - * Within the partial function the following values are returned for effecting - * state transitions: - * - * - <code>stay</code> for staying in the same state - * - <code>stay using Data(...)</code> for staying in the same state, but with - * different data - * - <code>stay forMax 5.millis</code> for staying with a state timeout; can be - * combined with <code>using</code> - * - <code>goto(...)</code> for changing into a different state; also supports - * <code>using</code> and <code>forMax</code> - * - <code>stop</code> for terminating this FSM actor - * - * Each of the above also supports the method <code>replying(AnyRef)</code> for - * sending a reply before changing state. - * - * While changing state, custom handlers may be invoked which are registered - * using <code>onTransition</code>. This is meant to enable concentrating - * different concerns in different places; you may choose to use - * <code>when</code> for describing the properties of a state, including of - * course initiating transitions, but you can describe the transitions using - * <code>onTransition</code> to avoid having to duplicate that code among - * multiple paths which lead to a transition: - * - * <pre> - * onTransition { - * case Active -> _ => cancelTimer("activeTimer") - * } - * </pre> - * - * Multiple such blocks are supported and all of them will be called, not only - * the first matching one. - * - * Another feature is that other actors may subscribe for transition events by - * sending a <code>SubscribeTransitionCallback</code> message to this actor; - * use <code>UnsubscribeTransitionCallback</code> before stopping the other - * actor. - * - * State timeouts set an upper bound to the time which may pass before another - * message is received in the current state. If no external message is - * available, then upon expiry of the timeout a StateTimeout message is sent. - * Note that this message will only be received in the state for which the - * timeout was set and that any message received will cancel the timeout - * (possibly to be started again by the next transition). - * - * Another feature is the ability to install and cancel single-shot as well as - * repeated timers which arrange for the sending of a user-specified message: - * - * <pre> - * setTimer("tock", TockMsg, 1 second, true) // repeating - * setTimer("lifetime", TerminateMsg, 1 hour, false) // single-shot - * cancelTimer("tock") - * timerActive_? ("tock") - * </pre> - */ -trait FSM[S, D] extends ListenerManagement { - this: Actor => - - import FSM._ - - type StateFunction = scala.PartialFunction[Event[D], State] - type Timeout = Option[Duration] - type TransitionHandler = PartialFunction[(S, S), Unit] - - /** - * **************************************** - * DSL - * **************************************** - */ - - /** - * Insert a new StateFunction at the end of the processing chain for the - * given state. If the stateTimeout parameter is set, entering this state - * without a differing explicit timeout setting will trigger a StateTimeout - * event; the same is true when using #stay. - * - * @param stateName designator for the state - * @param stateTimeout default state timeout for this state - * @param stateFunction partial function describing response to input - */ - protected final def when(stateName: S, stateTimeout: Timeout = None)(stateFunction: StateFunction) = { - register(stateName, stateFunction, stateTimeout) - } - - /** - * Set initial state. Call this method from the constructor before the #initialize method. - * - * @param stateName initial state designator - * @param stateData initial state data - * @param timeout state timeout for the initial state, overriding the default timeout for that state - */ - protected final def startWith(stateName: S, - stateData: D, - timeout: Timeout = None) = { - currentState = State(stateName, stateData, timeout) - } - - /** - * Produce transition to other state. Return this from a state function in - * order to effect the transition. - * - * @param nextStateName state designator for the next state - * @return state transition descriptor - */ - protected final def goto(nextStateName: S): State = { - State(nextStateName, currentState.stateData) - } - - /** - * Produce "empty" transition descriptor. Return this from a state function - * when no state change is to be effected. - * - * @return descriptor for staying in current state - */ - protected final def stay(): State = { - // cannot directly use currentState because of the timeout field - goto(currentState.stateName) - } - - /** - * Produce change descriptor to stop this FSM actor with reason "Normal". - */ - protected final def stop(): State = { - stop(Normal) - } - - /** - * Produce change descriptor to stop this FSM actor including specified reason. - */ - protected final def stop(reason: Reason): State = { - stop(reason, currentState.stateData) - } - - /** - * Produce change descriptor to stop this FSM actor including specified reason. - */ - protected final def stop(reason: Reason, stateData: D): State = { - stay using stateData withStopReason (reason) - } - - /** - * Schedule named timer to deliver message after given delay, possibly repeating. - * @param name identifier to be used with cancelTimer() - * @param msg message to be delivered - * @param timeout delay of first message delivery and between subsequent messages - * @param repeat send once if false, scheduleAtFixedRate if true - * @return current state descriptor - */ - protected final def setTimer(name: String, msg: AnyRef, timeout: Duration, repeat: Boolean): State = { - if (timers contains name) { - timers(name).cancel - } - val timer = Timer(name, msg, repeat, timerGen.next) - timer.schedule(self, timeout) - timers(name) = timer - stay - } - - /** - * Cancel named timer, ensuring that the message is not subsequently delivered (no race). - * @param name of the timer to cancel - */ - protected final def cancelTimer(name: String) = { - if (timers contains name) { - timers(name).cancel - timers -= name - } - } - - /** - * Inquire whether the named timer is still active. Returns true unless the - * timer does not exist, has previously been canceled or if it was a - * single-shot timer whose message was already received. - */ - protected final def timerActive_?(name: String) = timers contains name - - /** - * Set state timeout explicitly. This method can safely be used from within a - * state handler. - */ - protected final def setStateTimeout(state: S, timeout: Timeout) { - stateTimeouts(state) = timeout - } - - /** - * Set handler which is called upon each state transition, i.e. not when - * staying in the same state. This may use the pair extractor defined in the - * FSM companion object like so: - * - * <pre> - * onTransition { - * case Old -> New => doSomething - * } - * </pre> - * - * It is also possible to supply a 2-ary function object: - * - * <pre> - * onTransition(handler _) - * - * private def handler(from: S, to: S) { ... } - * </pre> - * - * The underscore is unfortunately necessary to enable the nicer syntax shown - * above (it uses the implicit conversion total2pf under the hood). - * - * <b>Multiple handlers may be installed, and every one of them will be - * called, not only the first one matching.</b> - */ - protected final def onTransition(transitionHandler: TransitionHandler) { - transitionEvent :+= transitionHandler - } - - /** - * Convenience wrapper for using a total function instead of a partial - * function literal. To be used with onTransition. - */ - implicit protected final def total2pf(transitionHandler: (S, S) => Unit) = - new PartialFunction[(S, S), Unit] { - def isDefinedAt(in: (S, S)) = true - def apply(in: (S, S)) { transitionHandler(in._1, in._2) } - } - - /** - * Set handler which is called upon termination of this FSM actor. - */ - protected final def onTermination(terminationHandler: PartialFunction[StopEvent[S, D], Unit]) = { - terminateEvent = terminationHandler - } - - /** - * Set handler which is called upon reception of unhandled messages. - */ - protected final def whenUnhandled(stateFunction: StateFunction) = { - handleEvent = stateFunction orElse handleEventDefault - } - - /** - * Verify existence of initial state and setup timers. This should be the - * last call within the constructor. - */ - def initialize { - makeTransition(currentState) - } - - /** - * **************************************************************** - * PRIVATE IMPLEMENTATION DETAILS - * **************************************************************** - */ - - /* - * FSM State data and current timeout handling - */ - private var currentState: State = _ - private var timeoutFuture: Option[ScheduledFuture[AnyRef]] = None - private var generation: Long = 0L - - /* - * Timer handling - */ - private val timers = mutable.Map[String, Timer]() - private val timerGen = Iterator from 0 - - /* - * State definitions - */ - private val stateFunctions = mutable.Map[S, StateFunction]() - private val stateTimeouts = mutable.Map[S, Timeout]() - - private def register(name: S, function: StateFunction, timeout: Timeout) { - if (stateFunctions contains name) { - stateFunctions(name) = stateFunctions(name) orElse function - stateTimeouts(name) = timeout orElse stateTimeouts(name) - } else { - stateFunctions(name) = function - stateTimeouts(name) = timeout - } - } - - /* - * unhandled event handler - */ - private val handleEventDefault: StateFunction = { - case Event(value, stateData) => - stay - } - private var handleEvent: StateFunction = handleEventDefault - - /* - * termination handling - */ - private var terminateEvent: PartialFunction[StopEvent[S, D], Unit] = { - case StopEvent(Failure(cause), _, _) => - case StopEvent(reason, _, _) => - } - - /* - * transition handling - */ - private var transitionEvent: List[TransitionHandler] = Nil - private def handleTransition(prev: S, next: S) { - val tuple = (prev, next) - for (te ← transitionEvent) { if (te.isDefinedAt(tuple)) te(tuple) } - } - - // ListenerManagement shall not start() or stop() listener actors - override protected val manageLifeCycleOfListeners = false - - /** - * ******************************************* - * Main actor receive() method - * ******************************************* - */ - override final protected def receive: Receive = { - case TimeoutMarker(gen) => - if (generation == gen) { - processEvent(StateTimeout) - } - case t@Timer(name, msg, repeat, generation) => - if ((timers contains name) && (timers(name).generation == generation)) { - processEvent(msg) - if (!repeat) { - timers -= name - } - } - case SubscribeTransitionCallBack(actorRef) => - addListener(actorRef) - // send current state back as reference point - try { - actorRef ! CurrentState(self, currentState.stateName) - } catch { - case e: ActorInitializationException => - EventHandler.warning(this, "trying to register not running listener") - } - case UnsubscribeTransitionCallBack(actorRef) => - removeListener(actorRef) - case value => { - if (timeoutFuture.isDefined) { - timeoutFuture.get.cancel(true) - timeoutFuture = None - } - generation += 1 - processEvent(value) - } - } - - private def processEvent(value: Any) = { - val event = Event(value, currentState.stateData) - val stateFunc = stateFunctions(currentState.stateName) - val nextState = if (stateFunc isDefinedAt event) { - stateFunc(event) - } else { - // handleEventDefault ensures that this is always defined - handleEvent(event) - } - nextState.stopReason match { - case Some(reason) => terminate(reason) - case None => makeTransition(nextState) - } - } - - private def makeTransition(nextState: State) = { - if (!stateFunctions.contains(nextState.stateName)) { - terminate(Failure("Next state %s does not exist".format(nextState.stateName))) - } else { - if (currentState.stateName != nextState.stateName) { - handleTransition(currentState.stateName, nextState.stateName) - notifyListeners(Transition(self, currentState.stateName, nextState.stateName)) - } - applyState(nextState) - } - } - - private def applyState(nextState: State) = { - currentState = nextState - val timeout = if (currentState.timeout.isDefined) currentState.timeout else stateTimeouts(currentState.stateName) - if (timeout.isDefined) { - val t = timeout.get - if (t.finite_? && t.length >= 0) { - timeoutFuture = Some(Scheduler.scheduleOnce(self, TimeoutMarker(generation), t.length, t.unit)) - } - } - } - - private def terminate(reason: Reason) = { - terminateEvent.apply(StopEvent(reason, currentState.stateName, currentState.stateData)) - self.stop() - } - - case class Event[D](event: Any, stateData: D) - object Ev { - def unapply[D](e: Event[D]): Option[Any] = Some(e.event) - } - - case class State(stateName: S, stateData: D, timeout: Timeout = None) { - - /** - * Modify state transition descriptor to include a state timeout for the - * next state. This timeout overrides any default timeout set for the next - * state. - */ - def forMax(timeout: Duration): State = { - copy(timeout = Some(timeout)) - } - - /** - * Send reply to sender of the current message, if available. - * - * @return this state transition descriptor - */ - def replying(replyValue: Any): State = { - self.sender match { - case Some(sender) => sender ! replyValue - case None => - } - this - } - - /** - * Modify state transition descriptor with new state data. The data will be - * set when transitioning to the new state. - */ - def using(nextStateDate: D): State = { - copy(stateData = nextStateDate) - } - - private[akka] var stopReason: Option[Reason] = None - - private[akka] def withStopReason(reason: Reason): State = { - stopReason = Some(reason) - this - } - } - - case class StopEvent[S, D](reason: Reason, currentState: S, stateData: D) -} diff --git a/test/files/presentation/akka/src/akka/actor/Scheduler.scala b/test/files/presentation/akka/src/akka/actor/Scheduler.scala deleted file mode 100644 index 128584f3c5..0000000000 --- a/test/files/presentation/akka/src/akka/actor/Scheduler.scala +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2007 WorldWide Conferencing, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Rework of David Pollak's ActorPing class in the Lift Project - * which is licensed under the Apache 2 License. - */ -package akka.actor - -import scala.collection.JavaConversions - -import java.util.concurrent._ - -import akka.event.EventHandler -import akka.AkkaException - -object Scheduler { - import Actor._ - - case class SchedulerException(msg: String, e: Throwable) extends RuntimeException(msg, e) - - @volatile - private var service = Executors.newSingleThreadScheduledExecutor(SchedulerThreadFactory) - - /** - * Schedules to send the specified message to the receiver after initialDelay and then repeated after delay - */ - def schedule(receiver: ActorRef, message: AnyRef, initialDelay: Long, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = { - try { - service.scheduleAtFixedRate( - new Runnable { def run = receiver ! message }, - initialDelay, delay, timeUnit).asInstanceOf[ScheduledFuture[AnyRef]] - } catch { - case e: Exception => - val error = SchedulerException(message + " could not be scheduled on " + receiver, e) - EventHandler.error(error, this, "%s @ %s".format(receiver, message)) - throw error - } - } - - /** - * Schedules to run specified function to the receiver after initialDelay and then repeated after delay, - * avoid blocking operations since this is executed in the schedulers thread - */ - def schedule(f: () => Unit, initialDelay: Long, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = - schedule(new Runnable { def run = f() }, initialDelay, delay, timeUnit) - - /** - * Schedules to run specified runnable to the receiver after initialDelay and then repeated after delay, - * avoid blocking operations since this is executed in the schedulers thread - */ - def schedule(runnable: Runnable, initialDelay: Long, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = { - try { - service.scheduleAtFixedRate(runnable, initialDelay, delay, timeUnit).asInstanceOf[ScheduledFuture[AnyRef]] - } catch { - case e: Exception => - val error = SchedulerException("Failed to schedule a Runnable", e) - EventHandler.error(error, this, error.getMessage) - throw error - } - } - - /** - * Schedules to send the specified message to the receiver after delay - */ - def scheduleOnce(receiver: ActorRef, message: AnyRef, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = { - try { - service.schedule( - new Runnable { def run = receiver ! message }, - delay, timeUnit).asInstanceOf[ScheduledFuture[AnyRef]] - } catch { - case e: Exception => - val error = SchedulerException(message + " could not be scheduleOnce'd on " + receiver, e) - EventHandler.error(e, this, receiver + " @ " + message) - throw error - } - } - - /** - * Schedules a function to be run after delay, - * avoid blocking operations since the runnable is executed in the schedulers thread - */ - def scheduleOnce(f: () => Unit, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = - scheduleOnce(new Runnable { def run = f() }, delay, timeUnit) - - /** - * Schedules a runnable to be run after delay, - * avoid blocking operations since the runnable is executed in the schedulers thread - */ - def scheduleOnce(runnable: Runnable, delay: Long, timeUnit: TimeUnit): ScheduledFuture[AnyRef] = { - try { - service.schedule(runnable, delay, timeUnit).asInstanceOf[ScheduledFuture[AnyRef]] - } catch { - case e: Exception => - val error = SchedulerException("Failed to scheduleOnce a Runnable", e) - EventHandler.error(e, this, error.getMessage) - throw error - } - } - - def shutdown() { - synchronized { - service.shutdown() - } - } - - def restart() { - synchronized { - shutdown() - service = Executors.newSingleThreadScheduledExecutor(SchedulerThreadFactory) - } - } -} - -private object SchedulerThreadFactory extends ThreadFactory { - private var count = 0 - val threadFactory = Executors.defaultThreadFactory() - - def newThread(r: Runnable): Thread = { - val thread = threadFactory.newThread(r) - thread.setName("akka:scheduler-" + count) - thread.setDaemon(true) - thread - } -} diff --git a/test/files/presentation/akka/src/akka/actor/Supervisor.scala b/test/files/presentation/akka/src/akka/actor/Supervisor.scala deleted file mode 100644 index 4a1309faef..0000000000 --- a/test/files/presentation/akka/src/akka/actor/Supervisor.scala +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import akka.AkkaException -import akka.util._ -import ReflectiveAccess._ -import Actor._ - -import java.util.concurrent.{ CopyOnWriteArrayList, ConcurrentHashMap } -import java.net.InetSocketAddress -import akka.config.Supervision._ - -class SupervisorException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) - -/** - * Factory object for creating supervisors declarative. It creates instances of the 'Supervisor' class. - * These are not actors, if you need a supervisor that is an Actor then you have to use the 'SupervisorActor' - * factory object. - * <p/> - * - * Here is a sample on how to use it: - * <pre> - * val supervisor = Supervisor( - * SupervisorConfig( - * RestartStrategy(OneForOne, 3, 10, List(classOf[Exception]), - * Supervise( - * myFirstActor, - * Permanent) :: - * Supervise( - * mySecondActor, - * Permanent) :: - * Nil)) - * </pre> - * - * You dynamically link and unlink child children using the 'link' and 'unlink' methods. - * <pre> - * supervisor.link(child) - * supervisor.unlink(child) - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Supervisor { - def apply(config: SupervisorConfig): Supervisor = SupervisorFactory(config).newInstance.start -} - -/** - * Use this factory instead of the Supervisor factory object if you want to control - * instantiation and starting of the Supervisor, if not then it is easier and better - * to use the Supervisor factory object. - * <p> - * Example usage: - * <pre> - * val factory = SupervisorFactory( - * SupervisorConfig( - * RestartStrategy(OneForOne, 3, 10, List(classOf[Exception]), - * Supervise( - * myFirstActor, - * Permanent) :: - * Supervise( - * mySecondActor, - * Permanent) :: - * Nil)) - * </pre> - * - * Then create a new Supervisor tree with the concrete Services we have defined. - * - * <pre> - * val supervisor = factory.newInstance - * supervisor.start // start up all managed servers - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -case class SupervisorFactory(val config: SupervisorConfig) { - - def newInstance: Supervisor = newInstanceFor(config) - - def newInstanceFor(config: SupervisorConfig): Supervisor = { - val supervisor = new Supervisor(config.restartStrategy, config.maxRestartsHandler) - supervisor.configure(config) - supervisor.start - supervisor - } -} - -/** - * <b>NOTE:</b> - * <p/> - * The supervisor class is only used for the configuration system when configuring supervisor - * hierarchies declaratively. Should not be used as part of the regular programming API. Instead - * wire the children together using 'link', 'spawnLink' etc. and set the 'trapExit' flag in the - * children that should trap error signals and trigger restart. - * <p/> - * See the ScalaDoc for the SupervisorFactory for an example on how to declaratively wire up children. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -sealed class Supervisor(handler: FaultHandlingStrategy, maxRestartsHandler: (ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached) => Unit) { - import Supervisor._ - - private val _childActors = new ConcurrentHashMap[String, List[ActorRef]] - private val _childSupervisors = new CopyOnWriteArrayList[Supervisor] - - private[akka] val supervisor = actorOf(new SupervisorActor(handler, maxRestartsHandler)).start() - - def uuid = supervisor.uuid - - def start: Supervisor = { - this - } - - def shutdown(): Unit = supervisor.stop() - - def link(child: ActorRef) = supervisor.link(child) - - def unlink(child: ActorRef) = supervisor.unlink(child) - - def children: List[ActorRef] = - _childActors.values.toArray.toList.asInstanceOf[List[List[ActorRef]]].flatten - - def childSupervisors: List[Supervisor] = - _childActors.values.toArray.toList.asInstanceOf[List[Supervisor]] - - def configure(config: SupervisorConfig): Unit = config match { - case SupervisorConfig(_, servers, _) => - - servers.map(server => - server match { - case Supervise(actorRef, lifeCycle, registerAsRemoteService) => - actorRef.start() - val className = actorRef.actor.getClass.getName - val currentActors = { - val list = _childActors.get(className) - if (list eq null) List[ActorRef]() - else list - } - _childActors.put(className, actorRef :: currentActors) - actorRef.lifeCycle = lifeCycle - supervisor.link(actorRef) - if (registerAsRemoteService) - Actor.remote.register(actorRef) - case supervisorConfig@SupervisorConfig(_, _, _) => // recursive supervisor configuration - val childSupervisor = Supervisor(supervisorConfig) - supervisor.link(childSupervisor.supervisor) - _childSupervisors.add(childSupervisor) - }) - } -} - -/** - * For internal use only. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -final class SupervisorActor private[akka] (handler: FaultHandlingStrategy, maxRestartsHandler: (ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached) => Unit) extends Actor { - self.faultHandler = handler - - override def postStop(): Unit = { - val i = self.linkedActors.values.iterator - while (i.hasNext) { - val ref = i.next - ref.stop() - self.unlink(ref) - } - } - - def receive = { - case max@MaximumNumberOfRestartsWithinTimeRangeReached(_, _, _, _) => maxRestartsHandler(self, max) - case unknown => throw new SupervisorException( - "SupervisorActor can not respond to messages.\n\tUnknown message [" + unknown + "]") - } -} diff --git a/test/files/presentation/akka/src/akka/actor/UntypedActor.scala b/test/files/presentation/akka/src/akka/actor/UntypedActor.scala deleted file mode 100644 index cbc43f22f8..0000000000 --- a/test/files/presentation/akka/src/akka/actor/UntypedActor.scala +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.actor - -import akka.japi.{ Creator, Procedure } - -/** - * Subclass this abstract class to create a MDB-style untyped actor. - * <p/> - * This class is meant to be used from Java. - * <p/> - * Here is an example on how to create and use an UntypedActor: - * <pre> - * public class SampleUntypedActor extends UntypedActor { - * public void onReceive(Object message) throws Exception { - * if (message instanceof String) { - * String msg = (String)message; - * - * if (msg.equals("UseReply")) { - * // Reply to original sender of message using the 'replyUnsafe' method - * getContext().replyUnsafe(msg + ":" + getContext().getUuid()); - * - * } else if (msg.equals("UseSender") && getContext().getSender().isDefined()) { - * // Reply to original sender of message using the sender reference - * // also passing along my own reference (the context) - * getContext().getSender().get().sendOneWay(msg, context); - * - * } else if (msg.equals("UseSenderFuture") && getContext().getSenderFuture().isDefined()) { - * // Reply to original sender of message using the sender future reference - * getContext().getSenderFuture().get().completeWithResult(msg); - * - * } else if (msg.equals("SendToSelf")) { - * // Send message to the actor itself recursively - * getContext().sendOneWay(msg) - * - * } else if (msg.equals("ForwardMessage")) { - * // Retrieve an actor from the ActorRegistry by ID and get an ActorRef back - * ActorRef actorRef = Actor.registry.actorsFor("some-actor-id").head(); - * - * } else throw new IllegalArgumentException("Unknown message: " + message); - * } else throw new IllegalArgumentException("Unknown message: " + message); - * } - * - * public static void main(String[] args) { - * ActorRef actor = Actors.actorOf(SampleUntypedActor.class); - * actor.start(); - * actor.sendOneWay("SendToSelf"); - * actor.stop(); - * } - * } - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -abstract class UntypedActor extends Actor { - - /** - * To be implemented by concrete UntypedActor. Defines the message handler. - */ - @throws(classOf[Exception]) - def onReceive(message: Any): Unit - - /** - * Returns the 'self' reference with the API. - */ - def getContext(): ActorRef = self - - /** - * Returns the 'self' reference with the API. - */ - def context(): ActorRef = self - - /** - * Java API for become - */ - def become(behavior: Procedure[Any]): Unit = become(behavior, false) - - /* - * Java API for become with optional discardOld - */ - def become(behavior: Procedure[Any], discardOld: Boolean): Unit = - super.become({ case msg => behavior.apply(msg) }, discardOld) - - /** - * User overridable callback. - * <p/> - * Is called when an Actor is started by invoking 'actor.start()'. - */ - override def preStart() {} - - /** - * User overridable callback. - * <p/> - * Is called when 'actor.stop()' is invoked. - */ - override def postStop() {} - - /** - * User overridable callback. - * <p/> - * Is called on a crashed Actor right BEFORE it is restarted to allow clean up of resources before Actor is terminated. - */ - override def preRestart(reason: Throwable) {} - - /** - * User overridable callback. - * <p/> - * Is called right AFTER restart on the newly created Actor to allow reinitialization after an Actor crash. - */ - override def postRestart(reason: Throwable) {} - - /** - * User overridable callback. - * <p/> - * Is called when a message isn't handled by the current behavior of the actor - * by default it throws an UnhandledMessageException - */ - override def unhandled(msg: Any) { - throw new UnhandledMessageException(msg, self) - } - - final protected def receive = { - case msg => onReceive(msg) - } -} - -/** - * Factory closure for an UntypedActor, to be used with 'Actors.actorOf(factory)'. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait UntypedActorFactory extends Creator[Actor] diff --git a/test/files/presentation/akka/src/akka/actor/package.scala b/test/files/presentation/akka/src/akka/actor/package.scala deleted file mode 100644 index fbeeed49cb..0000000000 --- a/test/files/presentation/akka/src/akka/actor/package.scala +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka - -import actor.{ ScalaActorRef, ActorRef } - -package object actor { - implicit def actorRef2Scala(ref: ActorRef): ScalaActorRef = - ref.asInstanceOf[ScalaActorRef] - - implicit def scala2ActorRef(ref: ScalaActorRef): ActorRef = - ref.asInstanceOf[ActorRef] - - type Uuid = com.eaio.uuid.UUID - - def newUuid(): Uuid = new Uuid() - - def uuidFrom(time: Long, clockSeqAndNode: Long): Uuid = new Uuid(time, clockSeqAndNode) - - def uuidFrom(uuid: String): Uuid = new Uuid(uuid) -} diff --git a/test/files/presentation/akka/src/akka/config/Config.scala b/test/files/presentation/akka/src/akka/config/Config.scala deleted file mode 100644 index 6578c66f77..0000000000 --- a/test/files/presentation/akka/src/akka/config/Config.scala +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.config - -import akka.AkkaException - -class ConfigurationException(message: String, cause: Throwable = null) extends AkkaException(message, cause) -class ModuleNotAvailableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) - -/** - * Loads up the configuration (from the akka.conf file). - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Config { - val VERSION = "1.1.3" - - val HOME = { - val envHome = System.getenv("AKKA_HOME") match { - case null | "" | "." => None - case value => Some(value) - } - - val systemHome = System.getProperty("akka.home") match { - case null | "" => None - case value => Some(value) - } - - envHome orElse systemHome - } - - val config: Configuration = try { - val confName = { - val envConf = System.getenv("AKKA_MODE") match { - case null | "" => None - case value => Some(value) - } - - val systemConf = System.getProperty("akka.mode") match { - case null | "" => None - case value => Some(value) - } - - (envConf orElse systemConf).map("akka." + _ + ".conf").getOrElse("akka.conf") - } - - val newInstance = - if (System.getProperty("akka.config", "") != "") { - val configFile = System.getProperty("akka.config", "") - println("Loading config from -Dakka.config=" + configFile) - Configuration.fromFile(configFile) - } else if (getClass.getClassLoader.getResource(confName) ne null) { - println("Loading config [" + confName + "] from the application classpath.") - Configuration.fromResource(confName, getClass.getClassLoader) - } else if (HOME.isDefined) { - val configFile = HOME.get + "/config/" + confName - println("AKKA_HOME is defined as [" + HOME.get + "], loading config from [" + configFile + "].") - Configuration.fromFile(configFile) - } else { - println( - "\nCan't load '" + confName + "'." + - "\nOne of the three ways of locating the '" + confName + "' file needs to be defined:" + - "\n\t1. Define the '-Dakka.config=...' system property option." + - "\n\t2. Put the '" + confName + "' file on the classpath." + - "\n\t3. Define 'AKKA_HOME' environment variable pointing to the root of the Akka distribution." + - "\nI have no way of finding the '" + confName + "' configuration file." + - "\nUsing default values everywhere.") - Configuration.fromString("akka {}") // default empty config - } - - val configVersion = newInstance.getString("akka.version", VERSION) - if (configVersion != VERSION) - throw new ConfigurationException( - "Akka JAR version [" + VERSION + "] is different than the provided config version [" + configVersion + "]") - - newInstance - } catch { - case e => - System.err.println("Couldn't parse config, fatal error.") - e.printStackTrace(System.err) - System.exit(-1) - throw e - } - - val CONFIG_VERSION = config.getString("akka.version", VERSION) - - val TIME_UNIT = config.getString("akka.time-unit", "seconds") - - val startTime = System.currentTimeMillis - def uptime = (System.currentTimeMillis - startTime) / 1000 -} diff --git a/test/files/presentation/akka/src/akka/config/ConfigParser.scala b/test/files/presentation/akka/src/akka/config/ConfigParser.scala deleted file mode 100644 index 73fac5e31b..0000000000 --- a/test/files/presentation/akka/src/akka/config/ConfigParser.scala +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - * - * Based on Configgy by Robey Pointer. - * Copyright 2009 Robey Pointer <robeypointer@gmail.com> - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -package akka.config - -import scala.collection.mutable -import scala.util.parsing.combinator._ - -class ConfigParser(var prefix: String = "", map: mutable.Map[String, Any] = mutable.Map.empty[String, Any], importer: Importer) extends RegexParsers { - val sections = mutable.Stack[String]() - - def createPrefix = { - prefix = if (sections.isEmpty) "" else sections.toList.reverse.mkString("", ".", ".") - } - - override val whiteSpace = """(\s+|#[^\n]*\n)+""".r - - // tokens - - val numberToken: Parser[String] = """-?\d+(\.\d+)?""".r - val stringToken: Parser[String] = ("\"" + """([^\\\"]|\\[^ux]|\\\n|\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2})*""" + "\"").r - val booleanToken: Parser[String] = "(true|on|false|off)".r - val identToken: Parser[String] = """([\da-zA-Z_][-\w]*)(\.[a-zA-Z_][-\w]*)*""".r - val assignToken: Parser[String] = "=".r - val sectionToken: Parser[String] = """[a-zA-Z][-\w]*""".r - - // values - - def value: Parser[Any] = number | string | list | boolean - def number = numberToken - def string = stringToken ^^ { s => s.substring(1, s.length - 1) } - def list = "[" ~> repsep(string | numberToken, opt(",")) <~ (opt(",") ~ "]") - def boolean = booleanToken - - // parser - - def root = rep(includeFile | assignment | sectionOpen | sectionClose) - - def includeFile = "include" ~> string ^^ { - case filename: String => - new ConfigParser(prefix, map, importer) parse importer.importFile(filename) - } - - def assignment = identToken ~ assignToken ~ value ^^ { - case k ~ a ~ v => map(prefix + k) = v - } - - def sectionOpen = sectionToken <~ "{" ^^ { name => - sections push name - createPrefix - } - - def sectionClose = "}" ^^ { _ => - if (sections.isEmpty) { - failure("dangling close tag") - } else { - sections.pop - createPrefix - } - } - - def parse(in: String): Map[String, Any] = { - parseAll(root, in) match { - case Success(result, _) => map.toMap - case x@Failure(msg, _) => throw new ConfigurationException(x.toString) - case x@Error(msg, _) => throw new ConfigurationException(x.toString) - } - } -} diff --git a/test/files/presentation/akka/src/akka/config/Configuration.scala b/test/files/presentation/akka/src/akka/config/Configuration.scala deleted file mode 100644 index 81c32fce90..0000000000 --- a/test/files/presentation/akka/src/akka/config/Configuration.scala +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - * - * Based on Configgy by Robey Pointer. - * Copyright 2009 Robey Pointer <robeypointer@gmail.com> - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -package akka.config - -import java.io.File - -object Configuration { - val DefaultPath = new File(".").getCanonicalPath - val DefaultImporter = new FilesystemImporter(DefaultPath) - - def load(data: String, importer: Importer = DefaultImporter): Configuration = { - val parser = new ConfigParser(importer = importer) - new Configuration(parser parse data) - } - - def fromFile(filename: String, importer: Importer): Configuration = { - load(importer.importFile(filename), importer) - } - - def fromFile(path: String, filename: String): Configuration = { - val importer = new FilesystemImporter(path) - fromFile(filename, importer) - } - - def fromFile(filename: String): Configuration = { - val n = filename.lastIndexOf('/') - if (n < 0) { - fromFile(DefaultPath, filename) - } else { - fromFile(filename.substring(0, n), filename.substring(n + 1)) - } - } - - def fromResource(filename: String): Configuration = { - fromResource(filename, ClassLoader.getSystemClassLoader) - } - - def fromResource(filename: String, classLoader: ClassLoader): Configuration = { - val importer = new ResourceImporter(classLoader) - fromFile(filename, importer) - } - - def fromMap(map: Map[String, Any]) = { - new Configuration(map) - } - - def fromString(data: String): Configuration = { - load(data) - } -} - -class Configuration(val map: Map[String, Any]) { - private val trueValues = Set("true", "on") - private val falseValues = Set("false", "off") - - def contains(key: String): Boolean = map contains key - - def keys: Iterable[String] = map.keys - - def getAny(key: String): Option[Any] = { - try { - Some(map(key)) - } catch { - case _ => None - } - } - - def getAny(key: String, defaultValue: Any): Any = getAny(key).getOrElse(defaultValue) - - def getSeqAny(key: String): Seq[Any] = { - try { - map(key).asInstanceOf[Seq[Any]] - } catch { - case _ => Seq.empty[Any] - } - } - - def getString(key: String): Option[String] = map.get(key).map(_.toString) - - def getString(key: String, defaultValue: String): String = getString(key).getOrElse(defaultValue) - - def getList(key: String): Seq[String] = { - try { - map(key).asInstanceOf[Seq[String]] - } catch { - case _ => Seq.empty[String] - } - } - - def getInt(key: String): Option[Int] = { - try { - Some(map(key).toString.toInt) - } catch { - case _ => None - } - } - - def getInt(key: String, defaultValue: Int): Int = getInt(key).getOrElse(defaultValue) - - def getLong(key: String): Option[Long] = { - try { - Some(map(key).toString.toLong) - } catch { - case _ => None - } - } - - def getLong(key: String, defaultValue: Long): Long = getLong(key).getOrElse(defaultValue) - - def getFloat(key: String): Option[Float] = { - try { - Some(map(key).toString.toFloat) - } catch { - case _ => None - } - } - - def getFloat(key: String, defaultValue: Float): Float = getFloat(key).getOrElse(defaultValue) - - def getDouble(key: String): Option[Double] = { - try { - Some(map(key).toString.toDouble) - } catch { - case _ => None - } - } - - def getDouble(key: String, defaultValue: Double): Double = getDouble(key).getOrElse(defaultValue) - - def getBoolean(key: String): Option[Boolean] = { - getString(key) flatMap { s => - val isTrue = trueValues.contains(s) - if (!isTrue && !falseValues.contains(s)) None - else Some(isTrue) - } - } - - def getBoolean(key: String, defaultValue: Boolean): Boolean = getBool(key).getOrElse(defaultValue) - - def getBool(key: String): Option[Boolean] = getBoolean(key) - - def getBool(key: String, defaultValue: Boolean): Boolean = getBoolean(key, defaultValue) - - def apply(key: String): String = getString(key) match { - case None => throw new ConfigurationException("undefined config: " + key) - case Some(v) => v - } - - def apply(key: String, defaultValue: String) = getString(key, defaultValue) - def apply(key: String, defaultValue: Int) = getInt(key, defaultValue) - def apply(key: String, defaultValue: Long) = getLong(key, defaultValue) - def apply(key: String, defaultValue: Boolean) = getBool(key, defaultValue) - - def getSection(name: String): Option[Configuration] = { - val l = name.length + 1 - val m = map.collect { case (k, v) if k.startsWith(name) => (k.substring(l), v) } - if (m.isEmpty) None - else Some(new Configuration(m)) - } -} diff --git a/test/files/presentation/akka/src/akka/config/Configurator.scala b/test/files/presentation/akka/src/akka/config/Configurator.scala deleted file mode 100644 index 2818339b0f..0000000000 --- a/test/files/presentation/akka/src/akka/config/Configurator.scala +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.config - -import akka.config.Supervision.{ SuperviseTypedActor, FaultHandlingStrategy } - -private[akka] trait TypedActorConfiguratorBase { - def getExternalDependency[T](clazz: Class[T]): T - - def configure(restartStrategy: FaultHandlingStrategy, components: List[SuperviseTypedActor]): TypedActorConfiguratorBase - - def inject: TypedActorConfiguratorBase - - def supervise: TypedActorConfiguratorBase - - def reset - - def stop -} diff --git a/test/files/presentation/akka/src/akka/config/Importer.scala b/test/files/presentation/akka/src/akka/config/Importer.scala deleted file mode 100644 index eebda1d4fe..0000000000 --- a/test/files/presentation/akka/src/akka/config/Importer.scala +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - * - * Based on Configgy by Robey Pointer. - * Copyright 2009 Robey Pointer <robeypointer@gmail.com> - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -package akka.config - -import java.io.{ BufferedReader, File, FileInputStream, InputStream, InputStreamReader } - -/** - * An interface for finding config files and reading them into strings for - * parsing. This is used to handle `include` directives in config files. - */ -trait Importer { - - def importFile(filename: String): String - - private val BUFFER_SIZE = 8192 - - protected def streamToString(in: InputStream): String = { - try { - val reader = new BufferedReader(new InputStreamReader(in, "UTF-8")) - val buffer = new Array[Char](BUFFER_SIZE) - val sb = new StringBuilder - var n = 0 - while (n >= 0) { - n = reader.read(buffer, 0, buffer.length) - if (n >= 0) { - sb.appendAll(buffer, 0, n) - } - } - in.close() - sb.toString - } catch { - case x => throw new ConfigurationException(x.toString) - } - } -} - -/** - * An Importer that looks for imported config files in the filesystem. - * This is the default importer. - */ -class FilesystemImporter(val baseDir: String) extends Importer { - def importFile(filename: String): String = { - val f = new File(filename) - val file = if (f.isAbsolute) f else new File(baseDir, filename) - streamToString(new FileInputStream(file)) - } -} - -/** - * An Importer that looks for imported config files in the java resources - * of the system class loader (usually the jar used to launch this app). - */ -class ResourceImporter(classLoader: ClassLoader) extends Importer { - def importFile(filename: String): String = { - val stream = classLoader.getResourceAsStream(filename) - streamToString(stream) - } -} diff --git a/test/files/presentation/akka/src/akka/config/SupervisionConfig.scala b/test/files/presentation/akka/src/akka/config/SupervisionConfig.scala deleted file mode 100644 index 40f61f615f..0000000000 --- a/test/files/presentation/akka/src/akka/config/SupervisionConfig.scala +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.config - -import akka.dispatch.MessageDispatcher -import akka.actor.{ MaximumNumberOfRestartsWithinTimeRangeReached, ActorRef } -import akka.japi.{ Procedure2, Procedure } - -case class RemoteAddress(val hostname: String, val port: Int) - -/** - * Configuration classes - not to be used as messages. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Supervision { - sealed abstract class ConfigElement - - abstract class Server extends ConfigElement - sealed abstract class LifeCycle extends ConfigElement - sealed abstract class FaultHandlingStrategy(val trapExit: List[Class[_ <: Throwable]]) extends ConfigElement - - case class SupervisorConfig(restartStrategy: FaultHandlingStrategy, worker: List[Server], maxRestartsHandler: (ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached) => Unit = { (aRef, max) => () }) extends Server { - //Java API - def this(restartStrategy: FaultHandlingStrategy, worker: Array[Server]) = this(restartStrategy, worker.toList) - def this(restartStrategy: FaultHandlingStrategy, worker: Array[Server], restartHandler: Procedure2[ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached]) = this(restartStrategy, worker.toList, { (aRef, max) => restartHandler.apply(aRef, max) }) - } - - class Supervise(val actorRef: ActorRef, val lifeCycle: LifeCycle, val registerAsRemoteService: Boolean = false) extends Server { - //Java API - def this(actorRef: ActorRef, lifeCycle: LifeCycle) = - this(actorRef, lifeCycle, false) - } - - object Supervise { - def apply(actorRef: ActorRef, lifeCycle: LifeCycle, registerAsRemoteService: Boolean = false) = new Supervise(actorRef, lifeCycle, registerAsRemoteService) - def apply(actorRef: ActorRef, lifeCycle: LifeCycle) = new Supervise(actorRef, lifeCycle, false) - def unapply(supervise: Supervise) = Some((supervise.actorRef, supervise.lifeCycle, supervise.registerAsRemoteService)) - } - - object AllForOneStrategy { - def apply(trapExit: List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int): AllForOneStrategy = - new AllForOneStrategy(trapExit, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - } - - case class AllForOneStrategy(override val trapExit: List[Class[_ <: Throwable]], - maxNrOfRetries: Option[Int] = None, - withinTimeRange: Option[Int] = None) extends FaultHandlingStrategy(trapExit) { - def this(trapExit: List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - - def this(trapExit: Array[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit.toList, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - - def this(trapExit: java.util.List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit.toArray.toList.asInstanceOf[List[Class[_ <: Throwable]]], - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - } - - object OneForOneStrategy { - def apply(trapExit: List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int): OneForOneStrategy = - new OneForOneStrategy(trapExit, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - } - - case class OneForOneStrategy(override val trapExit: List[Class[_ <: Throwable]], - maxNrOfRetries: Option[Int] = None, - withinTimeRange: Option[Int] = None) extends FaultHandlingStrategy(trapExit) { - def this(trapExit: List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - - def this(trapExit: Array[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit.toList, - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - - def this(trapExit: java.util.List[Class[_ <: Throwable]], maxNrOfRetries: Int, withinTimeRange: Int) = - this(trapExit.toArray.toList.asInstanceOf[List[Class[_ <: Throwable]]], - if (maxNrOfRetries < 0) None else Some(maxNrOfRetries), if (withinTimeRange < 0) None else Some(withinTimeRange)) - } - - case object NoFaultHandlingStrategy extends FaultHandlingStrategy(Nil) - - //Scala API - case object Permanent extends LifeCycle - case object Temporary extends LifeCycle - case object UndefinedLifeCycle extends LifeCycle - - //Java API (& Scala if you fancy) - def permanent(): LifeCycle = Permanent - def temporary(): LifeCycle = Temporary - def undefinedLifeCycle(): LifeCycle = UndefinedLifeCycle - - //Java API - def noFaultHandlingStrategy = NoFaultHandlingStrategy - - case class SuperviseTypedActor(_intf: Class[_], - val target: Class[_], - val lifeCycle: LifeCycle, - val timeout: Long, - _dispatcher: MessageDispatcher, // optional - _remoteAddress: RemoteAddress // optional - ) extends Server { - val intf: Option[Class[_]] = Option(_intf) - val dispatcher: Option[MessageDispatcher] = Option(_dispatcher) - val remoteAddress: Option[RemoteAddress] = Option(_remoteAddress) - - def this(target: Class[_], lifeCycle: LifeCycle, timeout: Long) = - this(null: Class[_], target, lifeCycle, timeout, null: MessageDispatcher, null: RemoteAddress) - - def this(intf: Class[_], target: Class[_], lifeCycle: LifeCycle, timeout: Long) = - this(intf, target, lifeCycle, timeout, null: MessageDispatcher, null: RemoteAddress) - - def this(intf: Class[_], target: Class[_], lifeCycle: LifeCycle, timeout: Long, dispatcher: MessageDispatcher) = - this(intf, target, lifeCycle, timeout, dispatcher, null: RemoteAddress) - - def this(target: Class[_], lifeCycle: LifeCycle, timeout: Long, dispatcher: MessageDispatcher) = - this(null: Class[_], target, lifeCycle, timeout, dispatcher, null: RemoteAddress) - - def this(intf: Class[_], target: Class[_], lifeCycle: LifeCycle, timeout: Long, remoteAddress: RemoteAddress) = - this(intf, target, lifeCycle, timeout, null: MessageDispatcher, remoteAddress) - - def this(target: Class[_], lifeCycle: LifeCycle, timeout: Long, remoteAddress: RemoteAddress) = - this(null: Class[_], target, lifeCycle, timeout, null: MessageDispatcher, remoteAddress) - - def this(target: Class[_], lifeCycle: LifeCycle, timeout: Long, dispatcher: MessageDispatcher, remoteAddress: RemoteAddress) = - this(null: Class[_], target, lifeCycle, timeout, dispatcher, remoteAddress) - } -} diff --git a/test/files/presentation/akka/src/akka/dataflow/DataFlow.scala b/test/files/presentation/akka/src/akka/dataflow/DataFlow.scala deleted file mode 100644 index bca7936116..0000000000 --- a/test/files/presentation/akka/src/akka/dataflow/DataFlow.scala +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dataflow - -import java.util.concurrent.atomic.AtomicReference -import java.util.concurrent.{ ConcurrentLinkedQueue, LinkedBlockingQueue } - -import akka.event.EventHandler -import akka.actor.{ Actor, ActorRef } -import akka.actor.Actor._ -import akka.dispatch.CompletableFuture -import akka.AkkaException -import akka.japi.{ Function, Effect } - -/** - * Implements Oz-style dataflow (single assignment) variables. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object DataFlow { - object Start - object Exit - - class DataFlowVariableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) - - /** - * Executes the supplied thunk in another thread. - */ - def thread(body: => Unit): Unit = spawn(body) - - /** - * JavaAPI. - * Executes the supplied Effect in another thread. - */ - def thread(body: Effect): Unit = spawn(body.apply) - - /** - * Executes the supplied function in another thread. - */ - def thread[A <: AnyRef, R <: AnyRef](body: A => R) = - actorOf(new ReactiveEventBasedThread(body)).start() - - /** - * JavaAPI. - * Executes the supplied Function in another thread. - */ - def thread[A <: AnyRef, R <: AnyRef](body: Function[A, R]) = - actorOf(new ReactiveEventBasedThread(body.apply)).start() - - private class ReactiveEventBasedThread[A <: AnyRef, T <: AnyRef](body: A => T) - extends Actor { - def receive = { - case Exit => self.stop() - case message => self.reply(body(message.asInstanceOf[A])) - } - } - - private object DataFlowVariable { - private sealed abstract class DataFlowVariableMessage - private case class Set[T <: Any](value: T) extends DataFlowVariableMessage - private object Get extends DataFlowVariableMessage - } - - /** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ - @deprecated("Superceeded by Future and CompletableFuture as of 1.1", "1.1") - sealed class DataFlowVariable[T <: Any](timeoutMs: Long) { - import DataFlowVariable._ - - def this() = this(1000 * 60) - - private val value = new AtomicReference[Option[T]](None) - private val blockedReaders = new ConcurrentLinkedQueue[ActorRef] - - private class In[T <: Any](dataFlow: DataFlowVariable[T]) extends Actor { - self.timeout = timeoutMs - def receive = { - case s@Set(v) => - if (dataFlow.value.compareAndSet(None, Some(v.asInstanceOf[T]))) { - while (dataFlow.blockedReaders.peek ne null) - dataFlow.blockedReaders.poll ! s - } else throw new DataFlowVariableException( - "Attempt to change data flow variable (from [" + dataFlow.value.get + "] to [" + v + "])") - case Exit => self.stop() - } - } - - private class Out[T <: Any](dataFlow: DataFlowVariable[T]) extends Actor { - self.timeout = timeoutMs - private var readerFuture: Option[CompletableFuture[Any]] = None - def receive = { - case Get => dataFlow.value.get match { - case Some(value) => self reply value - case None => readerFuture = self.senderFuture - } - case Set(v: T) => readerFuture.map(_ completeWithResult v) - case Exit => self.stop() - } - } - - private[this] val in = actorOf(new In(this)).start() - - /** - * Sets the value of this variable (if unset) with the value of the supplied variable. - */ - def <<(ref: DataFlowVariable[T]) { - if (this.value.get.isEmpty) in ! Set(ref()) - else throw new DataFlowVariableException( - "Attempt to change data flow variable (from [" + this.value.get + "] to [" + ref() + "])") - } - - /** - * JavaAPI. - * Sets the value of this variable (if unset) with the value of the supplied variable. - */ - def set(ref: DataFlowVariable[T]) { this << ref } - - /** - * Sets the value of this variable (if unset). - */ - def <<(value: T) { - if (this.value.get.isEmpty) in ! Set(value) - else throw new DataFlowVariableException( - "Attempt to change data flow variable (from [" + this.value.get + "] to [" + value + "])") - } - - /** - * JavaAPI. - * Sets the value of this variable (if unset) with the value of the supplied variable. - */ - def set(value: T) { this << value } - - /** - * Retrieves the value of variable, throws a DataFlowVariableException if it times out. - */ - def get(): T = this() - - /** - * Retrieves the value of variable, throws a DataFlowVariableException if it times out. - */ - def apply(): T = { - value.get getOrElse { - val out = actorOf(new Out(this)).start() - - val result = try { - blockedReaders offer out - (out !! Get).as[T] - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - out ! Exit - throw e - } - - result.getOrElse(throw new DataFlowVariableException( - "Timed out (after " + timeoutMs + " milliseconds) while waiting for result")) - } - } - - def shutdown() { in ! Exit } - } -} diff --git a/test/files/presentation/akka/src/akka/dispatch/Dispatchers.scala b/test/files/presentation/akka/src/akka/dispatch/Dispatchers.scala deleted file mode 100644 index 7dd1bf6218..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/Dispatchers.scala +++ /dev/null @@ -1,227 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.actor.{ Actor, ActorRef } -import akka.actor.newUuid -import akka.config.Config._ -import akka.util.{ Duration, ReflectiveAccess } - -import akka.config.Configuration - -import java.util.concurrent.TimeUnit - -/** - * Scala API. Dispatcher factory. - * <p/> - * Example usage: - * <pre/> - * val dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("name") - * dispatcher - * .withNewThreadPoolWithLinkedBlockingQueueWithCapacity(100) - * .setCorePoolSize(16) - * .setMaxPoolSize(128) - * .setKeepAliveTimeInMillis(60000) - * .setRejectionPolicy(new CallerRunsPolicy) - * .build - * </pre> - * <p/> - * Java API. Dispatcher factory. - * <p/> - * Example usage: - * <pre/> - * MessageDispatcher dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("name"); - * dispatcher - * .withNewThreadPoolWithLinkedBlockingQueueWithCapacity(100) - * .setCorePoolSize(16) - * .setMaxPoolSize(128) - * .setKeepAliveTimeInMillis(60000) - * .setRejectionPolicy(new CallerRunsPolicy()) - * .build(); - * </pre> - * <p/> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Dispatchers { - val THROUGHPUT = config.getInt("akka.actor.throughput", 5) - val DEFAULT_SHUTDOWN_TIMEOUT = config.getLong("akka.actor.dispatcher-shutdown-timeout"). - map(time => Duration(time, TIME_UNIT)). - getOrElse(Duration(1000, TimeUnit.MILLISECONDS)) - val MAILBOX_CAPACITY = config.getInt("akka.actor.default-dispatcher.mailbox-capacity", -1) - val MAILBOX_PUSH_TIME_OUT = Duration(config.getInt("akka.actor.default-dispatcher.mailbox-push-timeout-time", 10), TIME_UNIT) - val THROUGHPUT_DEADLINE_TIME = Duration(config.getInt("akka.actor.throughput-deadline-time", -1), TIME_UNIT) - val THROUGHPUT_DEADLINE_TIME_MILLIS = THROUGHPUT_DEADLINE_TIME.toMillis.toInt - val MAILBOX_TYPE: MailboxType = if (MAILBOX_CAPACITY < 1) UnboundedMailbox() else BoundedMailbox() - - lazy val defaultGlobalDispatcher = { - config.getSection("akka.actor.default-dispatcher").flatMap(from).getOrElse(globalExecutorBasedEventDrivenDispatcher) - } - - object globalExecutorBasedEventDrivenDispatcher extends ExecutorBasedEventDrivenDispatcher("global", THROUGHPUT, THROUGHPUT_DEADLINE_TIME_MILLIS, MAILBOX_TYPE) - - /** - * Creates an thread based dispatcher serving a single actor through the same single thread. - * Uses the default timeout - * <p/> - * E.g. each actor consumes its own thread. - */ - def newThreadBasedDispatcher(actor: ActorRef) = new ThreadBasedDispatcher(actor) - - /** - * Creates an thread based dispatcher serving a single actor through the same single thread. - * Uses the default timeout - * If capacity is negative, it's Integer.MAX_VALUE - * <p/> - * E.g. each actor consumes its own thread. - */ - def newThreadBasedDispatcher(actor: ActorRef, mailboxCapacity: Int) = new ThreadBasedDispatcher(actor, mailboxCapacity) - - /** - * Creates an thread based dispatcher serving a single actor through the same single thread. - * If capacity is negative, it's Integer.MAX_VALUE - * <p/> - * E.g. each actor consumes its own thread. - */ - def newThreadBasedDispatcher(actor: ActorRef, mailboxCapacity: Int, pushTimeOut: Duration) = - new ThreadBasedDispatcher(actor, mailboxCapacity, pushTimeOut) - - /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenDispatcher(name: String) = - ThreadPoolConfigDispatcherBuilder(config => new ExecutorBasedEventDrivenDispatcher(name, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenDispatcher(name: String, throughput: Int, mailboxType: MailboxType) = - ThreadPoolConfigDispatcherBuilder(config => - new ExecutorBasedEventDrivenDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenDispatcher(name: String, throughput: Int, throughputDeadlineMs: Int, mailboxType: MailboxType) = - ThreadPoolConfigDispatcherBuilder(config => - new ExecutorBasedEventDrivenDispatcher(name, throughput, throughputDeadlineMs, mailboxType, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenWorkStealingDispatcher(name: String) = - ThreadPoolConfigDispatcherBuilder(config => new ExecutorBasedEventDrivenWorkStealingDispatcher(name, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenWorkStealingDispatcher(name: String, throughput: Int) = - ThreadPoolConfigDispatcherBuilder(config => - new ExecutorBasedEventDrivenWorkStealingDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, MAILBOX_TYPE, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenWorkStealingDispatcher(name: String, throughput: Int, mailboxType: MailboxType) = - ThreadPoolConfigDispatcherBuilder(config => - new ExecutorBasedEventDrivenWorkStealingDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType, config), ThreadPoolConfig()) - - /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. - * <p/> - * Has a fluent builder interface for configuring its semantics. - */ - def newExecutorBasedEventDrivenWorkStealingDispatcher(name: String, throughput: Int, throughputDeadlineMs: Int, mailboxType: MailboxType) = - ThreadPoolConfigDispatcherBuilder(config => - new ExecutorBasedEventDrivenWorkStealingDispatcher(name, throughput, throughputDeadlineMs, mailboxType, config), ThreadPoolConfig()) - /** - * Utility function that tries to load the specified dispatcher config from the akka.conf - * or else use the supplied default dispatcher - */ - def fromConfig(key: String, default: => MessageDispatcher = defaultGlobalDispatcher): MessageDispatcher = - config getSection key flatMap from getOrElse default - - /* - * Creates of obtains a dispatcher from a ConfigMap according to the format below - * - * default-dispatcher { - * type = "GlobalExecutorBasedEventDriven" # Must be one of the following, all "Global*" are non-configurable - * # (ExecutorBasedEventDrivenWorkStealing), ExecutorBasedEventDriven, - * # GlobalExecutorBasedEventDriven - * # A FQCN to a class inheriting MessageDispatcherConfigurator with a no-arg visible constructor - * keep-alive-time = 60 # Keep alive time for threads - * core-pool-size-factor = 1.0 # No of core threads ... ceil(available processors * factor) - * max-pool-size-factor = 4.0 # Max no of threads ... ceil(available processors * factor) - * executor-bounds = -1 # Makes the Executor bounded, -1 is unbounded - * allow-core-timeout = on # Allow core threads to time out - * rejection-policy = "caller-runs" # abort, caller-runs, discard-oldest, discard - * throughput = 5 # Throughput for ExecutorBasedEventDrivenDispatcher - * } - * ex: from(config.getConfigMap(identifier).get) - * - * Gotcha: Only configures the dispatcher if possible - * Returns: None if "type" isn't specified in the config - * Throws: IllegalArgumentException if the value of "type" is not valid - * IllegalArgumentException if it cannot - */ - def from(cfg: Configuration): Option[MessageDispatcher] = { - cfg.getString("type") map { - case "ExecutorBasedEventDriven" => new ExecutorBasedEventDrivenDispatcherConfigurator() - case "ExecutorBasedEventDrivenWorkStealing" => new ExecutorBasedEventDrivenWorkStealingDispatcherConfigurator() - case "GlobalExecutorBasedEventDriven" => GlobalExecutorBasedEventDrivenDispatcherConfigurator - case fqn => - ReflectiveAccess.getClassFor[MessageDispatcherConfigurator](fqn) match { - case r: Right[_, Class[MessageDispatcherConfigurator]] => - ReflectiveAccess.createInstance[MessageDispatcherConfigurator](r.b, Array[Class[_]](), Array[AnyRef]()) match { - case r: Right[Exception, MessageDispatcherConfigurator] => r.b - case l: Left[Exception, MessageDispatcherConfigurator] => - throw new IllegalArgumentException("Cannot instantiate MessageDispatcherConfigurator type [%s], make sure it has a default no-args constructor" format fqn, l.a) - } - case l: Left[Exception, _] => - throw new IllegalArgumentException("Unknown MessageDispatcherConfigurator type [%s]" format fqn, l.a) - } - } map { - _ configure cfg - } - } -} - -object GlobalExecutorBasedEventDrivenDispatcherConfigurator extends MessageDispatcherConfigurator { - def configure(config: Configuration): MessageDispatcher = Dispatchers.globalExecutorBasedEventDrivenDispatcher -} - -class ExecutorBasedEventDrivenDispatcherConfigurator extends MessageDispatcherConfigurator { - def configure(config: Configuration): MessageDispatcher = { - configureThreadPool(config, threadPoolConfig => new ExecutorBasedEventDrivenDispatcher( - config.getString("name", newUuid.toString), - config.getInt("throughput", Dispatchers.THROUGHPUT), - config.getInt("throughput-deadline-time", Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS), - mailboxType(config), - threadPoolConfig)).build - } -} - -class ExecutorBasedEventDrivenWorkStealingDispatcherConfigurator extends MessageDispatcherConfigurator { - def configure(config: Configuration): MessageDispatcher = { - configureThreadPool(config, threadPoolConfig => new ExecutorBasedEventDrivenWorkStealingDispatcher( - config.getString("name", newUuid.toString), - config.getInt("throughput", Dispatchers.THROUGHPUT), - config.getInt("throughput-deadline-time", Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS), - mailboxType(config), - threadPoolConfig)).build - } -}
\ No newline at end of file diff --git a/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala deleted file mode 100644 index bc3f29ac68..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala +++ /dev/null @@ -1,305 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.event.EventHandler -import akka.actor.{ ActorRef, IllegalActorStateException } -import akka.util.{ ReflectiveAccess, Switch } - -import java.util.Queue -import java.util.concurrent.atomic.AtomicReference -import java.util.concurrent.{ TimeUnit, ExecutorService, RejectedExecutionException, ConcurrentLinkedQueue, LinkedBlockingQueue } - -/** - * Default settings are: - * <pre/> - * - withNewThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity - * - NR_START_THREADS = 16 - * - NR_MAX_THREADS = 128 - * - KEEP_ALIVE_TIME = 60000L // one minute - * </pre> - * <p/> - * - * The dispatcher has a fluent builder interface to build up a thread pool to suite your use-case. - * There is a default thread pool defined but make use of the builder if you need it. Here are some examples. - * <p/> - * - * Scala API. - * <p/> - * Example usage: - * <pre/> - * val dispatcher = new ExecutorBasedEventDrivenDispatcher("name") - * dispatcher - * .withNewThreadPoolWithBoundedBlockingQueue(100) - * .setCorePoolSize(16) - * .setMaxPoolSize(128) - * .setKeepAliveTimeInMillis(60000) - * .setRejectionPolicy(new CallerRunsPolicy) - * .buildThreadPool - * </pre> - * <p/> - * - * Java API. - * <p/> - * Example usage: - * <pre/> - * ExecutorBasedEventDrivenDispatcher dispatcher = new ExecutorBasedEventDrivenDispatcher("name"); - * dispatcher - * .withNewThreadPoolWithBoundedBlockingQueue(100) - * .setCorePoolSize(16) - * .setMaxPoolSize(128) - * .setKeepAliveTimeInMillis(60000) - * .setRejectionPolicy(new CallerRunsPolicy()) - * .buildThreadPool(); - * </pre> - * <p/> - * - * But the preferred way of creating dispatchers is to use - * the {@link akka.dispatch.Dispatchers} factory object. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - * @param throughput positive integer indicates the dispatcher will only process so much messages at a time from the - * mailbox, without checking the mailboxes of other actors. Zero or negative means the dispatcher - * always continues until the mailbox is empty. - * Larger values (or zero or negative) increase throughput, smaller values increase fairness - */ -class ExecutorBasedEventDrivenDispatcher( - _name: String, - val throughput: Int = Dispatchers.THROUGHPUT, - val throughputDeadlineTime: Int = Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, - val mailboxType: MailboxType = Dispatchers.MAILBOX_TYPE, - val config: ThreadPoolConfig = ThreadPoolConfig()) - extends MessageDispatcher { - - def this(_name: String, throughput: Int, throughputDeadlineTime: Int, mailboxType: MailboxType) = - this(_name, throughput, throughputDeadlineTime, mailboxType, ThreadPoolConfig()) // Needed for Java API usage - - def this(_name: String, throughput: Int, mailboxType: MailboxType) = - this(_name, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType) // Needed for Java API usage - - def this(_name: String, throughput: Int) = - this(_name, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage - - def this(_name: String, _config: ThreadPoolConfig) = - this(_name, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE, _config) - - def this(_name: String) = - this(_name, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage - - val name = "akka:event-driven:dispatcher:" + _name - - private[akka] val threadFactory = new MonitorableThreadFactory(name) - private[akka] val executorService = new AtomicReference[ExecutorService](config.createLazyExecutorService(threadFactory)) - - private[akka] def dispatch(invocation: MessageInvocation) = { - val mbox = getMailbox(invocation.receiver) - mbox enqueue invocation - registerForExecution(mbox) - } - - private[akka] def executeFuture(invocation: FutureInvocation[_]): Unit = if (active.isOn) { - try executorService.get() execute invocation - catch { - case e: RejectedExecutionException => - EventHandler.warning(this, e.toString) - throw e - } - } - - /** - * @return the mailbox associated with the actor - */ - protected def getMailbox(receiver: ActorRef) = receiver.mailbox.asInstanceOf[MessageQueue with ExecutableMailbox] - - override def mailboxSize(actorRef: ActorRef) = getMailbox(actorRef).size - - def createMailbox(actorRef: ActorRef): AnyRef = mailboxType match { - case b: UnboundedMailbox => - new ConcurrentLinkedQueue[MessageInvocation] with MessageQueue with ExecutableMailbox { - @inline - final def dispatcher = ExecutorBasedEventDrivenDispatcher.this - @inline - final def enqueue(m: MessageInvocation) = this.add(m) - @inline - final def dequeue(): MessageInvocation = this.poll() - } - case b: BoundedMailbox => - new DefaultBoundedMessageQueue(b.capacity, b.pushTimeOut) with ExecutableMailbox { - @inline - final def dispatcher = ExecutorBasedEventDrivenDispatcher.this - } - } - - private[akka] def start {} - - private[akka] def shutdown { - val old = executorService.getAndSet(config.createLazyExecutorService(threadFactory)) - if (old ne null) { - old.shutdownNow() - } - } - - private[akka] def registerForExecution(mbox: MessageQueue with ExecutableMailbox): Unit = { - if (mbox.dispatcherLock.tryLock()) { - if (active.isOn && !mbox.suspended.locked) { //If the dispatcher is active and the actor not suspended - try { - executorService.get() execute mbox - } catch { - case e: RejectedExecutionException => - EventHandler.warning(this, e.toString) - mbox.dispatcherLock.unlock() - throw e - } - } else { - mbox.dispatcherLock.unlock() //If the dispatcher isn't active or if the actor is suspended, unlock the dispatcher lock - } - } - } - - private[akka] def reRegisterForExecution(mbox: MessageQueue with ExecutableMailbox): Unit = - registerForExecution(mbox) - - override val toString = getClass.getSimpleName + "[" + name + "]" - - def suspend(actorRef: ActorRef) { - getMailbox(actorRef).suspended.tryLock - } - - def resume(actorRef: ActorRef) { - val mbox = getMailbox(actorRef) - mbox.suspended.tryUnlock - reRegisterForExecution(mbox) - } -} - -/** - * This is the behavior of an ExecutorBasedEventDrivenDispatchers mailbox. - */ -trait ExecutableMailbox extends Runnable { self: MessageQueue => - - def dispatcher: ExecutorBasedEventDrivenDispatcher - - final def run = { - try { - processMailbox() - } catch { - case ie: InterruptedException => - } - finally { - dispatcherLock.unlock() - } - if (!self.isEmpty) - dispatcher.reRegisterForExecution(this) - } - - /** - * Process the messages in the mailbox - * - * @return true if the processing finished before the mailbox was empty, due to the throughput constraint - */ - final def processMailbox() { - if (!self.suspended.locked) { - var nextMessage = self.dequeue - if (nextMessage ne null) { //If we have a message - if (dispatcher.throughput <= 1) //If we only run one message per process - nextMessage.invoke //Just run it - else { //But otherwise, if we are throttled, we need to do some book-keeping - var processedMessages = 0 - val isDeadlineEnabled = dispatcher.throughputDeadlineTime > 0 - val deadlineNs = if (isDeadlineEnabled) System.nanoTime + TimeUnit.MILLISECONDS.toNanos(dispatcher.throughputDeadlineTime) - else 0 - do { - nextMessage.invoke - nextMessage = - if (self.suspended.locked) { - null // If we are suspended, abort - } else { // If we aren't suspended, we need to make sure we're not overstepping our boundaries - processedMessages += 1 - if ((processedMessages >= dispatcher.throughput) || (isDeadlineEnabled && System.nanoTime >= deadlineNs)) // If we're throttled, break out - null //We reached our boundaries, abort - else self.dequeue //Dequeue the next message - } - } while (nextMessage ne null) - } - } - } - } -} - -object PriorityGenerator { - /** - * Creates a PriorityGenerator that uses the supplied function as priority generator - */ - def apply(priorityFunction: Any => Int): PriorityGenerator = new PriorityGenerator { - def gen(message: Any): Int = priorityFunction(message) - } -} - -/** - * A PriorityGenerator is a convenience API to create a Comparator that orders the messages of a - * PriorityExecutorBasedEventDrivenDispatcher - */ -abstract class PriorityGenerator extends java.util.Comparator[MessageInvocation] { - def gen(message: Any): Int - - final def compare(thisMessage: MessageInvocation, thatMessage: MessageInvocation): Int = - gen(thisMessage.message) - gen(thatMessage.message) -} - -/** - * A version of ExecutorBasedEventDrivenDispatcher that gives all actors registered to it a priority mailbox, - * prioritized according to the supplied comparator. - * - * The dispatcher will process the messages with the _lowest_ priority first. - */ -class PriorityExecutorBasedEventDrivenDispatcher( - name: String, - val comparator: java.util.Comparator[MessageInvocation], - throughput: Int = Dispatchers.THROUGHPUT, - throughputDeadlineTime: Int = Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, - mailboxType: MailboxType = Dispatchers.MAILBOX_TYPE, - config: ThreadPoolConfig = ThreadPoolConfig()) extends ExecutorBasedEventDrivenDispatcher(name, throughput, throughputDeadlineTime, mailboxType, config) with PriorityMailbox { - - def this(name: String, comparator: java.util.Comparator[MessageInvocation], throughput: Int, throughputDeadlineTime: Int, mailboxType: MailboxType) = - this(name, comparator, throughput, throughputDeadlineTime, mailboxType, ThreadPoolConfig()) // Needed for Java API usage - - def this(name: String, comparator: java.util.Comparator[MessageInvocation], throughput: Int, mailboxType: MailboxType) = - this(name, comparator, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType) // Needed for Java API usage - - def this(name: String, comparator: java.util.Comparator[MessageInvocation], throughput: Int) = - this(name, comparator, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage - - def this(name: String, comparator: java.util.Comparator[MessageInvocation], config: ThreadPoolConfig) = - this(name, comparator, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE, config) - - def this(name: String, comparator: java.util.Comparator[MessageInvocation]) = - this(name, comparator, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage -} - -/** - * Can be used to give an ExecutorBasedEventDrivenDispatcher's actors priority-enabled mailboxes - * - * Usage: - * new ExecutorBasedEventDrivenDispatcher(...) with PriorityMailbox { - * val comparator = ...comparator that determines mailbox priority ordering... - * } - */ -trait PriorityMailbox { self: ExecutorBasedEventDrivenDispatcher => - def comparator: java.util.Comparator[MessageInvocation] - - override def createMailbox(actorRef: ActorRef): AnyRef = self.mailboxType match { - case b: UnboundedMailbox => - new UnboundedPriorityMessageQueue(comparator) with ExecutableMailbox { - @inline - final def dispatcher = self - } - - case b: BoundedMailbox => - new BoundedPriorityMessageQueue(b.capacity, b.pushTimeOut, comparator) with ExecutableMailbox { - @inline - final def dispatcher = self - } - } -} diff --git a/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala b/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala deleted file mode 100644 index 4cba8eec8b..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.actor.{ ActorRef, Actor, IllegalActorStateException } -import akka.util.{ ReflectiveAccess, Switch } - -import java.util.Queue -import java.util.concurrent.atomic.{ AtomicReference, AtomicInteger } -import java.util.concurrent.{ TimeUnit, ExecutorService, RejectedExecutionException, ConcurrentLinkedQueue, LinkedBlockingQueue } -import util.DynamicVariable - -/** - * An executor based event driven dispatcher which will try to redistribute work from busy actors to idle actors. It is assumed - * that all actors using the same instance of this dispatcher can process all messages that have been sent to one of the actors. I.e. the - * actors belong to a pool of actors, and to the client there is no guarantee about which actor instance actually processes a given message. - * <p/> - * Although the technique used in this implementation is commonly known as "work stealing", the actual implementation is probably - * best described as "work donating" because the actor of which work is being stolen takes the initiative. - * <p/> - * The preferred way of creating dispatchers is to use - * the {@link akka.dispatch.Dispatchers} factory object. - * - * @see akka.dispatch.ExecutorBasedEventDrivenWorkStealingDispatcher - * @see akka.dispatch.Dispatchers - * - * @author Viktor Klang - */ -class ExecutorBasedEventDrivenWorkStealingDispatcher( - _name: String, - throughput: Int = Dispatchers.THROUGHPUT, - throughputDeadlineTime: Int = Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, - mailboxType: MailboxType = Dispatchers.MAILBOX_TYPE, - config: ThreadPoolConfig = ThreadPoolConfig()) - extends ExecutorBasedEventDrivenDispatcher(_name, throughput, throughputDeadlineTime, mailboxType, config) { - - def this(_name: String, throughput: Int, throughputDeadlineTime: Int, mailboxType: MailboxType) = - this(_name, throughput, throughputDeadlineTime, mailboxType, ThreadPoolConfig()) // Needed for Java API usage - - def this(_name: String, throughput: Int, mailboxType: MailboxType) = - this(_name, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType) // Needed for Java API usage - - def this(_name: String, throughput: Int) = - this(_name, throughput, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage - - def this(_name: String, _config: ThreadPoolConfig) = - this(_name, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE, _config) - - def this(_name: String, memberType: Class[_ <: Actor]) = - this(_name, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, Dispatchers.MAILBOX_TYPE) // Needed for Java API usage - - def this(_name: String, mailboxType: MailboxType) = - this(_name, Dispatchers.THROUGHPUT, Dispatchers.THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType) // Needed for Java API usage - - @volatile - private var actorType: Option[Class[_]] = None - @volatile - private var members = Vector[ActorRef]() - private val donationInProgress = new DynamicVariable(false) - - private[akka] override def register(actorRef: ActorRef) = { - //Verify actor type conformity - actorType match { - case None => actorType = Some(actorRef.actor.getClass) - case Some(aType) => - if (aType != actorRef.actor.getClass) - throw new IllegalActorStateException(String.format( - "Can't register actor %s in a work stealing dispatcher which already knows actors of type %s", - actorRef, aType)) - } - - synchronized { members :+= actorRef } //Update members - super.register(actorRef) - } - - private[akka] override def unregister(actorRef: ActorRef) = { - synchronized { members = members.filterNot(actorRef eq) } //Update members - super.unregister(actorRef) - } - - override private[akka] def dispatch(invocation: MessageInvocation) = { - val mbox = getMailbox(invocation.receiver) - if (donationInProgress.value == false && (!mbox.isEmpty || mbox.dispatcherLock.locked) && attemptDonationOf(invocation, mbox)) { - //We were busy and we got to donate the message to some other lucky guy, we're done here - } else { - mbox enqueue invocation - registerForExecution(mbox) - } - } - - override private[akka] def reRegisterForExecution(mbox: MessageQueue with ExecutableMailbox): Unit = { - try { - donationInProgress.value = true - while (donateFrom(mbox)) {} //When we reregister, first donate messages to another actor - } finally { donationInProgress.value = false } - - if (!mbox.isEmpty) //If we still have messages left to process, reschedule for execution - super.reRegisterForExecution(mbox) - } - - /** - * Returns true if it successfully donated a message - */ - protected def donateFrom(donorMbox: MessageQueue with ExecutableMailbox): Boolean = { - val actors = members // copy to prevent concurrent modifications having any impact - - // we risk to pick a thief which is unregistered from the dispatcher in the meantime, but that typically means - // the dispatcher is being shut down... - // Starts at is seeded by current time - doFindDonorRecipient(donorMbox, actors, (System.currentTimeMillis % actors.size).asInstanceOf[Int]) match { - case null => false - case recipient => donate(donorMbox.dequeue, recipient) - } - } - - /** - * Returns true if the donation succeeded or false otherwise - */ - protected def attemptDonationOf(message: MessageInvocation, donorMbox: MessageQueue with ExecutableMailbox): Boolean = try { - donationInProgress.value = true - val actors = members // copy to prevent concurrent modifications having any impact - doFindDonorRecipient(donorMbox, actors, System.identityHashCode(message) % actors.size) match { - case null => false - case recipient => donate(message, recipient) - } - } finally { donationInProgress.value = false } - - /** - * Rewrites the message and adds that message to the recipients mailbox - * returns true if the message is non-null - */ - protected def donate(organ: MessageInvocation, recipient: ActorRef): Boolean = { - if (organ ne null) { - if (organ.senderFuture.isDefined) recipient.postMessageToMailboxAndCreateFutureResultWithTimeout[Any]( - organ.message, recipient.timeout, organ.sender, organ.senderFuture) - else if (organ.sender.isDefined) recipient.postMessageToMailbox(organ.message, organ.sender) - else recipient.postMessageToMailbox(organ.message, None) - true - } else false - } - - /** - * Returns an available recipient for the message, if any - */ - protected def doFindDonorRecipient(donorMbox: MessageQueue with ExecutableMailbox, potentialRecipients: Vector[ActorRef], startIndex: Int): ActorRef = { - val prSz = potentialRecipients.size - var i = 0 - var recipient: ActorRef = null - - while ((i < prSz) && (recipient eq null)) { - val actor = potentialRecipients((i + startIndex) % prSz) //Wrap-around, one full lap - val mbox = getMailbox(actor) - - if ((mbox ne donorMbox) && mbox.isEmpty) { //Don't donate to yourself - recipient = actor //Found! - } - - i += 1 - } - - recipient // nothing found, reuse same start index next time - } -} diff --git a/test/files/presentation/akka/src/akka/dispatch/Future.scala b/test/files/presentation/akka/src/akka/dispatch/Future.scala deleted file mode 100644 index 1ad304d726..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/Future.scala +++ /dev/null @@ -1,832 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.AkkaException -import akka.event.EventHandler -import akka.actor.{ Actor, Channel } -import akka.util.Duration -import akka.japi.{ Procedure, Function => JFunc } - -import scala.util.continuations._ - -import java.util.concurrent.locks.ReentrantLock -import java.util.concurrent.{ ConcurrentLinkedQueue, TimeUnit, Callable } -import java.util.concurrent.TimeUnit.{ NANOSECONDS => NANOS, MILLISECONDS => MILLIS } -import java.util.concurrent.atomic.{ AtomicBoolean } -import java.lang.{ Iterable => JIterable } -import java.util.{ LinkedList => JLinkedList } -import scala.collection.mutable.Stack -import annotation.tailrec - -class FutureTimeoutException(message: String, cause: Throwable = null) extends AkkaException(message, cause) - -object Futures { - - /** - * Java API, equivalent to Future.apply - */ - def future[T](body: Callable[T]): Future[T] = - Future(body.call) - - /** - * Java API, equivalent to Future.apply - */ - def future[T](body: Callable[T], timeout: Long): Future[T] = - Future(body.call, timeout) - - /** - * Java API, equivalent to Future.apply - */ - def future[T](body: Callable[T], dispatcher: MessageDispatcher): Future[T] = - Future(body.call)(dispatcher) - - /** - * Java API, equivalent to Future.apply - */ - def future[T](body: Callable[T], timeout: Long, dispatcher: MessageDispatcher): Future[T] = - Future(body.call, timeout)(dispatcher) - - /** - * Returns a Future to the result of the first future in the list that is completed - */ - def firstCompletedOf[T](futures: Iterable[Future[T]], timeout: Long = Long.MaxValue): Future[T] = { - val futureResult = new DefaultCompletableFuture[T](timeout) - - val completeFirst: Future[T] => Unit = _.value.foreach(futureResult complete _) - for (f ← futures) f onComplete completeFirst - - futureResult - } - - /** - * Java API. - * Returns a Future to the result of the first future in the list that is completed - */ - def firstCompletedOf[T <: AnyRef](futures: java.lang.Iterable[Future[T]], timeout: Long): Future[T] = - firstCompletedOf(scala.collection.JavaConversions.iterableAsScalaIterable(futures), timeout) - - /** - * A non-blocking fold over the specified futures. - * The fold is performed on the thread where the last future is completed, - * the result will be the first failure of any of the futures, or any failure in the actual fold, - * or the result of the fold. - * Example: - * <pre> - * val result = Futures.fold(0)(futures)(_ + _).await.result - * </pre> - */ - def fold[T, R](zero: R, timeout: Long = Actor.TIMEOUT)(futures: Iterable[Future[T]])(foldFun: (R, T) => R): Future[R] = { - if (futures.isEmpty) { - new AlreadyCompletedFuture[R](Right(zero)) - } else { - val result = new DefaultCompletableFuture[R](timeout) - val results = new ConcurrentLinkedQueue[T]() - val allDone = futures.size - - val aggregate: Future[T] => Unit = f => if (!result.isCompleted) { //TODO: This is an optimization, is it premature? - f.value.get match { - case r: Right[Throwable, T] => - results add r.b - if (results.size == allDone) { //Only one thread can get here - try { - result completeWithResult scala.collection.JavaConversions.collectionAsScalaIterable(results).foldLeft(zero)(foldFun) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - result completeWithException e - } - finally { - results.clear - } - } - case l: Left[Throwable, T] => - result completeWithException l.a - results.clear - } - } - - futures foreach { _ onComplete aggregate } - result - } - } - - /** - * Java API - * A non-blocking fold over the specified futures. - * The fold is performed on the thread where the last future is completed, - * the result will be the first failure of any of the futures, or any failure in the actual fold, - * or the result of the fold. - */ - def fold[T <: AnyRef, R <: AnyRef](zero: R, timeout: Long, futures: java.lang.Iterable[Future[T]], fun: akka.japi.Function2[R, T, R]): Future[R] = - fold(zero, timeout)(scala.collection.JavaConversions.iterableAsScalaIterable(futures))(fun.apply _) - - /** - * Initiates a fold over the supplied futures where the fold-zero is the result value of the Future that's completed first - * Example: - * <pre> - * val result = Futures.reduce(futures)(_ + _).await.result - * </pre> - */ - def reduce[T, R >: T](futures: Iterable[Future[T]], timeout: Long = Actor.TIMEOUT)(op: (R, T) => T): Future[R] = { - if (futures.isEmpty) - new AlreadyCompletedFuture[R](Left(new UnsupportedOperationException("empty reduce left"))) - else { - val result = new DefaultCompletableFuture[R](timeout) - val seedFound = new AtomicBoolean(false) - val seedFold: Future[T] => Unit = f => { - if (seedFound.compareAndSet(false, true)) { //Only the first completed should trigger the fold - f.value.get match { - case r: Right[Throwable, T] => - result.completeWith(fold(r.b, timeout)(futures.filterNot(_ eq f))(op)) - case l: Left[Throwable, T] => - result.completeWithException(l.a) - } - } - } - for (f ← futures) f onComplete seedFold //Attach the listener to the Futures - result - } - } - - /** - * Java API. - * Initiates a fold over the supplied futures where the fold-zero is the result value of the Future that's completed first - */ - def reduce[T <: AnyRef, R >: T](futures: java.lang.Iterable[Future[T]], timeout: Long, fun: akka.japi.Function2[R, T, T]): Future[R] = - reduce(scala.collection.JavaConversions.iterableAsScalaIterable(futures), timeout)(fun.apply _) - - /** - * Java API. - * Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.util.LinkedList[A]]. - * Useful for reducing many Futures into a single Future. - */ - def sequence[A](in: JIterable[Future[A]], timeout: Long): Future[JLinkedList[A]] = - scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[A]()))((fr, fa) => - for (r ← fr; a ← fa) yield { - r add a - r - }) - - /** - * Java API. - * Simple version of Futures.traverse. Transforms a java.lang.Iterable[Future[A]] into a Future[java.util.LinkedList[A]]. - * Useful for reducing many Futures into a single Future. - */ - def sequence[A](in: JIterable[Future[A]]): Future[JLinkedList[A]] = sequence(in, Actor.TIMEOUT) - - /** - * Java API. - * Transforms a java.lang.Iterable[A] into a Future[java.util.LinkedList[B]] using the provided Function A => Future[B]. - * This is useful for performing a parallel map. For example, to apply a function to all items of a list - * in parallel. - */ - def traverse[A, B](in: JIterable[A], timeout: Long, fn: JFunc[A, Future[B]]): Future[JLinkedList[B]] = - scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(Future(new JLinkedList[B]())) { (fr, a) => - val fb = fn(a) - for (r ← fr; b ← fb) yield { - r add b - r - } - } - - /** - * Java API. - * Transforms a java.lang.Iterable[A] into a Future[java.util.LinkedList[B]] using the provided Function A => Future[B]. - * This is useful for performing a parallel map. For example, to apply a function to all items of a list - * in parallel. - */ - def traverse[A, B](in: JIterable[A], fn: JFunc[A, Future[B]]): Future[JLinkedList[B]] = traverse(in, Actor.TIMEOUT, fn) - - // ===================================== - // Deprecations - // ===================================== - - /** - * (Blocking!) - */ - @deprecated("Will be removed after 1.1, if you must block, use: futures.foreach(_.await)", "1.1") - def awaitAll(futures: List[Future[_]]): Unit = futures.foreach(_.await) - - /** - * Returns the First Future that is completed (blocking!) - */ - @deprecated("Will be removed after 1.1, if you must block, use: firstCompletedOf(futures).await", "1.1") - def awaitOne(futures: List[Future[_]], timeout: Long = Long.MaxValue): Future[_] = firstCompletedOf[Any](futures, timeout).await - - /** - * Applies the supplied function to the specified collection of Futures after awaiting each future to be completed - */ - @deprecated("Will be removed after 1.1, if you must block, use: futures map { f => fun(f.await) }", "1.1") - def awaitMap[A, B](in: Traversable[Future[A]])(fun: (Future[A]) => B): Traversable[B] = - in map { f => fun(f.await) } - - /** - * Returns Future.resultOrException of the first completed of the 2 Futures provided (blocking!) - */ - @deprecated("Will be removed after 1.1, if you must block, use: firstCompletedOf(List(f1,f2)).await.resultOrException", "1.1") - def awaitEither[T](f1: Future[T], f2: Future[T]): Option[T] = firstCompletedOf[T](List(f1, f2)).await.resultOrException -} - -object Future { - /** - * This method constructs and returns a Future that will eventually hold the result of the execution of the supplied body - * The execution is performed by the specified Dispatcher. - */ - def apply[T](body: => T, timeout: Long = Actor.TIMEOUT)(implicit dispatcher: MessageDispatcher): Future[T] = - dispatcher.dispatchFuture(() => body, timeout) - - /** - * Construct a completable channel - */ - def channel(timeout: Long = Actor.TIMEOUT) = new Channel[Any] { - val future = empty[Any](timeout) - def !(msg: Any) = future completeWithResult msg - } - - /** - * Create an empty Future with default timeout - */ - def empty[T](timeout: Long = Actor.TIMEOUT) = new DefaultCompletableFuture[T](timeout) - - import scala.collection.mutable.Builder - import scala.collection.generic.CanBuildFrom - - /** - * Simple version of Futures.traverse. Transforms a Traversable[Future[A]] into a Future[Traversable[A]]. - * Useful for reducing many Futures into a single Future. - */ - def sequence[A, M[_] <: Traversable[_]](in: M[Future[A]], timeout: Long = Actor.TIMEOUT)(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]]): Future[M[A]] = - in.foldLeft(new DefaultCompletableFuture[Builder[A, M[A]]](timeout).completeWithResult(cbf(in)): Future[Builder[A, M[A]]])((fr, fa) => for (r ← fr; a ← fa.asInstanceOf[Future[A]]) yield (r += a)).map(_.result) - - /** - * Transforms a Traversable[A] into a Future[Traversable[B]] using the provided Function A => Future[B]. - * This is useful for performing a parallel map. For example, to apply a function to all items of a list - * in parallel: - * <pre> - * val myFutureList = Futures.traverse(myList)(x => Future(myFunc(x))) - * </pre> - */ - def traverse[A, B, M[_] <: Traversable[_]](in: M[A], timeout: Long = Actor.TIMEOUT)(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]]): Future[M[B]] = - in.foldLeft(new DefaultCompletableFuture[Builder[B, M[B]]](timeout).completeWithResult(cbf(in)): Future[Builder[B, M[B]]]) { (fr, a) => - val fb = fn(a.asInstanceOf[A]) - for (r ← fr; b ← fb) yield (r += b) - }.map(_.result) - - /** - * Captures a block that will be transformed into 'Continuation Passing Style' using Scala's Delimited - * Continuations plugin. - * - * Within the block, the result of a Future may be accessed by calling Future.apply. At that point - * execution is suspended with the rest of the block being stored in a continuation until the result - * of the Future is available. If an Exception is thrown while processing, it will be contained - * within the resulting Future. - * - * This allows working with Futures in an imperative style without blocking for each result. - * - * Completing a Future using 'CompletableFuture << Future' will also suspend execution until the - * value of the other Future is available. - * - * The Delimited Continuations compiler plugin must be enabled in order to use this method. - */ - def flow[A](body: => A @cps[Future[Any]], timeout: Long = Actor.TIMEOUT): Future[A] = { - val future = Promise[A](timeout) - (reset(future.asInstanceOf[CompletableFuture[Any]].completeWithResult(body)): Future[Any]) onComplete { f => - val opte = f.exception - if (opte.isDefined) future completeWithException (opte.get) - } - future - } - - private[akka] val callbacksPendingExecution = new ThreadLocal[Option[Stack[() => Unit]]]() { - override def initialValue = None - } -} - -sealed trait Future[+T] { - - /** - * For use only within a Future.flow block or another compatible Delimited Continuations reset block. - * - * Returns the result of this Future without blocking, by suspending execution and storing it as a - * continuation until the result is available. - * - * If this Future is untyped (a Future[Nothing]), a type parameter must be explicitly provided or - * execution will fail. The normal result of getting a Future from an ActorRef using !!! will return - * an untyped Future. - */ - def apply[A >: T](): A @cps[Future[Any]] = shift(this flatMap (_: A => Future[Any])) - - /** - * Blocks awaiting completion of this Future, then returns the resulting value, - * or throws the completed exception - * - * Scala & Java API - * - * throws FutureTimeoutException if this Future times out when waiting for completion - */ - def get: T = this.await.resultOrException.get - - /** - * Blocks the current thread until the Future has been completed or the - * timeout has expired. In the case of the timeout expiring a - * FutureTimeoutException will be thrown. - */ - def await: Future[T] - - /** - * Blocks the current thread until the Future has been completed or the - * timeout has expired. The timeout will be the least value of 'atMost' and the timeout - * supplied at the constructuion of this Future. - * In the case of the timeout expiring a FutureTimeoutException will be thrown. - */ - def await(atMost: Duration): Future[T] - - /** - * Blocks the current thread until the Future has been completed. Use - * caution with this method as it ignores the timeout and will block - * indefinitely if the Future is never completed. - */ - @deprecated("Will be removed after 1.1, it's dangerous and can cause deadlocks, agony and insanity.", "1.1") - def awaitBlocking: Future[T] - - /** - * Tests whether this Future has been completed. - */ - final def isCompleted: Boolean = value.isDefined - - /** - * Tests whether this Future's timeout has expired. - * - * Note that an expired Future may still contain a value, or it may be - * completed with a value. - */ - def isExpired: Boolean - - /** - * This Future's timeout in nanoseconds. - */ - def timeoutInNanos: Long - - /** - * The contained value of this Future. Before this Future is completed - * the value will be None. After completion the value will be Some(Right(t)) - * if it contains a valid result, or Some(Left(error)) if it contains - * an exception. - */ - def value: Option[Either[Throwable, T]] - - /** - * Returns the successful result of this Future if it exists. - */ - final def result: Option[T] = { - val v = value - if (v.isDefined) v.get.right.toOption - else None - } - - /** - * Returns the contained exception of this Future if it exists. - */ - final def exception: Option[Throwable] = { - val v = value - if (v.isDefined) v.get.left.toOption - else None - } - - /** - * When this Future is completed, apply the provided function to the - * Future. If the Future has already been completed, this will apply - * immediately. - */ - def onComplete(func: Future[T] => Unit): Future[T] - - /** - * When the future is completed with a valid result, apply the provided - * PartialFunction to the result. - * <pre> - * val result = future receive { - * case Foo => "foo" - * case Bar => "bar" - * }.await.result - * </pre> - */ - final def receive(pf: PartialFunction[Any, Unit]): Future[T] = onComplete { f => - val optr = f.result - if (optr.isDefined) { - val r = optr.get - if (pf.isDefinedAt(r)) pf(r) - } - } - - /** - * Creates a new Future by applying a PartialFunction to the successful - * result of this Future if a match is found, or else return a MatchError. - * If this Future is completed with an exception then the new Future will - * also contain this exception. - * Example: - * <pre> - * val future1 = for { - * a <- actor !!! Req("Hello") collect { case Res(x: Int) => x } - * b <- actor !!! Req(a) collect { case Res(x: String) => x } - * c <- actor !!! Req(7) collect { case Res(x: String) => x } - * } yield b + "-" + c - * </pre> - */ - final def collect[A](pf: PartialFunction[Any, A]): Future[A] = { - val fa = new DefaultCompletableFuture[A](timeoutInNanos, NANOS) - onComplete { ft => - val v = ft.value.get - fa complete { - if (v.isLeft) v.asInstanceOf[Either[Throwable, A]] - else { - try { - val r = v.right.get - if (pf isDefinedAt r) Right(pf(r)) - else Left(new MatchError(r)) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - Left(e) - } - } - } - } - fa - } - - /** - * Creates a new Future that will handle any matching Throwable that this - * Future might contain. If there is no match, or if this Future contains - * a valid result then the new Future will contain the same. - * Example: - * <pre> - * Future(6 / 0) failure { case e: ArithmeticException => 0 } // result: 0 - * Future(6 / 0) failure { case e: NotFoundException => 0 } // result: exception - * Future(6 / 2) failure { case e: ArithmeticException => 0 } // result: 3 - * </pre> - */ - final def failure[A >: T](pf: PartialFunction[Throwable, A]): Future[A] = { - val fa = new DefaultCompletableFuture[A](timeoutInNanos, NANOS) - onComplete { ft => - val opte = ft.exception - fa complete { - if (opte.isDefined) { - val e = opte.get - try { - if (pf isDefinedAt e) Right(pf(e)) - else Left(e) - } catch { - case x: Exception => Left(x) - } - } else ft.value.get - } - } - fa - } - - /** - * Creates a new Future by applying a function to the successful result of - * this Future. If this Future is completed with an exception then the new - * Future will also contain this exception. - * Example: - * <pre> - * val future1 = for { - * a: Int <- actor !!! "Hello" // returns 5 - * b: String <- actor !!! a // returns "10" - * c: String <- actor !!! 7 // returns "14" - * } yield b + "-" + c - * </pre> - */ - final def map[A](f: T => A): Future[A] = { - val fa = new DefaultCompletableFuture[A](timeoutInNanos, NANOS) - onComplete { ft => - val optv = ft.value - if (optv.isDefined) { - val v = optv.get - if (v.isLeft) - fa complete v.asInstanceOf[Either[Throwable, A]] - else { - fa complete (try { - Right(f(v.right.get)) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - Left(e) - }) - } - } - } - fa - } - - /** - * Creates a new Future by applying a function to the successful result of - * this Future, and returns the result of the function as the new Future. - * If this Future is completed with an exception then the new Future will - * also contain this exception. - * Example: - * <pre> - * val future1 = for { - * a: Int <- actor !!! "Hello" // returns 5 - * b: String <- actor !!! a // returns "10" - * c: String <- actor !!! 7 // returns "14" - * } yield b + "-" + c - * </pre> - */ - final def flatMap[A](f: T => Future[A]): Future[A] = { - val fa = new DefaultCompletableFuture[A](timeoutInNanos, NANOS) - onComplete { ft => - val optv = ft.value - if (optv.isDefined) { - val v = optv.get - if (v.isLeft) - fa complete v.asInstanceOf[Either[Throwable, A]] - else { - try { - fa.completeWith(f(v.right.get)) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - fa completeWithException e - } - } - } - } - fa - } - - final def foreach(f: T => Unit): Unit = onComplete { ft => - val optr = ft.result - if (optr.isDefined) - f(optr.get) - } - - final def filter(p: Any => Boolean): Future[Any] = { - val f = new DefaultCompletableFuture[T](timeoutInNanos, NANOS) - onComplete { ft => - val optv = ft.value - if (optv.isDefined) { - val v = optv.get - if (v.isLeft) - f complete v - else { - val r = v.right.get - f complete (try { - if (p(r)) Right(r) - else Left(new MatchError(r)) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - Left(e) - }) - } - } - } - f - } - - /** - * Returns the current result, throws the exception is one has been raised, else returns None - */ - final def resultOrException: Option[T] = { - val v = value - if (v.isDefined) { - val r = v.get - if (r.isLeft) throw r.left.get - else r.right.toOption - } else None - } - - /* Java API */ - final def onComplete[A >: T](proc: Procedure[Future[A]]): Future[T] = onComplete(proc(_)) - - final def map[A >: T, B](f: JFunc[A, B]): Future[B] = map(f(_)) - - final def flatMap[A >: T, B](f: JFunc[A, Future[B]]): Future[B] = flatMap(f(_)) - - final def foreach[A >: T](proc: Procedure[A]): Unit = foreach(proc(_)) - - final def filter(p: JFunc[Any, Boolean]): Future[Any] = filter(p(_)) - -} - -object Promise { - - def apply[A](timeout: Long): CompletableFuture[A] = new DefaultCompletableFuture[A](timeout) - - def apply[A](): CompletableFuture[A] = apply(Actor.TIMEOUT) - -} - -/** - * Essentially this is the Promise (or write-side) of a Future (read-side). - */ -trait CompletableFuture[T] extends Future[T] { - /** - * Completes this Future with the specified result, if not already completed. - * @return this - */ - def complete(value: Either[Throwable, T]): Future[T] - - /** - * Completes this Future with the specified result, if not already completed. - * @return this - */ - final def completeWithResult(result: T): Future[T] = complete(Right(result)) - - /** - * Completes this Future with the specified exception, if not already completed. - * @return this - */ - final def completeWithException(exception: Throwable): Future[T] = complete(Left(exception)) - - /** - * Completes this Future with the specified other Future, when that Future is completed, - * unless this Future has already been completed. - * @return this. - */ - final def completeWith(other: Future[T]): Future[T] = { - other onComplete { f => complete(f.value.get) } - this - } - - final def <<(value: T): Future[T] @cps[Future[Any]] = shift { cont: (Future[T] => Future[Any]) => cont(complete(Right(value))) } - - final def <<(other: Future[T]): Future[T] @cps[Future[Any]] = shift { cont: (Future[T] => Future[Any]) => - val fr = new DefaultCompletableFuture[Any](Actor.TIMEOUT) - this completeWith other onComplete { f => - try { - fr completeWith cont(f) - } catch { - case e: Exception => - EventHandler.error(e, this, e.getMessage) - fr completeWithException e - } - } - fr - } - -} - -/** - * The default concrete Future implementation. - */ -class DefaultCompletableFuture[T](timeout: Long, timeunit: TimeUnit) extends CompletableFuture[T] { - - def this() = this(0, MILLIS) - - def this(timeout: Long) = this(timeout, MILLIS) - - val timeoutInNanos = timeunit.toNanos(timeout) - private val _startTimeInNanos = currentTimeInNanos - private val _lock = new ReentrantLock - private val _signal = _lock.newCondition - private var _value: Option[Either[Throwable, T]] = None - private var _listeners: List[Future[T] => Unit] = Nil - - /** - * Must be called inside _lock.lock<->_lock.unlock - */ - @tailrec - private def awaitUnsafe(waitTimeNanos: Long): Boolean = { - if (_value.isEmpty && waitTimeNanos > 0) { - val start = currentTimeInNanos - val remainingNanos = try { - _signal.awaitNanos(waitTimeNanos) - } catch { - case e: InterruptedException => - waitTimeNanos - (currentTimeInNanos - start) - } - awaitUnsafe(remainingNanos) - } else { - _value.isDefined - } - } - - def await(atMost: Duration) = { - _lock.lock - if (try { awaitUnsafe(atMost.toNanos min timeLeft()) } finally { _lock.unlock }) this - else throw new FutureTimeoutException("Futures timed out after [" + NANOS.toMillis(timeoutInNanos) + "] milliseconds") - } - - def await = { - _lock.lock - if (try { awaitUnsafe(timeLeft()) } finally { _lock.unlock }) this - else throw new FutureTimeoutException("Futures timed out after [" + NANOS.toMillis(timeoutInNanos) + "] milliseconds") - } - - def awaitBlocking = { - _lock.lock - try { - while (_value.isEmpty) { - _signal.await - } - this - } finally { - _lock.unlock - } - } - - def isExpired: Boolean = timeLeft() <= 0 - - def value: Option[Either[Throwable, T]] = { - _lock.lock - try { - _value - } finally { - _lock.unlock - } - } - - def complete(value: Either[Throwable, T]): DefaultCompletableFuture[T] = { - _lock.lock - val notifyTheseListeners = try { - if (_value.isEmpty && !isExpired) { //Only complete if we aren't expired - _value = Some(value) - val existingListeners = _listeners - _listeners = Nil - existingListeners - } else Nil - } finally { - _signal.signalAll - _lock.unlock - } - - if (notifyTheseListeners.nonEmpty) { // Steps to ensure we don't run into a stack-overflow situation - @tailrec - def runCallbacks(rest: List[Future[T] => Unit], callbacks: Stack[() => Unit]) { - if (rest.nonEmpty) { - notifyCompleted(rest.head) - while (callbacks.nonEmpty) { callbacks.pop().apply() } - runCallbacks(rest.tail, callbacks) - } - } - - val pending = Future.callbacksPendingExecution.get - if (pending.isDefined) { //Instead of nesting the calls to the callbacks (leading to stack overflow) - pending.get.push(() => { // Linearize/aggregate callbacks at top level and then execute - val doNotify = notifyCompleted _ //Hoist closure to avoid garbage - notifyTheseListeners foreach doNotify - }) - } else { - try { - val callbacks = Stack[() => Unit]() // Allocate new aggregator for pending callbacks - Future.callbacksPendingExecution.set(Some(callbacks)) // Specify the callback aggregator - runCallbacks(notifyTheseListeners, callbacks) // Execute callbacks, if they trigger new callbacks, they are aggregated - } finally { Future.callbacksPendingExecution.set(None) } // Ensure cleanup - } - } - - this - } - - def onComplete(func: Future[T] => Unit): CompletableFuture[T] = { - _lock.lock - val notifyNow = try { - if (_value.isEmpty) { - if (!isExpired) { //Only add the listener if the future isn't expired - _listeners ::= func - false - } else false //Will never run the callback since the future is expired - } else true - } finally { - _lock.unlock - } - - if (notifyNow) notifyCompleted(func) - - this - } - - private def notifyCompleted(func: Future[T] => Unit) { - try { - func(this) - } catch { - case e => EventHandler notify EventHandler.Error(e, this) - } - } - - @inline - private def currentTimeInNanos: Long = MILLIS.toNanos(System.currentTimeMillis) - @inline - private def timeLeft(): Long = timeoutInNanos - (currentTimeInNanos - _startTimeInNanos) -} - -/** - * An already completed Future is seeded with it's result at creation, is useful for when you are participating in - * a Future-composition but you already have a value to contribute. - */ -sealed class AlreadyCompletedFuture[T](suppliedValue: Either[Throwable, T]) extends CompletableFuture[T] { - val value = Some(suppliedValue) - - def complete(value: Either[Throwable, T]): CompletableFuture[T] = this - def onComplete(func: Future[T] => Unit): Future[T] = { func(this); this } - def await(atMost: Duration): Future[T] = this - def await: Future[T] = this - def awaitBlocking: Future[T] = this - def isExpired: Boolean = true - def timeoutInNanos: Long = 0 -} diff --git a/test/files/presentation/akka/src/akka/dispatch/MailboxHandling.scala b/test/files/presentation/akka/src/akka/dispatch/MailboxHandling.scala deleted file mode 100644 index 4c00577157..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/MailboxHandling.scala +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.AkkaException - -import java.util.{ Comparator, PriorityQueue } -import java.util.concurrent._ -import akka.util._ - -class MessageQueueAppendFailedException(message: String, cause: Throwable = null) extends AkkaException(message, cause) - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait MessageQueue { - val dispatcherLock = new SimpleLock - val suspended = new SimpleLock - def enqueue(handle: MessageInvocation) - def dequeue(): MessageInvocation - def size: Int - def isEmpty: Boolean -} - -/** - * Mailbox configuration. - */ -sealed trait MailboxType - -case class UnboundedMailbox() extends MailboxType -case class BoundedMailbox( - val capacity: Int = { if (Dispatchers.MAILBOX_CAPACITY < 0) Int.MaxValue else Dispatchers.MAILBOX_CAPACITY }, - val pushTimeOut: Duration = Dispatchers.MAILBOX_PUSH_TIME_OUT) extends MailboxType { - if (capacity < 0) throw new IllegalArgumentException("The capacity for BoundedMailbox can not be negative") - if (pushTimeOut eq null) throw new IllegalArgumentException("The push time-out for BoundedMailbox can not be null") -} - -trait UnboundedMessageQueueSemantics extends MessageQueue { self: BlockingQueue[MessageInvocation] => - @inline - final def enqueue(handle: MessageInvocation): Unit = this add handle - @inline - final def dequeue(): MessageInvocation = this.poll() -} - -trait BoundedMessageQueueSemantics extends MessageQueue { self: BlockingQueue[MessageInvocation] => - def pushTimeOut: Duration - - final def enqueue(handle: MessageInvocation) { - if (pushTimeOut.length > 0) { - this.offer(handle, pushTimeOut.length, pushTimeOut.unit) || { - throw new MessageQueueAppendFailedException("Couldn't enqueue message " + handle + " to " + toString) - } - } else this put handle - } - - @inline - final def dequeue(): MessageInvocation = this.poll() -} - -class DefaultUnboundedMessageQueue extends LinkedBlockingQueue[MessageInvocation] with UnboundedMessageQueueSemantics - -class DefaultBoundedMessageQueue(capacity: Int, val pushTimeOut: Duration) extends LinkedBlockingQueue[MessageInvocation](capacity) with BoundedMessageQueueSemantics - -class UnboundedPriorityMessageQueue(cmp: Comparator[MessageInvocation]) extends PriorityBlockingQueue[MessageInvocation](11, cmp) with UnboundedMessageQueueSemantics - -class BoundedPriorityMessageQueue(capacity: Int, val pushTimeOut: Duration, cmp: Comparator[MessageInvocation]) extends BoundedBlockingQueue[MessageInvocation](capacity, new PriorityQueue[MessageInvocation](11, cmp)) with BoundedMessageQueueSemantics diff --git a/test/files/presentation/akka/src/akka/dispatch/MessageHandling.scala b/test/files/presentation/akka/src/akka/dispatch/MessageHandling.scala deleted file mode 100644 index 20887c3867..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/MessageHandling.scala +++ /dev/null @@ -1,260 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import java.util.concurrent._ -import java.util.concurrent.atomic.AtomicLong -import akka.event.EventHandler -import akka.config.Configuration -import akka.config.Config.TIME_UNIT -import akka.util.{ Duration, Switch, ReentrantGuard } -import java.util.concurrent.ThreadPoolExecutor.{ AbortPolicy, CallerRunsPolicy, DiscardOldestPolicy, DiscardPolicy } -import akka.actor._ - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -final case class MessageInvocation(val receiver: ActorRef, - val message: Any, - val sender: Option[ActorRef], - val senderFuture: Option[CompletableFuture[Any]]) { - if (receiver eq null) throw new IllegalArgumentException("Receiver can't be null") - - def invoke = try { - receiver.invoke(this) - } catch { - case e: NullPointerException => throw new ActorInitializationException( - "Don't call 'self ! message' in the Actor's constructor (in Scala this means in the body of the class).") - } -} - -final case class FutureInvocation[T](future: CompletableFuture[T], function: () => T, cleanup: () => Unit) extends Runnable { - def run = { - future complete (try { - Right(function()) - } catch { - case e => - EventHandler.error(e, this, e.getMessage) - Left(e) - } - finally { - cleanup() - }) - } -} - -object MessageDispatcher { - val UNSCHEDULED = 0 - val SCHEDULED = 1 - val RESCHEDULED = 2 - - implicit def defaultGlobalDispatcher = Dispatchers.defaultGlobalDispatcher -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -trait MessageDispatcher { - import MessageDispatcher._ - - protected val uuids = new ConcurrentSkipListSet[Uuid] - protected val futures = new AtomicLong(0L) - protected val guard = new ReentrantGuard - protected val active = new Switch(false) - - private var shutdownSchedule = UNSCHEDULED //This can be non-volatile since it is protected by guard withGuard - - /** - * Creates and returns a mailbox for the given actor. - */ - private[akka] def createMailbox(actorRef: ActorRef): AnyRef - - /** - * Attaches the specified actorRef to this dispatcher - */ - final def attach(actorRef: ActorRef): Unit = guard withGuard { - register(actorRef) - } - - /** - * Detaches the specified actorRef from this dispatcher - */ - final def detach(actorRef: ActorRef): Unit = guard withGuard { - unregister(actorRef) - } - - private[akka] final def dispatchMessage(invocation: MessageInvocation): Unit = dispatch(invocation) - - private[akka] final def dispatchFuture[T](block: () => T, timeout: Long): Future[T] = { - futures.getAndIncrement() - try { - val future = new DefaultCompletableFuture[T](timeout) - - if (active.isOff) - guard withGuard { active.switchOn { start } } - - executeFuture(FutureInvocation[T](future, block, futureCleanup)) - future - } catch { - case e => - futures.decrementAndGet - throw e - } - } - - private val futureCleanup: () => Unit = - () => if (futures.decrementAndGet() == 0) { - guard withGuard { - if (futures.get == 0 && uuids.isEmpty) { - shutdownSchedule match { - case UNSCHEDULED => - shutdownSchedule = SCHEDULED - Scheduler.scheduleOnce(shutdownAction, timeoutMs, TimeUnit.MILLISECONDS) - case SCHEDULED => - shutdownSchedule = RESCHEDULED - case RESCHEDULED => //Already marked for reschedule - } - } - } - } - - private[akka] def register(actorRef: ActorRef) { - if (actorRef.mailbox eq null) - actorRef.mailbox = createMailbox(actorRef) - - uuids add actorRef.uuid - if (active.isOff) { - active.switchOn { - start - } - } - } - - private[akka] def unregister(actorRef: ActorRef) = { - if (uuids remove actorRef.uuid) { - actorRef.mailbox = null - if (uuids.isEmpty && futures.get == 0) { - shutdownSchedule match { - case UNSCHEDULED => - shutdownSchedule = SCHEDULED - Scheduler.scheduleOnce(shutdownAction, timeoutMs, TimeUnit.MILLISECONDS) - case SCHEDULED => - shutdownSchedule = RESCHEDULED - case RESCHEDULED => //Already marked for reschedule - } - } - } - } - - /** - * Traverses the list of actors (uuids) currently being attached to this dispatcher and stops those actors - */ - def stopAllAttachedActors { - val i = uuids.iterator - while (i.hasNext()) { - val uuid = i.next() - Actor.registry.actorFor(uuid) match { - case Some(actor) => actor.stop() - case None => {} - } - } - } - - private val shutdownAction = new Runnable { - def run = guard withGuard { - shutdownSchedule match { - case RESCHEDULED => - shutdownSchedule = SCHEDULED - Scheduler.scheduleOnce(this, timeoutMs, TimeUnit.MILLISECONDS) - case SCHEDULED => - if (uuids.isEmpty && futures.get == 0) { - active switchOff { - shutdown // shut down in the dispatcher's references is zero - } - } - shutdownSchedule = UNSCHEDULED - case UNSCHEDULED => //Do nothing - } - } - } - - /** - * When the dispatcher no longer has any actors registered, how long will it wait until it shuts itself down, in Ms - * defaulting to your akka configs "akka.actor.dispatcher-shutdown-timeout" or otherwise, 1 Second - */ - private[akka] def timeoutMs: Long = Dispatchers.DEFAULT_SHUTDOWN_TIMEOUT.toMillis - - /** - * After the call to this method, the dispatcher mustn't begin any new message processing for the specified reference - */ - def suspend(actorRef: ActorRef): Unit - - /* - * After the call to this method, the dispatcher must begin any new message processing for the specified reference - */ - def resume(actorRef: ActorRef): Unit - - /** - * Will be called when the dispatcher is to queue an invocation for execution - */ - private[akka] def dispatch(invocation: MessageInvocation): Unit - - private[akka] def executeFuture(invocation: FutureInvocation[_]): Unit - - /** - * Called one time every time an actor is attached to this dispatcher and this dispatcher was previously shutdown - */ - private[akka] def start(): Unit - - /** - * Called one time every time an actor is detached from this dispatcher and this dispatcher has no actors left attached - */ - private[akka] def shutdown(): Unit - - /** - * Returns the size of the mailbox for the specified actor - */ - def mailboxSize(actorRef: ActorRef): Int - - /** - * Returns the amount of futures queued for execution - */ - def pendingFutures: Long = futures.get -} - -/** - * Trait to be used for hooking in new dispatchers into Dispatchers.fromConfig - */ -abstract class MessageDispatcherConfigurator { - /** - * Returns an instance of MessageDispatcher given a Configuration - */ - def configure(config: Configuration): MessageDispatcher - - def mailboxType(config: Configuration): MailboxType = { - val capacity = config.getInt("mailbox-capacity", Dispatchers.MAILBOX_CAPACITY) - if (capacity < 1) UnboundedMailbox() - else BoundedMailbox(capacity, Duration(config.getInt("mailbox-push-timeout-time", Dispatchers.MAILBOX_PUSH_TIME_OUT.toMillis.toInt), TIME_UNIT)) - } - - def configureThreadPool(config: Configuration, createDispatcher: => (ThreadPoolConfig) => MessageDispatcher): ThreadPoolConfigDispatcherBuilder = { - import ThreadPoolConfigDispatcherBuilder.conf_? - - //Apply the following options to the config if they are present in the config - ThreadPoolConfigDispatcherBuilder(createDispatcher, ThreadPoolConfig()).configure( - conf_?(config getInt "keep-alive-time")(time => _.setKeepAliveTime(Duration(time, TIME_UNIT))), - conf_?(config getDouble "core-pool-size-factor")(factor => _.setCorePoolSizeFromFactor(factor)), - conf_?(config getDouble "max-pool-size-factor")(factor => _.setMaxPoolSizeFromFactor(factor)), - conf_?(config getInt "executor-bounds")(bounds => _.setExecutorBounds(bounds)), - conf_?(config getBool "allow-core-timeout")(allow => _.setAllowCoreThreadTimeout(allow)), - conf_?(config getString "rejection-policy" map { - case "abort" => new AbortPolicy() - case "caller-runs" => new CallerRunsPolicy() - case "discard-oldest" => new DiscardOldestPolicy() - case "discard" => new DiscardPolicy() - case x => throw new IllegalArgumentException("[%s] is not a valid rejectionPolicy!" format x) - })(policy => _.setRejectionPolicy(policy))) - } -} diff --git a/test/files/presentation/akka/src/akka/dispatch/ThreadBasedDispatcher.scala b/test/files/presentation/akka/src/akka/dispatch/ThreadBasedDispatcher.scala deleted file mode 100644 index 3169c70ef9..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/ThreadBasedDispatcher.scala +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import akka.actor.{ Actor, ActorRef } -import akka.config.Config.config -import akka.util.Duration - -import java.util.Queue -import java.util.concurrent.{ ConcurrentLinkedQueue, BlockingQueue, TimeUnit, LinkedBlockingQueue } -import akka.actor -import java.util.concurrent.atomic.AtomicReference - -/** - * Dedicates a unique thread for each actor passed in as reference. Served through its messageQueue. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class ThreadBasedDispatcher(_actor: ActorRef, _mailboxType: MailboxType) - extends ExecutorBasedEventDrivenDispatcher( - _actor.uuid.toString, Dispatchers.THROUGHPUT, -1, _mailboxType, ThreadBasedDispatcher.oneThread) { - - private[akka] val owner = new AtomicReference[ActorRef](_actor) - - def this(actor: ActorRef) = - this(actor, UnboundedMailbox()) // For Java API - - def this(actor: ActorRef, capacity: Int) = - this(actor, BoundedMailbox(capacity)) //For Java API - - def this(actor: ActorRef, capacity: Int, pushTimeOut: Duration) = //For Java API - this(actor, BoundedMailbox(capacity, pushTimeOut)) - - override def register(actorRef: ActorRef) = { - val actor = owner.get() - if ((actor ne null) && actorRef != actor) throw new IllegalArgumentException("Cannot register to anyone but " + actor) - owner.compareAndSet(null, actorRef) //Register if unregistered - super.register(actorRef) - } - - override def unregister(actorRef: ActorRef) = { - super.unregister(actorRef) - owner.compareAndSet(actorRef, null) //Unregister (prevent memory leak) - } -} - -object ThreadBasedDispatcher { - val oneThread: ThreadPoolConfig = ThreadPoolConfig(allowCorePoolTimeout = true, corePoolSize = 1, maxPoolSize = 1) -} - diff --git a/test/files/presentation/akka/src/akka/dispatch/ThreadPoolBuilder.scala b/test/files/presentation/akka/src/akka/dispatch/ThreadPoolBuilder.scala deleted file mode 100644 index e847610c4c..0000000000 --- a/test/files/presentation/akka/src/akka/dispatch/ThreadPoolBuilder.scala +++ /dev/null @@ -1,259 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.dispatch - -import java.util.Collection -import java.util.concurrent._ -import atomic.{ AtomicLong, AtomicInteger } -import ThreadPoolExecutor.CallerRunsPolicy - -import akka.util.Duration -import akka.event.EventHandler - -object ThreadPoolConfig { - type Bounds = Int - type FlowHandler = Either[RejectedExecutionHandler, Bounds] - type QueueFactory = () => BlockingQueue[Runnable] - - val defaultAllowCoreThreadTimeout: Boolean = false - val defaultCorePoolSize: Int = 16 - val defaultMaxPoolSize: Int = 128 - val defaultTimeout: Duration = Duration(60000L, TimeUnit.MILLISECONDS) - def defaultFlowHandler: FlowHandler = flowHandler(new CallerRunsPolicy) - - def flowHandler(rejectionHandler: RejectedExecutionHandler): FlowHandler = Left(rejectionHandler) - def flowHandler(bounds: Int): FlowHandler = Right(bounds) - - def fixedPoolSize(size: Int): Int = size - def scaledPoolSize(multiplier: Double): Int = - (Runtime.getRuntime.availableProcessors * multiplier).ceil.toInt - - def arrayBlockingQueue(capacity: Int, fair: Boolean): QueueFactory = - () => new ArrayBlockingQueue[Runnable](capacity, fair) - - def synchronousQueue(fair: Boolean): QueueFactory = - () => new SynchronousQueue[Runnable](fair) - - def linkedBlockingQueue(): QueueFactory = - () => new LinkedBlockingQueue[Runnable]() - - def linkedBlockingQueue(capacity: Int): QueueFactory = - () => new LinkedBlockingQueue[Runnable](capacity) - - def reusableQueue(queue: BlockingQueue[Runnable]): QueueFactory = - () => queue - - def reusableQueue(queueFactory: QueueFactory): QueueFactory = { - val queue = queueFactory() - () => queue - } -} - -case class ThreadPoolConfig(allowCorePoolTimeout: Boolean = ThreadPoolConfig.defaultAllowCoreThreadTimeout, - corePoolSize: Int = ThreadPoolConfig.defaultCorePoolSize, - maxPoolSize: Int = ThreadPoolConfig.defaultMaxPoolSize, - threadTimeout: Duration = ThreadPoolConfig.defaultTimeout, - flowHandler: ThreadPoolConfig.FlowHandler = ThreadPoolConfig.defaultFlowHandler, - queueFactory: ThreadPoolConfig.QueueFactory = ThreadPoolConfig.linkedBlockingQueue()) { - - final def createLazyExecutorService(threadFactory: ThreadFactory): ExecutorService = - new LazyExecutorServiceWrapper(createExecutorService(threadFactory)) - - final def createExecutorService(threadFactory: ThreadFactory): ExecutorService = { - flowHandler match { - case Left(rejectHandler) => - val service = new ThreadPoolExecutor(corePoolSize, maxPoolSize, threadTimeout.length, threadTimeout.unit, queueFactory(), threadFactory, rejectHandler) - service.allowCoreThreadTimeOut(allowCorePoolTimeout) - service - case Right(bounds) => - val service = new ThreadPoolExecutor(corePoolSize, maxPoolSize, threadTimeout.length, threadTimeout.unit, queueFactory(), threadFactory) - service.allowCoreThreadTimeOut(allowCorePoolTimeout) - new BoundedExecutorDecorator(service, bounds) - } - } -} - -trait DispatcherBuilder { - def build: MessageDispatcher -} - -object ThreadPoolConfigDispatcherBuilder { - def conf_?[T](opt: Option[T])(fun: (T) => ThreadPoolConfigDispatcherBuilder => ThreadPoolConfigDispatcherBuilder): Option[(ThreadPoolConfigDispatcherBuilder) => ThreadPoolConfigDispatcherBuilder] = opt map fun -} - -case class ThreadPoolConfigDispatcherBuilder(dispatcherFactory: (ThreadPoolConfig) => MessageDispatcher, config: ThreadPoolConfig) extends DispatcherBuilder { - import ThreadPoolConfig._ - def build = dispatcherFactory(config) - - //TODO remove this, for backwards compat only - @deprecated("Use .build instead", "1.1") - def buildThreadPool = build - - def withNewBoundedThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity(bounds: Int): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(flowHandler = flowHandler(bounds), queueFactory = linkedBlockingQueue())) - - def withNewThreadPoolWithCustomBlockingQueue(newQueueFactory: QueueFactory): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(flowHandler = defaultFlowHandler, queueFactory = newQueueFactory)) - - def withNewThreadPoolWithCustomBlockingQueue(queue: BlockingQueue[Runnable]): ThreadPoolConfigDispatcherBuilder = - withNewThreadPoolWithCustomBlockingQueue(reusableQueue(queue)) - - def withNewThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity: ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(queueFactory = linkedBlockingQueue(), flowHandler = defaultFlowHandler)) - - def withNewThreadPoolWithLinkedBlockingQueueWithCapacity(capacity: Int): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(queueFactory = linkedBlockingQueue(capacity), flowHandler = defaultFlowHandler)) - - def withNewThreadPoolWithSynchronousQueueWithFairness(fair: Boolean): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(queueFactory = synchronousQueue(fair), flowHandler = defaultFlowHandler)) - - def withNewThreadPoolWithArrayBlockingQueueWithCapacityAndFairness(capacity: Int, fair: Boolean): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(queueFactory = arrayBlockingQueue(capacity, fair), flowHandler = defaultFlowHandler)) - - def setCorePoolSize(size: Int): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(corePoolSize = size)) - - def setMaxPoolSize(size: Int): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(maxPoolSize = size)) - - def setCorePoolSizeFromFactor(multiplier: Double): ThreadPoolConfigDispatcherBuilder = - setCorePoolSize(scaledPoolSize(multiplier)) - - def setMaxPoolSizeFromFactor(multiplier: Double): ThreadPoolConfigDispatcherBuilder = - setMaxPoolSize(scaledPoolSize(multiplier)) - - def setExecutorBounds(bounds: Int): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(flowHandler = flowHandler(bounds))) - - def setKeepAliveTimeInMillis(time: Long): ThreadPoolConfigDispatcherBuilder = - setKeepAliveTime(Duration(time, TimeUnit.MILLISECONDS)) - - def setKeepAliveTime(time: Duration): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(threadTimeout = time)) - - def setRejectionPolicy(policy: RejectedExecutionHandler): ThreadPoolConfigDispatcherBuilder = - setFlowHandler(flowHandler(policy)) - - def setFlowHandler(newFlowHandler: FlowHandler): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(flowHandler = newFlowHandler)) - - def setAllowCoreThreadTimeout(allow: Boolean): ThreadPoolConfigDispatcherBuilder = - this.copy(config = config.copy(allowCorePoolTimeout = allow)) - - def configure(fs: Option[Function[ThreadPoolConfigDispatcherBuilder, ThreadPoolConfigDispatcherBuilder]]*): ThreadPoolConfigDispatcherBuilder = fs.foldLeft(this)((c, f) => f.map(_(c)).getOrElse(c)) -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class MonitorableThreadFactory(val name: String) extends ThreadFactory { - protected val counter = new AtomicLong - - def newThread(runnable: Runnable) = new MonitorableThread(runnable, name) -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object MonitorableThread { - val DEFAULT_NAME = "MonitorableThread" - - // FIXME use MonitorableThread.created and MonitorableThread.alive in monitoring - val created = new AtomicInteger - val alive = new AtomicInteger -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class MonitorableThread(runnable: Runnable, name: String) - extends Thread(runnable, name + "-" + MonitorableThread.created.incrementAndGet) { - - setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - def uncaughtException(thread: Thread, cause: Throwable) = {} - }) - - override def run = { - try { - MonitorableThread.alive.incrementAndGet - super.run - } finally { - MonitorableThread.alive.decrementAndGet - } - } -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class BoundedExecutorDecorator(val executor: ExecutorService, bound: Int) extends ExecutorServiceDelegate { - protected val semaphore = new Semaphore(bound) - - override def execute(command: Runnable) = { - semaphore.acquire - try { - executor.execute(new Runnable() { - def run = { - try { - command.run - } finally { - semaphore.release - } - } - }) - } catch { - case e: RejectedExecutionException => - EventHandler.warning(this, e.toString) - semaphore.release - case e: Throwable => - EventHandler.error(e, this, e.getMessage) - throw e - } - } -} - -trait ExecutorServiceDelegate extends ExecutorService { - - def executor: ExecutorService - - def execute(command: Runnable) = executor.execute(command) - - def shutdown() { executor.shutdown() } - - def shutdownNow() = executor.shutdownNow() - - def isShutdown = executor.isShutdown - - def isTerminated = executor.isTerminated - - def awaitTermination(l: Long, timeUnit: TimeUnit) = executor.awaitTermination(l, timeUnit) - - def submit[T](callable: Callable[T]) = executor.submit(callable) - - def submit[T](runnable: Runnable, t: T) = executor.submit(runnable, t) - - def submit(runnable: Runnable) = executor.submit(runnable) - - def invokeAll[T](callables: Collection[_ <: Callable[T]]) = executor.invokeAll(callables) - - def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = executor.invokeAll(callables, l, timeUnit) - - def invokeAny[T](callables: Collection[_ <: Callable[T]]) = executor.invokeAny(callables) - - def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = executor.invokeAny(callables, l, timeUnit) -} - -trait LazyExecutorService extends ExecutorServiceDelegate { - - def createExecutor: ExecutorService - - lazy val executor = { - createExecutor - } -} - -class LazyExecutorServiceWrapper(executorFactory: => ExecutorService) extends LazyExecutorService { - def createExecutor = executorFactory -} diff --git a/test/files/presentation/akka/src/akka/event/EventHandler.scala b/test/files/presentation/akka/src/akka/event/EventHandler.scala deleted file mode 100644 index f3176b7c21..0000000000 --- a/test/files/presentation/akka/src/akka/event/EventHandler.scala +++ /dev/null @@ -1,235 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.event - -import akka.actor._ -import akka.config.Config._ -import akka.config.ConfigurationException -import akka.util.{ ListenerManagement, ReflectiveAccess } -import akka.AkkaException - -/** - * Event handler. - * <p/> - * Create, add and remove a listener: - * <pre> - * val eventHandlerListener = Actor.actorOf(new Actor { - * self.dispatcher = EventHandler.EventHandlerDispatcher - * - * def receive = { - * case EventHandler.Error(cause, instance, message) => ... - * case EventHandler.Warning(instance, message) => ... - * case EventHandler.Info(instance, message) => ... - * case EventHandler.Debug(instance, message) => ... - * case genericEvent => ... - * } - * }) - * - * EventHandler.addListener(eventHandlerListener) - * ... - * EventHandler.removeListener(eventHandlerListener) - * </pre> - * <p/> - * However best is probably to register the listener in the 'akka.conf' - * configuration file. - * <p/> - * Log an error event: - * <pre> - * EventHandler.notify(EventHandler.Error(exception, this, message)) - * </pre> - * Or use the direct methods (better performance): - * <pre> - * EventHandler.error(exception, this, message) - * </pre> - * - * Shut down the EventHandler: - * <pre> - * EventHandler.shutdown() - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object EventHandler extends ListenerManagement { - import java.io.{ StringWriter, PrintWriter } - import java.text.DateFormat - import java.util.Date - import akka.dispatch.Dispatchers - - val ErrorLevel = 1 - val WarningLevel = 2 - val InfoLevel = 3 - val DebugLevel = 4 - - sealed trait Event { - @transient - val thread: Thread = Thread.currentThread - val level: Int - } - case class Error(cause: Throwable, instance: AnyRef, message: Any = "") extends Event { - override val level = ErrorLevel - } - case class Warning(instance: AnyRef, message: Any = "") extends Event { - override val level = WarningLevel - } - case class Info(instance: AnyRef, message: Any = "") extends Event { - override val level = InfoLevel - } - case class Debug(instance: AnyRef, message: Any = "") extends Event { - override val level = DebugLevel - } - - val error = "[ERROR] [%s] [%s] [%s] %s\n%s".intern - val warning = "[WARN] [%s] [%s] [%s] %s".intern - val info = "[INFO] [%s] [%s] [%s] %s".intern - val debug = "[DEBUG] [%s] [%s] [%s] %s".intern - val generic = "[GENERIC] [%s] [%s]".intern - val ID = "event:handler".intern - - class EventHandlerException extends AkkaException - - lazy val EventHandlerDispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher(ID).build - - val level: Int = config.getString("akka.event-handler-level", "INFO") match { - case "ERROR" => ErrorLevel - case "WARNING" => WarningLevel - case "INFO" => InfoLevel - case "DEBUG" => DebugLevel - case unknown => throw new ConfigurationException( - "Configuration option 'akka.event-handler-level' is invalid [" + unknown + "]") - } - - /** - * Shuts down all event handler listeners including the event handle dispatcher. - */ - def shutdown() { - foreachListener(_.stop()) - EventHandlerDispatcher.shutdown() - } - - def notify(event: Any) { - if (event.isInstanceOf[Event]) { - if (level >= event.asInstanceOf[Event].level) notifyListeners(event) - } else - notifyListeners(event) - } - - def notify[T <: Event: ClassManifest](event: => T) { - if (level >= levelFor(classManifest[T].erasure.asInstanceOf[Class[_ <: Event]])) notifyListeners(event) - } - - def error(cause: Throwable, instance: AnyRef, message: => String) { - if (level >= ErrorLevel) notifyListeners(Error(cause, instance, message)) - } - - def error(cause: Throwable, instance: AnyRef, message: Any) { - if (level >= ErrorLevel) notifyListeners(Error(cause, instance, message)) - } - - def error(instance: AnyRef, message: => String) { - if (level >= ErrorLevel) notifyListeners(Error(new EventHandlerException, instance, message)) - } - - def error(instance: AnyRef, message: Any) { - if (level >= ErrorLevel) notifyListeners(Error(new EventHandlerException, instance, message)) - } - - def warning(instance: AnyRef, message: => String) { - if (level >= WarningLevel) notifyListeners(Warning(instance, message)) - } - - def warning(instance: AnyRef, message: Any) { - if (level >= WarningLevel) notifyListeners(Warning(instance, message)) - } - - def info(instance: AnyRef, message: => String) { - if (level >= InfoLevel) notifyListeners(Info(instance, message)) - } - - def info(instance: AnyRef, message: Any) { - if (level >= InfoLevel) notifyListeners(Info(instance, message)) - } - - def debug(instance: AnyRef, message: => String) { - if (level >= DebugLevel) notifyListeners(Debug(instance, message)) - } - - def debug(instance: AnyRef, message: Any) { - if (level >= DebugLevel) notifyListeners(Debug(instance, message)) - } - - def isInfoEnabled = level >= InfoLevel - - def isDebugEnabled = level >= DebugLevel - - def formattedTimestamp = DateFormat.getInstance.format(new Date) - - def stackTraceFor(e: Throwable) = { - val sw = new StringWriter - val pw = new PrintWriter(sw) - e.printStackTrace(pw) - sw.toString - } - - private def levelFor(eventClass: Class[_ <: Event]) = { - if (eventClass.isInstanceOf[Error]) ErrorLevel - else if (eventClass.isInstanceOf[Warning]) WarningLevel - else if (eventClass.isInstanceOf[Info]) InfoLevel - else if (eventClass.isInstanceOf[Debug]) DebugLevel - else DebugLevel - } - - class DefaultListener extends Actor { - self.id = ID - self.dispatcher = EventHandlerDispatcher - - def receive = { - case event@Error(cause, instance, message) => - println(error.format( - formattedTimestamp, - event.thread.getName, - instance.getClass.getSimpleName, - message, - stackTraceFor(cause))) - case event@Warning(instance, message) => - println(warning.format( - formattedTimestamp, - event.thread.getName, - instance.getClass.getSimpleName, - message)) - case event@Info(instance, message) => - println(info.format( - formattedTimestamp, - event.thread.getName, - instance.getClass.getSimpleName, - message)) - case event@Debug(instance, message) => - println(debug.format( - formattedTimestamp, - event.thread.getName, - instance.getClass.getSimpleName, - message)) - case event => - println(generic.format(formattedTimestamp, event.toString)) - } - } - - val defaultListeners = config.getList("akka.event-handlers") match { - case Nil => "akka.event.EventHandler$DefaultListener" :: Nil - case listeners => listeners - } - defaultListeners foreach { listenerName => - try { - ReflectiveAccess.getClassFor[Actor](listenerName) match { - case r: Right[_, Class[Actor]] => addListener(Actor.actorOf(r.b).start()) - case l: Left[Exception, _] => throw l.a - } - } catch { - case e: Exception => - throw new ConfigurationException( - "Event Handler specified in config can't be loaded [" + listenerName + - "] due to [" + e.toString + "]", e) - } - } -} diff --git a/test/files/presentation/akka/src/akka/event/JavaEventHandler.java b/test/files/presentation/akka/src/akka/event/JavaEventHandler.java deleted file mode 100644 index 7e6e2d4143..0000000000 --- a/test/files/presentation/akka/src/akka/event/JavaEventHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package akka.event; - - -import akka.actor.ActorRef; - -/** - * Java API for Akka EventHandler - */ - -public class JavaEventHandler { - - - public static void notify(Object message){ - EventHandler$.MODULE$.notify(message); - } - - public static void debug(ActorRef instance, Object message){ - EventHandler$.MODULE$.debug(instance, message); - } - - public static void info(ActorRef instance, Object message){ - EventHandler$.MODULE$.info(instance,message); - } - - public static void warning(ActorRef instance, Object message){ - EventHandler$.MODULE$.warning(instance,message); - } - - public static void error(ActorRef instance, Object message){ - EventHandler$.MODULE$.debug(instance,message); - } - -} - - diff --git a/test/files/presentation/akka/src/akka/japi/JavaAPI.scala b/test/files/presentation/akka/src/akka/japi/JavaAPI.scala deleted file mode 100644 index f5c4ccdcaa..0000000000 --- a/test/files/presentation/akka/src/akka/japi/JavaAPI.scala +++ /dev/null @@ -1,108 +0,0 @@ -package akka.japi - -/** - * A Function interface. Used to create first-class-functions is Java (sort of). - */ -trait Function[T, R] { - def apply(param: T): R -} - -/** - * A Function interface. Used to create 2-arg first-class-functions is Java (sort of). - */ -trait Function2[T1, T2, R] { - def apply(arg1: T1, arg2: T2): R -} - -/** - * A Procedure is like a Function, but it doesn't produce a return value - */ -trait Procedure[T] { - def apply(param: T): Unit -} - -/** - * A Procedure is like a Function, but it doesn't produce a return value - */ -trait Procedure2[T1, T2] { - def apply(param: T1, param2: T2): Unit -} - -/** - * An executable piece of code that takes no parameters and doesn't return any value. - */ -trait SideEffect { - def apply: Unit -} - -/** - * An executable piece of code that takes no parameters and doesn't return any value. - */ -trait Effect { - def apply: Unit -} - -/** - * + * A constructor/factory, takes no parameters but creates a new value of type T every call - * + - */ -trait Creator[T] { - def create: T -} - -/** - * This class represents optional values. Instances of <code>Option</code> - * are either instances of case class <code>Some</code> or it is case - * object <code>None</code>. - * <p> - * Java API - */ -sealed abstract class Option[A] extends java.lang.Iterable[A] { - import scala.collection.JavaConversions._ - - def get: A - def isEmpty: Boolean - def isDefined = !isEmpty - def asScala: scala.Option[A] - def iterator = if (isEmpty) Iterator.empty else Iterator.single(get) -} - -object Option { - /** - * <code>Option</code> factory that creates <code>Some</code> - */ - def some[A](v: A): Option[A] = Some(v) - - /** - * <code>Option</code> factory that creates <code>None</code> - */ - def none[A] = None.asInstanceOf[Option[A]] - - /** - * <code>Option</code> factory that creates <code>None</code> if - * <code>v</code> is <code>null</code>, <code>Some(v)</code> otherwise. - */ - def option[A](v: A): Option[A] = if (v == null) none else some(v) - - /** - * Class <code>Some[A]</code> represents existing values of type - * <code>A</code>. - */ - final case class Some[A](v: A) extends Option[A] { - def get = v - def isEmpty = false - def asScala = scala.Some(v) - } - - /** - * This case object represents non-existent values. - */ - private case object None extends Option[Nothing] { - def get = throw new NoSuchElementException("None.get") - def isEmpty = true - def asScala = scala.None - } - - implicit def java2ScalaOption[A](o: Option[A]): scala.Option[A] = o.asScala - implicit def scala2JavaOption[A](o: scala.Option[A]): Option[A] = option(o.get) -} diff --git a/test/files/presentation/akka/src/akka/remoteinterface/RemoteEventHandler.scala b/test/files/presentation/akka/src/akka/remoteinterface/RemoteEventHandler.scala deleted file mode 100644 index 1c75618301..0000000000 --- a/test/files/presentation/akka/src/akka/remoteinterface/RemoteEventHandler.scala +++ /dev/null @@ -1,43 +0,0 @@ -package akka.remoteinterface - -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -import akka.actor.Actor -import akka.event.EventHandler - -/** - * Remote client and server event listener that pipes the events to the standard Akka EventHander. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class RemoteEventHandler extends Actor { - import EventHandler._ - - self.id = ID - self.dispatcher = EventHandlerDispatcher - - def receive = { - - // client - case RemoteClientError(cause, client, address) => EventHandler.error(cause, client, "RemoteClientError - Address[%s]" format address.toString) - case RemoteClientWriteFailed(request, cause, client, address) => EventHandler.error(cause, client, "RemoteClientWriteFailed - Request[%s] Address[%s]".format(address.toString)) - case RemoteClientDisconnected(client, address) => EventHandler.info(client, "RemoteClientDisconnected - Address[%s]" format address.toString) - case RemoteClientConnected(client, address) => EventHandler.info(client, "RemoteClientConnected - Address[%s]" format address.toString) - case RemoteClientStarted(client, address) => EventHandler.info(client, "RemoteClientStarted - Address[%s]" format address.toString) - case RemoteClientShutdown(client, address) => EventHandler.info(client, "RemoteClientShutdown - Address[%s]" format address.toString) - - // server - case RemoteServerError(cause, server) => EventHandler.error(cause, server, "RemoteServerError") - case RemoteServerWriteFailed(request, cause, server, clientAddress) => EventHandler.error(cause, server, "RemoteServerWriteFailed - Request[%s] Address[%s]" format (request, clientAddress.toString)) - case RemoteServerStarted(server) => EventHandler.info(server, "RemoteServerStarted") - case RemoteServerShutdown(server) => EventHandler.info(server, "RemoteServerShutdown") - case RemoteServerClientConnected(server, clientAddress) => EventHandler.info(server, "RemoteServerClientConnected - Address[%s]" format clientAddress.toString) - case RemoteServerClientDisconnected(server, clientAddress) => EventHandler.info(server, "RemoteServerClientDisconnected - Address[%s]" format clientAddress.toString) - case RemoteServerClientClosed(server, clientAddress) => EventHandler.info(server, "RemoteServerClientClosed - Address[%s]" format clientAddress.toString) - - case _ => //ignore other - } -} - diff --git a/test/files/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala b/test/files/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala deleted file mode 100644 index 0c5da82294..0000000000 --- a/test/files/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala +++ /dev/null @@ -1,493 +0,0 @@ -/** - * Copyright (C) 2009-2010 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.remoteinterface - -import akka.japi.Creator -import akka.actor._ -import akka.util._ -import akka.dispatch.CompletableFuture -import akka.AkkaException - -import scala.beans.BeanProperty - -import java.net.InetSocketAddress -import java.util.concurrent.ConcurrentHashMap -import java.io.{ PrintWriter, PrintStream } -import java.lang.reflect.InvocationTargetException - -trait RemoteModule { - val UUID_PREFIX = "uuid:".intern - - def optimizeLocalScoped_?(): Boolean //Apply optimizations for remote operations in local scope - protected[akka] def notifyListeners(message: => Any): Unit - - private[akka] def actors: ConcurrentHashMap[String, ActorRef] - private[akka] def actorsByUuid: ConcurrentHashMap[String, ActorRef] - private[akka] def actorsFactories: ConcurrentHashMap[String, () => ActorRef] - private[akka] def typedActors: ConcurrentHashMap[String, AnyRef] - private[akka] def typedActorsByUuid: ConcurrentHashMap[String, AnyRef] - private[akka] def typedActorsFactories: ConcurrentHashMap[String, () => AnyRef] - - /** Lookup methods **/ - - private[akka] def findActorById(id: String): ActorRef = actors.get(id) - - private[akka] def findActorByUuid(uuid: String): ActorRef = actorsByUuid.get(uuid) - - private[akka] def findActorFactory(id: String): () => ActorRef = actorsFactories.get(id) - - private[akka] def findTypedActorById(id: String): AnyRef = typedActors.get(id) - - private[akka] def findTypedActorFactory(id: String): () => AnyRef = typedActorsFactories.get(id) - - private[akka] def findTypedActorByUuid(uuid: String): AnyRef = typedActorsByUuid.get(uuid) - - private[akka] def findActorByIdOrUuid(id: String, uuid: String): ActorRef = { - var actorRefOrNull = if (id.startsWith(UUID_PREFIX)) findActorByUuid(id.substring(UUID_PREFIX.length)) - else findActorById(id) - if (actorRefOrNull eq null) actorRefOrNull = findActorByUuid(uuid) - actorRefOrNull - } - - private[akka] def findTypedActorByIdOrUuid(id: String, uuid: String): AnyRef = { - var actorRefOrNull = if (id.startsWith(UUID_PREFIX)) findTypedActorByUuid(id.substring(UUID_PREFIX.length)) - else findTypedActorById(id) - if (actorRefOrNull eq null) actorRefOrNull = findTypedActorByUuid(uuid) - actorRefOrNull - } -} - -/** - * Life-cycle events for RemoteClient. - */ -sealed trait RemoteClientLifeCycleEvent -case class RemoteClientError( - @BeanProperty cause: Throwable, - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent -case class RemoteClientDisconnected( - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent -case class RemoteClientConnected( - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent -case class RemoteClientStarted( - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent -case class RemoteClientShutdown( - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent -case class RemoteClientWriteFailed( - @BeanProperty request: AnyRef, - @BeanProperty cause: Throwable, - @BeanProperty client: RemoteClientModule, - @BeanProperty remoteAddress: InetSocketAddress) extends RemoteClientLifeCycleEvent - -/** - * Life-cycle events for RemoteServer. - */ -sealed trait RemoteServerLifeCycleEvent -case class RemoteServerStarted( - @BeanProperty val server: RemoteServerModule) extends RemoteServerLifeCycleEvent -case class RemoteServerShutdown( - @BeanProperty val server: RemoteServerModule) extends RemoteServerLifeCycleEvent -case class RemoteServerError( - @BeanProperty val cause: Throwable, - @BeanProperty val server: RemoteServerModule) extends RemoteServerLifeCycleEvent -case class RemoteServerClientConnected( - @BeanProperty val server: RemoteServerModule, - @BeanProperty val clientAddress: Option[InetSocketAddress]) extends RemoteServerLifeCycleEvent -case class RemoteServerClientDisconnected( - @BeanProperty val server: RemoteServerModule, - @BeanProperty val clientAddress: Option[InetSocketAddress]) extends RemoteServerLifeCycleEvent -case class RemoteServerClientClosed( - @BeanProperty val server: RemoteServerModule, - @BeanProperty val clientAddress: Option[InetSocketAddress]) extends RemoteServerLifeCycleEvent -case class RemoteServerWriteFailed( - @BeanProperty request: AnyRef, - @BeanProperty cause: Throwable, - @BeanProperty server: RemoteServerModule, - @BeanProperty clientAddress: Option[InetSocketAddress]) extends RemoteServerLifeCycleEvent - -/** - * Thrown for example when trying to send a message using a RemoteClient that is either not started or shut down. - */ -class RemoteClientException private[akka] ( - message: String, - @BeanProperty val client: RemoteClientModule, - val remoteAddress: InetSocketAddress, cause: Throwable = null) extends AkkaException(message, cause) - -/** - * Thrown when the remote server actor dispatching fails for some reason. - */ -class RemoteServerException private[akka] (message: String) extends AkkaException(message) - -/** - * Thrown when a remote exception sent over the wire cannot be loaded and instantiated - */ -case class CannotInstantiateRemoteExceptionDueToRemoteProtocolParsingErrorException private[akka] (cause: Throwable, originalClassName: String, originalMessage: String) - extends AkkaException("\nParsingError[%s]\nOriginalException[%s]\nOriginalMessage[%s]" - .format(cause.toString, originalClassName, originalMessage)) { - override def printStackTrace = cause.printStackTrace - override def printStackTrace(printStream: PrintStream) = cause.printStackTrace(printStream) - override def printStackTrace(printWriter: PrintWriter) = cause.printStackTrace(printWriter) -} - -abstract class RemoteSupport extends ListenerManagement with RemoteServerModule with RemoteClientModule { - - lazy val eventHandler: ActorRef = { - val handler = Actor.actorOf[RemoteEventHandler].start() - // add the remote client and server listener that pipes the events to the event handler system - addListener(handler) - handler - } - - def shutdown() { - eventHandler.stop() - removeListener(eventHandler) - this.shutdownClientModule() - this.shutdownServerModule() - clear - } - - /** - * Creates a Client-managed ActorRef out of the Actor of the specified Class. - * If the supplied host and port is identical of the configured local node, it will be a local actor - * <pre> - * import Actor._ - * val actor = actorOf(classOf[MyActor],"www.akka.io", 2552) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf(classOf[MyActor],"www.akka.io", 2552).start() - * </pre> - */ - @deprecated("Will be removed after 1.1", "1.1") - def actorOf(factory: => Actor, host: String, port: Int): ActorRef = - Actor.remote.clientManagedActorOf(() => factory, host, port) - - /** - * Creates a Client-managed ActorRef out of the Actor of the specified Class. - * If the supplied host and port is identical of the configured local node, it will be a local actor - * <pre> - * import Actor._ - * val actor = actorOf(classOf[MyActor],"www.akka.io",2552) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf(classOf[MyActor],"www.akka.io",2552).start() - * </pre> - */ - @deprecated("Will be removed after 1.1", "1.1") - def actorOf(clazz: Class[_ <: Actor], host: String, port: Int): ActorRef = - clientManagedActorOf(() => createActorFromClass(clazz), host, port) - - /** - * Creates a Client-managed ActorRef out of the Actor of the specified Class. - * If the supplied host and port is identical of the configured local node, it will be a local actor - * <pre> - * import Actor._ - * val actor = actorOf[MyActor]("www.akka.io",2552) - * actor.start() - * actor ! message - * actor.stop() - * </pre> - * You can create and start the actor in one statement like this: - * <pre> - * val actor = actorOf[MyActor]("www.akka.io",2552).start() - * </pre> - */ - @deprecated("Will be removed after 1.1", "1.1") - def actorOf[T <: Actor: Manifest](host: String, port: Int): ActorRef = - clientManagedActorOf(() => createActorFromClass(manifest.erasure), host, port) - - protected def createActorFromClass(clazz: Class[_]): Actor = { - import ReflectiveAccess.{ createInstance, noParams, noArgs } - createInstance[Actor](clazz, noParams, noArgs) match { - case Right(actor) => actor - case Left(exception) => - val cause = exception match { - case i: InvocationTargetException => i.getTargetException - case _ => exception - } - - throw new ActorInitializationException( - "Could not instantiate Actor of " + clazz + - "\nMake sure Actor is NOT defined inside a class/trait," + - "\nif so put it outside the class/trait, f.e. in a companion object," + - "\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'.", cause) - } - } - - protected override def manageLifeCycleOfListeners = false - protected[akka] override def notifyListeners(message: => Any): Unit = super.notifyListeners(message) - - private[akka] val actors = new ConcurrentHashMap[String, ActorRef] - private[akka] val actorsByUuid = new ConcurrentHashMap[String, ActorRef] - private[akka] val actorsFactories = new ConcurrentHashMap[String, () => ActorRef] - private[akka] val typedActors = new ConcurrentHashMap[String, AnyRef] - private[akka] val typedActorsByUuid = new ConcurrentHashMap[String, AnyRef] - private[akka] val typedActorsFactories = new ConcurrentHashMap[String, () => AnyRef] - - def clear { - actors.clear - actorsByUuid.clear - typedActors.clear - typedActorsByUuid.clear - actorsFactories.clear - typedActorsFactories.clear - } -} - -/** - * This is the interface for the RemoteServer functionality, it's used in Actor.remote - */ -trait RemoteServerModule extends RemoteModule { - protected val guard = new ReentrantGuard - - /** - * Signals whether the server is up and running or not - */ - def isRunning: Boolean - - /** - * Gets the name of the server instance - */ - def name: String - - /** - * Gets the address of the server instance - */ - def address: InetSocketAddress - - /** - * Starts the server up - */ - def start(): RemoteServerModule = - start(ReflectiveAccess.Remote.configDefaultAddress.getAddress.getHostAddress, - ReflectiveAccess.Remote.configDefaultAddress.getPort, - None) - - /** - * Starts the server up - */ - def start(loader: ClassLoader): RemoteServerModule = - start(ReflectiveAccess.Remote.configDefaultAddress.getAddress.getHostAddress, - ReflectiveAccess.Remote.configDefaultAddress.getPort, - Option(loader)) - - /** - * Starts the server up - */ - def start(host: String, port: Int): RemoteServerModule = - start(host, port, None) - - /** - * Starts the server up - */ - def start(host: String, port: Int, loader: ClassLoader): RemoteServerModule = - start(host, port, Option(loader)) - - /** - * Starts the server up - */ - def start(host: String, port: Int, loader: Option[ClassLoader]): RemoteServerModule - - /** - * Shuts the server down - */ - def shutdownServerModule(): Unit - - /** - * Register typed actor by interface name. - */ - def registerTypedActor(intfClass: Class[_], typedActor: AnyRef): Unit = registerTypedActor(intfClass.getName, typedActor) - - /** - * Register remote typed actor by a specific id. - * @param id custom actor id - * @param typedActor typed actor to register - */ - def registerTypedActor(id: String, typedActor: AnyRef): Unit - - /** - * Register typed actor by interface name. - */ - def registerTypedPerSessionActor(intfClass: Class[_], factory: => AnyRef): Unit = registerTypedActor(intfClass.getName, factory) - - /** - * Register typed actor by interface name. - * Java API - */ - def registerTypedPerSessionActor(intfClass: Class[_], factory: Creator[AnyRef]): Unit = registerTypedActor(intfClass.getName, factory) - - /** - * Register remote typed actor by a specific id. - * @param id custom actor id - * @param typedActor typed actor to register - */ - def registerTypedPerSessionActor(id: String, factory: => AnyRef): Unit - - /** - * Register remote typed actor by a specific id. - * @param id custom actor id - * @param typedActor typed actor to register - * Java API - */ - def registerTypedPerSessionActor(id: String, factory: Creator[AnyRef]): Unit = registerTypedPerSessionActor(id, factory.create) - - /** - * Register Remote Actor by the Actor's 'id' field. It starts the Actor if it is not started already. - */ - def register(actorRef: ActorRef): Unit = register(actorRef.id, actorRef) - - /** - * Register Remote Actor by the Actor's uuid field. It starts the Actor if it is not started already. - */ - def registerByUuid(actorRef: ActorRef): Unit - - /** - * Register Remote Actor by a specific 'id' passed as argument. The actor is registered by UUID rather than ID - * when prefixing the handle with the “uuid:” protocol. - * <p/> - * NOTE: If you use this method to register your remote actor then you must unregister the actor by this ID yourself. - */ - def register(id: String, actorRef: ActorRef): Unit - - /** - * 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 - - /** - * 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. - * Java API - */ - def registerPerSession(id: String, factory: Creator[ActorRef]): Unit = registerPerSession(id, factory.create) - - /** - * Unregister Remote Actor that is registered using its 'id' field (not custom ID). - */ - def unregister(actorRef: ActorRef): Unit - - /** - * 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 unregister(id: String): Unit - - /** - * 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 - - /** - * Unregister Remote Typed Actor by specific 'id'. - * <p/> - * NOTE: You need to call this method if you have registered an actor by a custom ID. - */ - def unregisterTypedActor(id: String): Unit - - /** - * Unregister Remote Typed Actor by specific 'id'. - * <p/> - * NOTE: You need to call this method if you have registered an actor by a custom ID. - */ - def unregisterTypedPerSessionActor(id: String): Unit -} - -trait RemoteClientModule extends RemoteModule { self: RemoteModule => - - def actorFor(classNameOrServiceId: String, hostname: String, port: Int): ActorRef = - actorFor(classNameOrServiceId, classNameOrServiceId, Actor.TIMEOUT, hostname, port, None) - - def actorFor(classNameOrServiceId: String, hostname: String, port: Int, loader: ClassLoader): ActorRef = - actorFor(classNameOrServiceId, classNameOrServiceId, Actor.TIMEOUT, hostname, port, Some(loader)) - - def actorFor(serviceId: String, className: String, hostname: String, port: Int): ActorRef = - actorFor(serviceId, className, Actor.TIMEOUT, hostname, port, None) - - def actorFor(serviceId: String, className: String, hostname: String, port: Int, loader: ClassLoader): ActorRef = - actorFor(serviceId, className, Actor.TIMEOUT, hostname, port, Some(loader)) - - def actorFor(classNameOrServiceId: String, timeout: Long, hostname: String, port: Int): ActorRef = - actorFor(classNameOrServiceId, classNameOrServiceId, timeout, hostname, port, None) - - def actorFor(classNameOrServiceId: String, timeout: Long, hostname: String, port: Int, loader: ClassLoader): ActorRef = - actorFor(classNameOrServiceId, classNameOrServiceId, timeout, hostname, port, Some(loader)) - - def actorFor(serviceId: String, className: String, timeout: Long, hostname: String, port: Int): ActorRef = - actorFor(serviceId, className, timeout, hostname, port, None) - - def typedActorFor[T](intfClass: Class[T], serviceIdOrClassName: String, hostname: String, port: Int): T = - typedActorFor(intfClass, serviceIdOrClassName, serviceIdOrClassName, Actor.TIMEOUT, hostname, port, None) - - def typedActorFor[T](intfClass: Class[T], serviceIdOrClassName: String, timeout: Long, hostname: String, port: Int): T = - typedActorFor(intfClass, serviceIdOrClassName, serviceIdOrClassName, timeout, hostname, port, None) - - def typedActorFor[T](intfClass: Class[T], serviceIdOrClassName: String, timeout: Long, hostname: String, port: Int, loader: ClassLoader): T = - typedActorFor(intfClass, serviceIdOrClassName, serviceIdOrClassName, timeout, hostname, port, Some(loader)) - - def typedActorFor[T](intfClass: Class[T], serviceId: String, implClassName: String, timeout: Long, hostname: String, port: Int, loader: ClassLoader): T = - typedActorFor(intfClass, serviceId, implClassName, timeout, hostname, port, Some(loader)) - - @deprecated("Will be removed after 1.1", "1.1") - def clientManagedActorOf(factory: () => Actor, host: String, port: Int): ActorRef - - /** - * Clean-up all open connections. - */ - def shutdownClientModule(): Unit - - /** - * Shuts down a specific client connected to the supplied remote address returns true if successful - */ - def shutdownClientConnection(address: InetSocketAddress): Boolean - - /** - * Restarts a specific client connected to the supplied remote address, but only if the client is not shut down - */ - def restartClientConnection(address: InetSocketAddress): Boolean - - /** Methods that needs to be implemented by a transport **/ - - protected[akka] def typedActorFor[T](intfClass: Class[T], serviceId: String, implClassName: String, timeout: Long, host: String, port: Int, loader: Option[ClassLoader]): T - - protected[akka] def actorFor(serviceId: String, className: String, timeout: Long, hostname: String, port: Int, loader: Option[ClassLoader]): ActorRef - - protected[akka] def send[T](message: Any, - senderOption: Option[ActorRef], - senderFuture: Option[CompletableFuture[T]], - remoteAddress: InetSocketAddress, - timeout: Long, - isOneWay: Boolean, - actorRef: ActorRef, - typedActorInfo: Option[Tuple2[String, String]], - actorType: ActorType, - loader: Option[ClassLoader]): Option[CompletableFuture[T]] - - private[akka] def registerSupervisorForActor(actorRef: ActorRef): ActorRef - - private[akka] def deregisterSupervisorForActor(actorRef: ActorRef): ActorRef - - @deprecated("Will be removed after 1.1", "1.1") - private[akka] def registerClientManagedActor(hostname: String, port: Int, uuid: Uuid): Unit - - @deprecated("Will be removed after 1.1", "1.1") - private[akka] def unregisterClientManagedActor(hostname: String, port: Int, uuid: Uuid): Unit -} diff --git a/test/files/presentation/akka/src/akka/routing/Iterators.scala b/test/files/presentation/akka/src/akka/routing/Iterators.scala deleted file mode 100644 index 315e7bea51..0000000000 --- a/test/files/presentation/akka/src/akka/routing/Iterators.scala +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.routing - -import akka.actor.ActorRef -import scala.collection.JavaConversions._ -import scala.collection.immutable.Seq - -/** - * An Iterator that is either always empty or yields an infinite number of Ts. - */ -trait InfiniteIterator[T] extends Iterator[T] { - val items: Seq[T] -} - -/** - * CyclicIterator is a round-robin style InfiniteIterator that cycles the supplied List. - */ -case class CyclicIterator[T](val items: Seq[T]) extends InfiniteIterator[T] { - def this(items: java.util.List[T]) = this(items.toList) - - @volatile - private[this] var current: Seq[T] = items - - def hasNext = items != Nil - - def next = { - val nc = if (current == Nil) items else current - current = nc.tail - nc.head - } - - override def exists(f: T => Boolean): Boolean = items.exists(f) -} - -/** - * This InfiniteIterator always returns the Actor that has the currently smallest mailbox - * useful for work-stealing. - */ -case class SmallestMailboxFirstIterator(val items: Seq[ActorRef]) extends InfiniteIterator[ActorRef] { - def this(items: java.util.List[ActorRef]) = this(items.toList) - def hasNext = items != Nil - - def next = items.reduceLeft((a1, a2) => if (a1.mailboxSize < a2.mailboxSize) a1 else a2) - - override def exists(f: ActorRef => Boolean): Boolean = items.exists(f) -} diff --git a/test/files/presentation/akka/src/akka/routing/Listeners.scala b/test/files/presentation/akka/src/akka/routing/Listeners.scala deleted file mode 100644 index 04f6c1259f..0000000000 --- a/test/files/presentation/akka/src/akka/routing/Listeners.scala +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.routing - -import akka.actor.{ Actor, ActorRef } -import java.util.concurrent.ConcurrentSkipListSet -import scala.collection.JavaConversions._ - -sealed trait ListenerMessage -case class Listen(listener: ActorRef) extends ListenerMessage -case class Deafen(listener: ActorRef) extends ListenerMessage -case class WithListeners(f: (ActorRef) => Unit) extends ListenerMessage - -/** - * Listeners is a generic trait to implement listening capability on an Actor. - * <p/> - * Use the <code>gossip(msg)</code> method to have it sent to the listeners. - * <p/> - * Send <code>Listen(self)</code> to start listening. - * <p/> - * Send <code>Deafen(self)</code> to stop listening. - * <p/> - * Send <code>WithListeners(fun)</code> to traverse the current listeners. - */ -trait Listeners { self: Actor => - private val listeners = new ConcurrentSkipListSet[ActorRef] - - protected def listenerManagement: Receive = { - case Listen(l) => listeners add l - case Deafen(l) => listeners remove l - case WithListeners(f) => listeners foreach f - } - - protected def gossip(msg: Any) = listeners foreach (_ ! msg) -} diff --git a/test/files/presentation/akka/src/akka/routing/Pool.scala b/test/files/presentation/akka/src/akka/routing/Pool.scala deleted file mode 100644 index 0fd1bc8f49..0000000000 --- a/test/files/presentation/akka/src/akka/routing/Pool.scala +++ /dev/null @@ -1,292 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.routing - -import akka.actor.{ Actor, ActorRef, PoisonPill } -import java.util.concurrent.TimeUnit - -/** - * Actor pooling - * - * An actor pool is an message router for a set of delegate actors. The pool is an actor itself. - * There are a handful of basic concepts that need to be understood when working with and defining your pool. - * - * Selectors - A selector is a trait that determines how and how many pooled actors will receive an incoming message. - * Capacitors - A capacitor is a trait that influences the size of pool. There are effectively two types. - * The first determines the size itself - either fixed or bounded. - * The second determines how to adjust of the pool according to some internal pressure characteristic. - * Filters - A filter can be used to refine the raw pressure value returned from a capacitor. - * - * It should be pointed out that all actors in the pool are treated as essentially equivalent. This is not to say - * that one couldn't instance different classes within the pool, only that the pool, when selecting and routing, - * will not take any type information into consideration. - * - * @author Garrick Evans - */ - -object ActorPool { - case object Stat - case class Stats(size: Int) -} - -/** - * Defines the nature of an actor pool. - */ -trait ActorPool { - def instance(): ActorRef //Question, Instance of what? - def capacity(delegates: Seq[ActorRef]): Int //Question, What is the semantics of this return value? - def select(delegates: Seq[ActorRef]): Tuple2[Iterator[ActorRef], Int] //Question, Why does select return this instead of an ordered Set? -} - -/** - * A default implementation of a pool, on each message to route, - * - checks the current capacity and adjusts accordingly if needed - * - routes the incoming message to a selection set of delegate actors - */ -trait DefaultActorPool extends ActorPool { this: Actor => - import ActorPool._ - import collection.mutable.LinkedList - import akka.actor.MaximumNumberOfRestartsWithinTimeRangeReached - - protected var _delegates = Vector[ActorRef]() - private var _lastCapacityChange = 0 - private var _lastSelectorCount = 0 - - override def postStop() = _delegates foreach { delegate => - try { - delegate ! PoisonPill - } catch { case e: Exception => } //Ignore any exceptions here - } - - protected def _route(): Receive = { - // for testing... - case Stat => - self reply_? Stats(_delegates length) - case max: MaximumNumberOfRestartsWithinTimeRangeReached => - _delegates = _delegates filterNot { _.uuid == max.victim.uuid } - case msg => - resizeIfAppropriate() - - select(_delegates) match { - case (selectedDelegates, count) => - _lastSelectorCount = count - selectedDelegates foreach { _ forward msg } //Should we really send the same message to several actors? - } - } - - private def resizeIfAppropriate() { - val requestedCapacity = capacity(_delegates) - val newDelegates = requestedCapacity match { - case qty if qty > 0 => - _delegates ++ { - for (i ← 0 until requestedCapacity) yield { - val delegate = instance() - self startLink delegate - delegate - } - } - case qty if qty < 0 => - _delegates.splitAt(_delegates.length + requestedCapacity) match { - case (keep, abandon) => - abandon foreach { _ ! PoisonPill } - keep - } - case _ => _delegates //No change - } - - _lastCapacityChange = requestedCapacity - _delegates = newDelegates - } -} - -/** - * Selectors - * These traits define how, when a message needs to be routed, delegate(s) are chosen from the pool - */ - -/** - * Returns the set of delegates with the least amount of message backlog. - */ -trait SmallestMailboxSelector { - def selectionCount: Int - def partialFill: Boolean - - def select(delegates: Seq[ActorRef]): Tuple2[Iterator[ActorRef], Int] = { - var set: Seq[ActorRef] = Nil - var take = if (partialFill) math.min(selectionCount, delegates.length) else selectionCount - - while (take > 0) { - set = delegates.sortWith(_.mailboxSize < _.mailboxSize).take(take) ++ set //Question, doesn't this risk selecting the same actor multiple times? - take -= set.size - } - - (set.iterator, set.size) - } -} - -/** - * Returns the set of delegates that occur sequentially 'after' the last delegate from the previous selection - */ -trait RoundRobinSelector { - private var _last: Int = -1; - - def selectionCount: Int - def partialFill: Boolean - - def select(delegates: Seq[ActorRef]): Tuple2[Iterator[ActorRef], Int] = { - val length = delegates.length - val take = if (partialFill) math.min(selectionCount, length) - else selectionCount - - val set = - for (i ← 0 until take) yield { - _last = (_last + 1) % length - delegates(_last) - } - - (set.iterator, set.size) - } -} - -/** - * Capacitors - * These traits define how to alter the size of the pool - */ - -/** - * Ensures a fixed number of delegates in the pool - */ -trait FixedSizeCapacitor { - def limit: Int - def capacity(delegates: Seq[ActorRef]): Int = (limit - delegates.size) max 0 -} - -/** - * Constrains the pool capacity to a bounded range - */ -trait BoundedCapacitor { - def lowerBound: Int - def upperBound: Int - - def capacity(delegates: Seq[ActorRef]): Int = { - val current = delegates length - val delta = _eval(delegates) - val proposed = current + delta - - if (proposed < lowerBound) delta + (lowerBound - proposed) - else if (proposed > upperBound) delta - (proposed - upperBound) - else delta - } - - protected def _eval(delegates: Seq[ActorRef]): Int -} - -/** - * Returns the number of delegates required to manage the current message backlogs - */ -trait MailboxPressureCapacitor { - def pressureThreshold: Int - def pressure(delegates: Seq[ActorRef]): Int = - delegates count { _.mailboxSize > pressureThreshold } -} - -/** - * Returns the number of delegates required to respond to the number of pending futures - */ -trait ActiveFuturesPressureCapacitor { - def pressure(delegates: Seq[ActorRef]): Int = - delegates count { _.senderFuture.isDefined } -} - -/** - */ -trait CapacityStrategy { - import ActorPool._ - - def pressure(delegates: Seq[ActorRef]): Int - def filter(pressure: Int, capacity: Int): Int - - protected def _eval(delegates: Seq[ActorRef]): Int = filter(pressure(delegates), delegates.size) -} - -trait FixedCapacityStrategy extends FixedSizeCapacitor -trait BoundedCapacityStrategy extends CapacityStrategy with BoundedCapacitor - -/** - * Filters - * These traits refine the raw pressure reading into a more appropriate capacity delta. - */ - -/** - * The basic filter trait that composes ramp-up and and back-off subfiltering. - */ -trait Filter { - def rampup(pressure: Int, capacity: Int): Int - def backoff(pressure: Int, capacity: Int): Int - - // pass through both filters just to be sure any internal counters - // are updated consistently. ramping up is always + and backing off - // is always - and each should return 0 otherwise... - def filter(pressure: Int, capacity: Int): Int = - rampup(pressure, capacity) + backoff(pressure, capacity) -} - -trait BasicFilter extends Filter with BasicRampup with BasicBackoff - -/** - * Filter performs steady incremental growth using only the basic ramp-up subfilter - */ -trait BasicNoBackoffFilter extends BasicRampup { - def filter(pressure: Int, capacity: Int): Int = rampup(pressure, capacity) -} - -/** - * Basic incremental growth as a percentage of the current pool capacity - */ -trait BasicRampup { - def rampupRate: Double - - def rampup(pressure: Int, capacity: Int): Int = - if (pressure < capacity) 0 else math.ceil(rampupRate * capacity) toInt -} - -/** - * Basic decrement as a percentage of the current pool capacity - */ -trait BasicBackoff { - def backoffThreshold: Double - def backoffRate: Double - - def backoff(pressure: Int, capacity: Int): Int = - if (capacity > 0 && pressure / capacity < backoffThreshold) math.ceil(-1.0 * backoffRate * capacity) toInt else 0 -} -/** - * This filter tracks the average pressure over the lifetime of the pool (or since last reset) and - * will begin to reduce capacity once this value drops below the provided threshold. The number of - * delegates to cull from the pool is determined by some scaling factor (the backoffRate) multiplied - * by the difference in capacity and pressure. - */ -trait RunningMeanBackoff { - def backoffThreshold: Double - def backoffRate: Double - - private var _pressure: Double = 0.0 - private var _capacity: Double = 0.0 - - def backoff(pressure: Int, capacity: Int): Int = { - _pressure += pressure - _capacity += capacity - - if (capacity > 0 && pressure / capacity < backoffThreshold - && _capacity > 0 && _pressure / _capacity < backoffThreshold) //Why does the entire clause need to be true? - math.floor(-1.0 * backoffRate * (capacity - pressure)).toInt - else 0 - } - - def backoffReset { - _pressure = 0.0 - _capacity = 0.0 - } -} diff --git a/test/files/presentation/akka/src/akka/routing/Routers.scala b/test/files/presentation/akka/src/akka/routing/Routers.scala deleted file mode 100644 index a4c34c5c67..0000000000 --- a/test/files/presentation/akka/src/akka/routing/Routers.scala +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.routing - -import akka.actor.{ UntypedActor, Actor, ActorRef } - -/** - * A Dispatcher is a trait whose purpose is to route incoming messages to actors. - */ -trait Dispatcher { this: Actor => - - protected def transform(msg: Any): Any = msg - - protected def routes: PartialFunction[Any, ActorRef] - - protected def broadcast(message: Any) {} - - protected def dispatch: Receive = { - case Routing.Broadcast(message) => - broadcast(message) - case a if routes.isDefinedAt(a) => - if (isSenderDefined) routes(a).forward(transform(a))(someSelf) - else routes(a).!(transform(a))(None) - } - - def receive = dispatch - - private def isSenderDefined = self.senderFuture.isDefined || self.sender.isDefined -} - -/** - * An UntypedDispatcher is an abstract class whose purpose is to route incoming messages to actors. - */ -abstract class UntypedDispatcher extends UntypedActor { - protected def transform(msg: Any): Any = msg - - protected def route(msg: Any): ActorRef - - protected def broadcast(message: Any) {} - - private def isSenderDefined = self.senderFuture.isDefined || self.sender.isDefined - - @throws(classOf[Exception]) - def onReceive(msg: Any): Unit = { - if (msg.isInstanceOf[Routing.Broadcast]) broadcast(msg.asInstanceOf[Routing.Broadcast].message) - else { - val r = route(msg) - if (r eq null) throw new IllegalStateException("No route for " + msg + " defined!") - if (isSenderDefined) r.forward(transform(msg))(someSelf) - else r.!(transform(msg))(None) - } - } -} - -/** - * A LoadBalancer is a specialized kind of Dispatcher, that is supplied an InfiniteIterator of targets - * to dispatch incoming messages to. - */ -trait LoadBalancer extends Dispatcher { self: Actor => - protected def seq: InfiniteIterator[ActorRef] - - protected def routes = { - case x if seq.hasNext => seq.next - } - - override def broadcast(message: Any) = seq.items.foreach(_ ! message) - - override def isDefinedAt(msg: Any) = seq.exists(_.isDefinedAt(msg)) -} - -/** - * A UntypedLoadBalancer is a specialized kind of UntypedDispatcher, that is supplied an InfiniteIterator of targets - * to dispatch incoming messages to. - */ -abstract class UntypedLoadBalancer extends UntypedDispatcher { - protected def seq: InfiniteIterator[ActorRef] - - protected def route(msg: Any) = - if (seq.hasNext) seq.next - else null - - override def broadcast(message: Any) = seq.items.foreach(_ ! message) - - override def isDefinedAt(msg: Any) = seq.exists(_.isDefinedAt(msg)) -} diff --git a/test/files/presentation/akka/src/akka/routing/Routing.scala b/test/files/presentation/akka/src/akka/routing/Routing.scala deleted file mode 100644 index befc124248..0000000000 --- a/test/files/presentation/akka/src/akka/routing/Routing.scala +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.routing - -import akka.actor.{ Actor, ActorRef } -import akka.actor.Actor._ - -object Routing { - - sealed trait RoutingMessage - case class Broadcast(message: Any) extends RoutingMessage - - type PF[A, B] = PartialFunction[A, B] - - /** - * Creates a new PartialFunction whose isDefinedAt is a combination - * of the two parameters, and whose apply is first to call filter.apply - * and then filtered.apply. - */ - def filter[A, B](filter: PF[A, Unit], filtered: PF[A, B]): PF[A, B] = { - case a: A if filtered.isDefinedAt(a) && filter.isDefinedAt(a) => - filter(a) - filtered(a) - } - - /** - * Interceptor is a filter(x,y) where x.isDefinedAt is considered to be always true. - */ - def intercept[A, B](interceptor: (A) => Unit, interceptee: PF[A, B]): PF[A, B] = - filter({ case a if a.isInstanceOf[A] => interceptor(a) }, interceptee) - - /** - * Creates a LoadBalancer from the thunk-supplied InfiniteIterator. - */ - def loadBalancerActor(actors: => InfiniteIterator[ActorRef]): ActorRef = - actorOf(new Actor with LoadBalancer { - val seq = actors - }).start() - - /** - * Creates a Dispatcher given a routing and a message-transforming function. - */ - def dispatcherActor(routing: PF[Any, ActorRef], msgTransformer: (Any) => Any): ActorRef = - actorOf(new Actor with Dispatcher { - override def transform(msg: Any) = msgTransformer(msg) - def routes = routing - }).start() - - /** - * Creates a Dispatcher given a routing. - */ - def dispatcherActor(routing: PF[Any, ActorRef]): ActorRef = actorOf(new Actor with Dispatcher { - def routes = routing - }).start() - - /** - * Creates an actor that pipes all incoming messages to - * both another actor and through the supplied function - */ - def loggerActor(actorToLog: ActorRef, logger: (Any) => Unit): ActorRef = - dispatcherActor({ case _ => actorToLog }, logger) -} diff --git a/test/files/presentation/akka/src/akka/util/Address.scala b/test/files/presentation/akka/src/akka/util/Address.scala deleted file mode 100644 index 65b5c0a834..0000000000 --- a/test/files/presentation/akka/src/akka/util/Address.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ -package akka.util - -import java.net.InetSocketAddress - -object Address { - def apply(hostname: String, port: Int) = new Address(hostname, port) - def apply(inetAddress: InetSocketAddress): Address = inetAddress match { - case null => null - case inet => new Address(inet.getAddress.getHostAddress, inet.getPort) - } -} - -class Address(val hostname: String, val port: Int) { - override val hashCode: Int = { - var result = HashCode.SEED - result = HashCode.hash(result, hostname) - result = HashCode.hash(result, port) - result - } - - override def equals(that: Any): Boolean = { - that.isInstanceOf[Address] && - that.asInstanceOf[Address].hostname == hostname && - that.asInstanceOf[Address].port == port - } -} diff --git a/test/files/presentation/akka/src/akka/util/AkkaLoader.scala b/test/files/presentation/akka/src/akka/util/AkkaLoader.scala deleted file mode 100644 index cb246f2ecf..0000000000 --- a/test/files/presentation/akka/src/akka/util/AkkaLoader.scala +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import akka.config.Config -import akka.actor.Actor - -/* - * This class is responsible for booting up a stack of bundles and then shutting them down - */ -class AkkaLoader { - private val hasBooted = new Switch(false) - - @volatile - private var _bundles: Option[Bootable] = None - - def bundles = _bundles; - - /* - * Boot initializes the specified bundles - */ - def boot(withBanner: Boolean, b: Bootable): Unit = hasBooted switchOn { - if (withBanner) printBanner() - println("Starting Akka...") - b.onLoad - Thread.currentThread.setContextClassLoader(getClass.getClassLoader) - _bundles = Some(b) - println("Akka started successfully") - } - - /* - * Shutdown, well, shuts down the bundles used in boot - */ - def shutdown() { - hasBooted switchOff { - println("Shutting down Akka...") - _bundles.foreach(_.onUnload) - _bundles = None - Actor.shutdownHook.run - println("Akka succesfully shut down") - } - } - - private def printBanner() { - println(""" -============================================================================== - - ZZ: - ZZZZ - ZZZZZZ - ZZZ' ZZZ - ~7 7ZZ' ZZZ - :ZZZ: IZZ' ZZZ - ,OZZZZ.~ZZ? ZZZ - ZZZZ' 'ZZZ$ ZZZ - . $ZZZ ~ZZ$ ZZZ - .=Z?. .ZZZO ~ZZ7 OZZ - .ZZZZ7..:ZZZ~ 7ZZZ ZZZ~ - .$ZZZ$Z+.ZZZZ ZZZ: ZZZ$ - .,ZZZZ?' =ZZO= .OZZ 'ZZZ - .$ZZZZ+ .ZZZZ IZZZ ZZZ$ - .ZZZZZ' .ZZZZ' .ZZZ$ ?ZZZ - .ZZZZZZ' .OZZZ? ?ZZZ 'ZZZ$ - .?ZZZZZZ' .ZZZZ? .ZZZ? 'ZZZO - .+ZZZZZZ?' .7ZZZZ' .ZZZZ :ZZZZ - .ZZZZZZ$' .?ZZZZZ' .~ZZZZ 'ZZZZ. - - - NNNNN $NNNN+ - NNNNN $NNNN+ - NNNNN $NNNN+ - NNNNN $NNNN+ - NNNNN $NNNN+ - =NNNNNNNNND$ NNNNN DDDDDD: $NNNN+ DDDDDN NDDNNNNNNNN, - NNNNNNNNNNNNND NNNNN DNNNNN $NNNN+ 8NNNNN= :NNNNNNNNNNNNNN - NNNNN$ DNNNNN NNNNN $NNNNN~ $NNNN+ NNNNNN NNNNN, :NNNNN+ - ?DN~ NNNNN NNNNN MNNNNN $NNNN+:NNNNN7 $ND =NNNNN - DNNNNN NNNNNDNNNN$ $NNNNDNNNNN :DNNNNN - ZNDNNNNNNNNND NNNNNNNNNND, $NNNNNNNNNNN DNDNNNNNNNNNN - NNNNNNNDDINNNNN NNNNNNNNNNND $NNNNNNNNNNND ONNNNNNND8+NNNNN - :NNNND NNNNN NNNNNN DNNNN, $NNNNNO 7NNNND NNNNNO :NNNNN - DNNNN NNNNN NNNNN DNNNN $NNNN+ 8NNNNN NNNNN $NNNNN - DNNNNO NNNNNN NNNNN NNNNN $NNNN+ NNNNN$ NNNND, ,NNNNND - NNNNNNDDNNNNNNNN NNNNN =NNNNN $NNNN+ DNNNN? DNNNNNNDNNNNNNNND - NNNNNNNNN NNNN$ NNNNN 8NNNND $NNNN+ NNNNN= ,DNNNNNNND NNNNN$ - -============================================================================== - Running version %s -============================================================================== -""".format(Config.VERSION)) - } -} diff --git a/test/files/presentation/akka/src/akka/util/Bootable.scala b/test/files/presentation/akka/src/akka/util/Bootable.scala deleted file mode 100644 index d07643e1ac..0000000000 --- a/test/files/presentation/akka/src/akka/util/Bootable.scala +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -trait Bootable { - def onLoad() {} - def onUnload() {} -} diff --git a/test/files/presentation/akka/src/akka/util/BoundedBlockingQueue.scala b/test/files/presentation/akka/src/akka/util/BoundedBlockingQueue.scala deleted file mode 100644 index f8deda746c..0000000000 --- a/test/files/presentation/akka/src/akka/util/BoundedBlockingQueue.scala +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.util.concurrent.locks.ReentrantLock -import java.util.concurrent.{ TimeUnit, BlockingQueue } -import java.util.{ AbstractQueue, Queue, Collection, Iterator } - -class BoundedBlockingQueue[E <: AnyRef]( - val maxCapacity: Int, private val backing: Queue[E]) extends AbstractQueue[E] with BlockingQueue[E] { - - backing match { - case null => throw new IllegalArgumentException("Backing Queue may not be null") - case b: BlockingQueue[_] => - require(maxCapacity > 0) - require(b.size() == 0) - require(b.remainingCapacity >= maxCapacity) - case b: Queue[_] => - require(b.size() == 0) - require(maxCapacity > 0) - } - - protected val lock = new ReentrantLock(false) - - private val notEmpty = lock.newCondition() - private val notFull = lock.newCondition() - - def put(e: E): Unit = { //Blocks until not full - if (e eq null) throw new NullPointerException - lock.lock() - try { - while (backing.size() == maxCapacity) - notFull.await() - require(backing.offer(e)) - notEmpty.signal() - } finally { - lock.unlock() - } - } - - def take(): E = { //Blocks until not empty - lock.lockInterruptibly() - try { - while (backing.size() == 0) - notEmpty.await() - val e = backing.poll() - require(e ne null) - notFull.signal() - e - } finally { - lock.unlock() - } - } - - def offer(e: E): Boolean = { //Tries to do it immediately, if fail return false - if (e eq null) throw new NullPointerException - lock.lock() - try { - if (backing.size() == maxCapacity) false - else { - require(backing.offer(e)) //Should never fail - notEmpty.signal() - true - } - } finally { - lock.unlock() - } - } - - def offer(e: E, timeout: Long, unit: TimeUnit): Boolean = { //Tries to do it within the timeout, return false if fail - if (e eq null) throw new NullPointerException - var nanos = unit.toNanos(timeout) - lock.lockInterruptibly() - try { - while (backing.size() == maxCapacity) { - if (nanos <= 0) - return false - else - nanos = notFull.awaitNanos(nanos) - } - require(backing.offer(e)) //Should never fail - notEmpty.signal() - true - } finally { - lock.unlock() - } - } - - def poll(timeout: Long, unit: TimeUnit): E = { //Tries to do it within the timeout, returns null if fail - var nanos = unit.toNanos(timeout) - lock.lockInterruptibly() - try { - var result: E = null.asInstanceOf[E] - var hasResult = false - while (!hasResult) { - hasResult = backing.poll() match { - case null if nanos <= 0 => - result = null.asInstanceOf[E] - true - case null => - try { - nanos = notEmpty.awaitNanos(nanos) - } catch { - case ie: InterruptedException => - notEmpty.signal() - throw ie - } - false - case e => - notFull.signal() - result = e - true - } - } - result - } finally { - lock.unlock() - } - } - - def poll(): E = { //Tries to remove the head of the queue immediately, if fail, return null - lock.lock() - try { - backing.poll() match { - case null => null.asInstanceOf[E] - case e => - notFull.signal() - e - } - } finally { - lock.unlock - } - } - - override def remove(e: AnyRef): Boolean = { //Tries to do it immediately, if fail, return false - if (e eq null) throw new NullPointerException - lock.lock() - try { - if (backing remove e) { - notFull.signal() - true - } else false - } finally { - lock.unlock() - } - } - - override def contains(e: AnyRef): Boolean = { - if (e eq null) throw new NullPointerException - lock.lock() - try { - backing contains e - } finally { - lock.unlock() - } - } - - override def clear(): Unit = { - lock.lock() - try { - backing.clear - } finally { - lock.unlock() - } - } - - def remainingCapacity(): Int = { - lock.lock() - try { - maxCapacity - backing.size() - } finally { - lock.unlock() - } - } - - def size(): Int = { - lock.lock() - try { - backing.size() - } finally { - lock.unlock() - } - } - - def peek(): E = { - lock.lock() - try { - backing.peek() - } finally { - lock.unlock() - } - } - - def drainTo(c: Collection[_ >: E]): Int = drainTo(c, Int.MaxValue) - - def drainTo(c: Collection[_ >: E], maxElements: Int): Int = { - if (c eq null) throw new NullPointerException - if (c eq this) throw new IllegalArgumentException - if (maxElements <= 0) 0 - else { - lock.lock() - try { - var n = 0 - var e: E = null.asInstanceOf[E] - while (n < maxElements) { - backing.poll() match { - case null => return n - case e => - c add e - n += 1 - } - } - n - } finally { - lock.unlock() - } - } - } - - override def containsAll(c: Collection[_]): Boolean = { - lock.lock() - try { - backing containsAll c - } finally { - lock.unlock() - } - } - - override def removeAll(c: Collection[_]): Boolean = { - lock.lock() - try { - if (backing.removeAll(c)) { - val sz = backing.size() - if (sz < maxCapacity) notFull.signal() - if (sz > 0) notEmpty.signal() //FIXME needed? - true - } else false - } finally { - lock.unlock() - } - } - - override def retainAll(c: Collection[_]): Boolean = { - lock.lock() - try { - if (backing.retainAll(c)) { - val sz = backing.size() - if (sz < maxCapacity) notFull.signal() //FIXME needed? - if (sz > 0) notEmpty.signal() - true - } else false - } finally { - lock.unlock() - } - } - - def iterator(): Iterator[E] = { - lock.lock - try { - val elements = backing.toArray - new Iterator[E] { - var at = 0 - var last = -1 - - def hasNext(): Boolean = at < elements.length - - def next(): E = { - if (at >= elements.length) throw new NoSuchElementException - last = at - at += 1 - elements(last).asInstanceOf[E] - } - - def remove(): Unit = { - if (last < 0) throw new IllegalStateException - val target = elements(last) - last = -1 //To avoid 2 subsequent removes without a next in between - lock.lock() - try { - val i = backing.iterator() - while (i.hasNext) { - if (i.next eq target) { - i.remove() - notFull.signal() - return () - } - } - } finally { - lock.unlock() - } - } - } - } finally { - lock.unlock - } - } - - override def toArray(): Array[AnyRef] = { - lock.lock() - try { - backing.toArray - } finally { - lock.unlock() - } - } - - override def isEmpty(): Boolean = { - lock.lock() - try { - backing.isEmpty() - } finally { - lock.unlock() - } - } - - override def toArray[X](a: Array[X with AnyRef]) = { - lock.lock() - try { - backing.toArray[X](a) - } finally { - lock.unlock() - } - } -} diff --git a/test/files/presentation/akka/src/akka/util/Crypt.scala b/test/files/presentation/akka/src/akka/util/Crypt.scala deleted file mode 100644 index 3ce2d559a2..0000000000 --- a/test/files/presentation/akka/src/akka/util/Crypt.scala +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.security.{ MessageDigest, SecureRandom } - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Crypt { - val hex = "0123456789ABCDEF" - val lineSeparator = System.getProperty("line.separator") - - lazy val random = SecureRandom.getInstance("SHA1PRNG") - - def md5(text: String): String = md5(unifyLineSeparator(text).getBytes("ASCII")) - - def md5(bytes: Array[Byte]): String = digest(bytes, MessageDigest.getInstance("MD5")) - - def sha1(text: String): String = sha1(unifyLineSeparator(text).getBytes("ASCII")) - - def sha1(bytes: Array[Byte]): String = digest(bytes, MessageDigest.getInstance("SHA1")) - - def generateSecureCookie: String = { - val bytes = Array.fill(32)(0.byteValue) - random.nextBytes(bytes) - sha1(bytes) - } - - def digest(bytes: Array[Byte], md: MessageDigest): String = { - md.update(bytes) - hexify(md.digest) - } - - def hexify(bytes: Array[Byte]): String = { - val builder = new StringBuilder - bytes.foreach { byte => builder.append(hex.charAt((byte & 0xF) >> 4)).append(hex.charAt(byte & 0xF)) } - builder.toString - } - - private def unifyLineSeparator(text: String): String = text.replaceAll(lineSeparator, "\n") -} diff --git a/test/files/presentation/akka/src/akka/util/Duration.scala b/test/files/presentation/akka/src/akka/util/Duration.scala deleted file mode 100644 index 316cb86689..0000000000 --- a/test/files/presentation/akka/src/akka/util/Duration.scala +++ /dev/null @@ -1,437 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.util.concurrent.TimeUnit -import TimeUnit._ -import java.lang.{ Long => JLong, Double => JDouble } - -object Duration { - def apply(length: Long, unit: TimeUnit): Duration = new FiniteDuration(length, unit) - def apply(length: Double, unit: TimeUnit): Duration = fromNanos(unit.toNanos(1) * length) - def apply(length: Long, unit: String): Duration = new FiniteDuration(length, timeUnit(unit)) - - def fromNanos(nanos: Long): Duration = { - if (nanos % 86400000000000L == 0) { - Duration(nanos / 86400000000000L, DAYS) - } else if (nanos % 3600000000000L == 0) { - Duration(nanos / 3600000000000L, HOURS) - } else if (nanos % 60000000000L == 0) { - Duration(nanos / 60000000000L, MINUTES) - } else if (nanos % 1000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) - } else if (nanos % 1000000L == 0) { - Duration(nanos / 1000000L, MILLISECONDS) - } else if (nanos % 1000L == 0) { - Duration(nanos / 1000L, MICROSECONDS) - } else { - Duration(nanos, NANOSECONDS) - } - } - - def fromNanos(nanos: Double): Duration = fromNanos((nanos + 0.5).asInstanceOf[Long]) - - /** - * Construct a Duration by parsing a String. In case of a format error, a - * RuntimeException is thrown. See `unapply(String)` for more information. - */ - def apply(s: String): Duration = unapply(s) getOrElse sys.error("format error") - - /** - * Deconstruct a Duration into length and unit if it is finite. - */ - def unapply(d: Duration): Option[(Long, TimeUnit)] = { - if (d.finite_?) { - Some((d.length, d.unit)) - } else { - None - } - } - - private val RE = ("""^\s*(\d+(?:\.\d+)?)\s*""" + // length part - "(?:" + // units are distinguished in separate match groups - "(d|day|days)|" + - "(h|hour|hours)|" + - "(min|minute|minutes)|" + - "(s|sec|second|seconds)|" + - "(ms|milli|millis|millisecond|milliseconds)|" + - "(µs|micro|micros|microsecond|microseconds)|" + - "(ns|nano|nanos|nanosecond|nanoseconds)" + - """)\s*$""").r // close the non-capturing group - private val REinf = """^\s*Inf\s*$""".r - private val REminf = """^\s*(?:-\s*|Minus)Inf\s*""".r - - /** - * Parse String, return None if no match. Format is `"<length><unit>"`, where - * whitespace is allowed before, between and after the parts. Infinities are - * designated by `"Inf"` and `"-Inf"` or `"MinusInf"`. - */ - def unapply(s: String): Option[Duration] = s match { - case RE(length, d, h, m, s, ms, mus, ns) => - if (d ne null) Some(Duration(JDouble.parseDouble(length), DAYS)) else if (h ne null) Some(Duration(JDouble.parseDouble(length), HOURS)) else if (m ne null) Some(Duration(JDouble.parseDouble(length), MINUTES)) else if (s ne null) Some(Duration(JDouble.parseDouble(length), SECONDS)) else if (ms ne null) Some(Duration(JDouble.parseDouble(length), MILLISECONDS)) else if (mus ne null) Some(Duration(JDouble.parseDouble(length), MICROSECONDS)) else if (ns ne null) Some(Duration(JDouble.parseDouble(length), NANOSECONDS)) else - sys.error("made some error in regex (should not be possible)") - case REinf() => Some(Inf) - case REminf() => Some(MinusInf) - case _ => None - } - - /** - * Parse TimeUnit from string representation. - */ - def timeUnit(unit: String) = unit.toLowerCase match { - case "d" | "day" | "days" => DAYS - case "h" | "hour" | "hours" => HOURS - case "min" | "minute" | "minutes" => MINUTES - case "s" | "sec" | "second" | "seconds" => SECONDS - case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" => MILLISECONDS - case "µs" | "micro" | "micros" | "microsecond" | "microseconds" => MICROSECONDS - case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" => NANOSECONDS - } - - val Zero: Duration = new FiniteDuration(0, NANOSECONDS) - - trait Infinite { - this: Duration => - - override def equals(other: Any) = false - - def +(other: Duration): Duration = - other match { - case _: this.type => this - case _: Infinite => throw new IllegalArgumentException("illegal addition of infinities") - case _ => this - } - def -(other: Duration): Duration = - other match { - case _: this.type => throw new IllegalArgumentException("illegal subtraction of infinities") - case _ => this - } - def *(factor: Double): Duration = this - def /(factor: Double): Duration = this - def /(other: Duration): Double = - other match { - case _: Infinite => throw new IllegalArgumentException("illegal division of infinities") - // maybe questionable but pragmatic: Inf / 0 => Inf - case x => Double.PositiveInfinity * (if ((this > Zero) ^ (other >= Zero)) -1 else 1) - } - - def finite_? = false - - def length: Long = throw new IllegalArgumentException("length not allowed on infinite Durations") - def unit: TimeUnit = throw new IllegalArgumentException("unit not allowed on infinite Durations") - def toNanos: Long = throw new IllegalArgumentException("toNanos not allowed on infinite Durations") - def toMicros: Long = throw new IllegalArgumentException("toMicros not allowed on infinite Durations") - def toMillis: Long = throw new IllegalArgumentException("toMillis not allowed on infinite Durations") - def toSeconds: Long = throw new IllegalArgumentException("toSeconds not allowed on infinite Durations") - def toMinutes: Long = throw new IllegalArgumentException("toMinutes not allowed on infinite Durations") - def toHours: Long = throw new IllegalArgumentException("toHours not allowed on infinite Durations") - def toDays: Long = throw new IllegalArgumentException("toDays not allowed on infinite Durations") - def toUnit(unit: TimeUnit): Double = throw new IllegalArgumentException("toUnit not allowed on infinite Durations") - - def printHMS = toString - } - - /** - * Infinite duration: greater than any other and not equal to any other, - * including itself. - */ - val Inf: Duration = new Duration with Infinite { - override def toString = "Duration.Inf" - def >(other: Duration) = true - def >=(other: Duration) = true - def <(other: Duration) = false - def <=(other: Duration) = false - def unary_- : Duration = MinusInf - } - - /** - * Infinite negative duration: lesser than any other and not equal to any other, - * including itself. - */ - val MinusInf: Duration = new Duration with Infinite { - override def toString = "Duration.MinusInf" - def >(other: Duration) = false - def >=(other: Duration) = false - def <(other: Duration) = true - def <=(other: Duration) = true - def unary_- : Duration = Inf - } - - // Java Factories - def create(length: Long, unit: TimeUnit): Duration = apply(length, unit) - def create(length: Double, unit: TimeUnit): Duration = apply(length, unit) - def create(length: Long, unit: String): Duration = apply(length, unit) - def parse(s: String): Duration = unapply(s).get -} - -/** - * Utility for working with java.util.concurrent.TimeUnit durations. - * - * <p/> - * Examples of usage from Java: - * <pre> - * import akka.util.FiniteDuration; - * import java.util.concurrent.TimeUnit; - * - * Duration duration = new FiniteDuration(100, MILLISECONDS); - * Duration duration = new FiniteDuration(5, "seconds"); - * - * duration.toNanos(); - * </pre> - * - * <p/> - * Examples of usage from Scala: - * <pre> - * import akka.util.Duration - * import java.util.concurrent.TimeUnit - * - * val duration = Duration(100, MILLISECONDS) - * val duration = Duration(100, "millis") - * - * duration.toNanos - * duration < 1.second - * duration <= Duration.Inf - * </pre> - * - * <p/> - * Implicits are also provided for Int, Long and Double. Example usage: - * <pre> - * import akka.util.duration._ - * - * val duration = 100 millis - * </pre> - * - * Extractors, parsing and arithmetic are also included: - * <pre> - * val d = Duration("1.2 µs") - * val Duration(length, unit) = 5 millis - * val d2 = d * 2.5 - * val d3 = d2 + 1.millisecond - * </pre> - */ -abstract class Duration { - def length: Long - def unit: TimeUnit - def toNanos: Long - def toMicros: Long - def toMillis: Long - def toSeconds: Long - def toMinutes: Long - def toHours: Long - def toDays: Long - def toUnit(unit: TimeUnit): Double - def printHMS: String - def <(other: Duration): Boolean - def <=(other: Duration): Boolean - def >(other: Duration): Boolean - def >=(other: Duration): Boolean - def +(other: Duration): Duration - def -(other: Duration): Duration - def *(factor: Double): Duration - def /(factor: Double): Duration - def /(other: Duration): Double - def unary_- : Duration - def finite_? : Boolean - - // Java API - def lt(other: Duration) = this < other - def lteq(other: Duration) = this <= other - def gt(other: Duration) = this > other - def gteq(other: Duration) = this >= other - def plus(other: Duration) = this + other - def minus(other: Duration) = this - other - def mul(factor: Double) = this * factor - def div(factor: Double) = this / factor - def div(other: Duration) = this / other - def neg() = -this - def isFinite() = finite_? -} - -class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration { - import Duration._ - - def this(length: Long, unit: String) = this(length, Duration.timeUnit(unit)) - - def toNanos = unit.toNanos(length) - def toMicros = unit.toMicros(length) - def toMillis = unit.toMillis(length) - def toSeconds = unit.toSeconds(length) - def toMinutes = unit.toMinutes(length) - def toHours = unit.toHours(length) - def toDays = unit.toDays(length) - def toUnit(u: TimeUnit) = long2double(toNanos) / NANOSECONDS.convert(1, u) - - override def toString = this match { - case Duration(1, DAYS) => "1 day" - case Duration(x, DAYS) => x + " days" - case Duration(1, HOURS) => "1 hour" - case Duration(x, HOURS) => x + " hours" - case Duration(1, MINUTES) => "1 minute" - case Duration(x, MINUTES) => x + " minutes" - case Duration(1, SECONDS) => "1 second" - case Duration(x, SECONDS) => x + " seconds" - case Duration(1, MILLISECONDS) => "1 millisecond" - case Duration(x, MILLISECONDS) => x + " milliseconds" - case Duration(1, MICROSECONDS) => "1 microsecond" - case Duration(x, MICROSECONDS) => x + " microseconds" - case Duration(1, NANOSECONDS) => "1 nanosecond" - case Duration(x, NANOSECONDS) => x + " nanoseconds" - } - - def printHMS = "%02d:%02d:%06.3f".format(toHours, toMinutes % 60, toMillis / 1000. % 60) - - def <(other: Duration) = { - if (other.finite_?) { - toNanos < other.asInstanceOf[FiniteDuration].toNanos - } else { - other > this - } - } - - def <=(other: Duration) = { - if (other.finite_?) { - toNanos <= other.asInstanceOf[FiniteDuration].toNanos - } else { - other >= this - } - } - - def >(other: Duration) = { - if (other.finite_?) { - toNanos > other.asInstanceOf[FiniteDuration].toNanos - } else { - other < this - } - } - - def >=(other: Duration) = { - if (other.finite_?) { - toNanos >= other.asInstanceOf[FiniteDuration].toNanos - } else { - other <= this - } - } - - def +(other: Duration) = { - if (!other.finite_?) { - other - } else { - val nanos = toNanos + other.asInstanceOf[FiniteDuration].toNanos - fromNanos(nanos) - } - } - - def -(other: Duration) = { - if (!other.finite_?) { - other - } else { - val nanos = toNanos - other.asInstanceOf[FiniteDuration].toNanos - fromNanos(nanos) - } - } - - def *(factor: Double) = fromNanos(long2double(toNanos) * factor) - - def /(factor: Double) = fromNanos(long2double(toNanos) / factor) - - def /(other: Duration) = if (other.finite_?) long2double(toNanos) / other.toNanos else 0 - - def unary_- = Duration(-length, unit) - - def finite_? = true - - override def equals(other: Any) = - other.isInstanceOf[FiniteDuration] && - toNanos == other.asInstanceOf[FiniteDuration].toNanos - - override def hashCode = toNanos.asInstanceOf[Int] -} - -class DurationInt(n: Int) { - def nanoseconds = Duration(n, NANOSECONDS) - def nanos = Duration(n, NANOSECONDS) - def nanosecond = Duration(n, NANOSECONDS) - def nano = Duration(n, NANOSECONDS) - - def microseconds = Duration(n, MICROSECONDS) - def micros = Duration(n, MICROSECONDS) - def microsecond = Duration(n, MICROSECONDS) - def micro = Duration(n, MICROSECONDS) - - def milliseconds = Duration(n, MILLISECONDS) - def millis = Duration(n, MILLISECONDS) - def millisecond = Duration(n, MILLISECONDS) - def milli = Duration(n, MILLISECONDS) - - def seconds = Duration(n, SECONDS) - def second = Duration(n, SECONDS) - - def minutes = Duration(n, MINUTES) - def minute = Duration(n, MINUTES) - - def hours = Duration(n, HOURS) - def hour = Duration(n, HOURS) - - def days = Duration(n, DAYS) - def day = Duration(n, DAYS) -} - -class DurationLong(n: Long) { - def nanoseconds = Duration(n, NANOSECONDS) - def nanos = Duration(n, NANOSECONDS) - def nanosecond = Duration(n, NANOSECONDS) - def nano = Duration(n, NANOSECONDS) - - def microseconds = Duration(n, MICROSECONDS) - def micros = Duration(n, MICROSECONDS) - def microsecond = Duration(n, MICROSECONDS) - def micro = Duration(n, MICROSECONDS) - - def milliseconds = Duration(n, MILLISECONDS) - def millis = Duration(n, MILLISECONDS) - def millisecond = Duration(n, MILLISECONDS) - def milli = Duration(n, MILLISECONDS) - - def seconds = Duration(n, SECONDS) - def second = Duration(n, SECONDS) - - def minutes = Duration(n, MINUTES) - def minute = Duration(n, MINUTES) - - def hours = Duration(n, HOURS) - def hour = Duration(n, HOURS) - - def days = Duration(n, DAYS) - def day = Duration(n, DAYS) -} - -class DurationDouble(d: Double) { - def nanoseconds = Duration(d, NANOSECONDS) - def nanos = Duration(d, NANOSECONDS) - def nanosecond = Duration(d, NANOSECONDS) - def nano = Duration(d, NANOSECONDS) - - def microseconds = Duration(d, MICROSECONDS) - def micros = Duration(d, MICROSECONDS) - def microsecond = Duration(d, MICROSECONDS) - def micro = Duration(d, MICROSECONDS) - - def milliseconds = Duration(d, MILLISECONDS) - def millis = Duration(d, MILLISECONDS) - def millisecond = Duration(d, MILLISECONDS) - def milli = Duration(d, MILLISECONDS) - - def seconds = Duration(d, SECONDS) - def second = Duration(d, SECONDS) - - def minutes = Duration(d, MINUTES) - def minute = Duration(d, MINUTES) - - def hours = Duration(d, HOURS) - def hour = Duration(d, HOURS) - - def days = Duration(d, DAYS) - def day = Duration(d, DAYS) -} diff --git a/test/files/presentation/akka/src/akka/util/HashCode.scala b/test/files/presentation/akka/src/akka/util/HashCode.scala deleted file mode 100644 index d015f12f5d..0000000000 --- a/test/files/presentation/akka/src/akka/util/HashCode.scala +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.lang.reflect.{ Array => JArray } -import java.lang.{ Float => JFloat, Double => JDouble } - -/** - * Set of methods which allow easy implementation of <code>hashCode</code>. - * - * Example: - * <pre> - * override def hashCode: Int = { - * var result = HashCode.SEED - * //collect the contributions of various fields - * result = HashCode.hash(result, fPrimitive) - * result = HashCode.hash(result, fObject) - * result = HashCode.hash(result, fArray) - * result - * } - * </pre> - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object HashCode { - val SEED = 23 - - def hash(seed: Int, any: Any): Int = any match { - case value: Boolean => hash(seed, value) - case value: Char => hash(seed, value) - case value: Short => hash(seed, value) - case value: Int => hash(seed, value) - case value: Long => hash(seed, value) - case value: Float => hash(seed, value) - case value: Double => hash(seed, value) - case value: Byte => hash(seed, value) - case value: AnyRef => - var result = seed - if (value eq null) result = hash(result, 0) - else if (!isArray(value)) result = hash(result, value.hashCode()) - else for (id ← 0 until JArray.getLength(value)) result = hash(result, JArray.get(value, id)) // is an array - result - } - def hash(seed: Int, value: Boolean): Int = firstTerm(seed) + (if (value) 1 else 0) - def hash(seed: Int, value: Char): Int = firstTerm(seed) + value.asInstanceOf[Int] - def hash(seed: Int, value: Int): Int = firstTerm(seed) + value - def hash(seed: Int, value: Long): Int = firstTerm(seed) + (value ^ (value >>> 32)).asInstanceOf[Int] - def hash(seed: Int, value: Float): Int = hash(seed, JFloat.floatToIntBits(value)) - def hash(seed: Int, value: Double): Int = hash(seed, JDouble.doubleToLongBits(value)) - - private def firstTerm(seed: Int): Int = PRIME * seed - private def isArray(anyRef: AnyRef): Boolean = anyRef.getClass.isArray - private val PRIME = 37 -} - diff --git a/test/files/presentation/akka/src/akka/util/Helpers.scala b/test/files/presentation/akka/src/akka/util/Helpers.scala deleted file mode 100644 index 48477426c9..0000000000 --- a/test/files/presentation/akka/src/akka/util/Helpers.scala +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object Helpers { - - implicit def null2Option[T](t: T): Option[T] = Option(t) - - def intToBytes(value: Int): Array[Byte] = { - val bytes = new Array[Byte](4) - bytes(0) = (value >>> 24).asInstanceOf[Byte] - bytes(1) = (value >>> 16).asInstanceOf[Byte] - bytes(2) = (value >>> 8).asInstanceOf[Byte] - bytes(3) = value.asInstanceOf[Byte] - bytes - } - - def bytesToInt(bytes: Array[Byte], offset: Int): Int = { - (0 until 4).foldLeft(0)((value, index) => value + ((bytes(index + offset) & 0x000000FF) << ((4 - 1 - index) * 8))) - } - - /** - * Convenience helper to cast the given Option of Any to an Option of the given type. Will throw a ClassCastException - * if the actual type is not assignable from the given one. - */ - def narrow[T](o: Option[Any]): Option[T] = { - require((o ne null), "Option to be narrowed must not be null!") - o.asInstanceOf[Option[T]] - } - - /** - * Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible - * ClassCastException and return None in that case. - */ - def narrowSilently[T: Manifest](o: Option[Any]): Option[T] = - try { - narrow(o) - } catch { - case e: ClassCastException => - None - } - - /** - * Reference that can hold either a typed value or an exception. - * - * Usage: - * <pre> - * scala> ResultOrError(1) - * res0: ResultOrError[Int] = ResultOrError@a96606 - * - * scala> res0() - * res1: Int = 1 - * - * scala> res0() = 3 - * - * scala> res0() - * res3: Int = 3 - * - * scala> res0() = { println("Hello world"); 3} - * Hello world - * - * scala> res0() - * res5: Int = 3 - * - * scala> res0() = error("Lets see what happens here...") - * - * scala> res0() - * java.lang.RuntimeException: Lets see what happens here... - * at ResultOrError.apply(Helper.scala:11) - * at .<init>(<console>:6) - * at .<clinit>(<console>) - * at Re... - * </pre> - */ - class ResultOrError[R](result: R) { - private[this] var contents: Either[R, Throwable] = Left(result) - - def update(value: => R) = { - contents = try { - Left(value) - } catch { - case (error: Throwable) => Right(error) - } - } - - def apply() = contents match { - case Left(result) => result - case Right(error) => throw error.fillInStackTrace - } - } - object ResultOrError { - def apply[R](result: R) = new ResultOrError(result) - } -} diff --git a/test/files/presentation/akka/src/akka/util/ListenerManagement.scala b/test/files/presentation/akka/src/akka/util/ListenerManagement.scala deleted file mode 100644 index 7065397a45..0000000000 --- a/test/files/presentation/akka/src/akka/util/ListenerManagement.scala +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.util.concurrent.ConcurrentSkipListSet -import akka.actor.{ ActorInitializationException, ActorRef } - -/** - * A manager for listener actors. Intended for mixin by observables. - * - * @author Martin Krasser - */ -trait ListenerManagement { - - private val listeners = new ConcurrentSkipListSet[ActorRef] - - /** - * Specifies whether listeners should be started when added and stopped when removed or not - */ - protected def manageLifeCycleOfListeners: Boolean = true - - /** - * Adds the <code>listener</code> this this registry's listener list. - * The <code>listener</code> is started by this method if manageLifeCycleOfListeners yields true. - */ - def addListener(listener: ActorRef) { - if (manageLifeCycleOfListeners) listener.start() - listeners add listener - } - - /** - * Removes the <code>listener</code> this this registry's listener list. - * The <code>listener</code> is stopped by this method if manageLifeCycleOfListeners yields true. - */ - def removeListener(listener: ActorRef) { - listeners remove listener - if (manageLifeCycleOfListeners) listener.stop() - } - - /* - * Returns whether there are any listeners currently - */ - def hasListeners: Boolean = !listeners.isEmpty - - /** - * Checks if a specific listener is registered. ActorInitializationException leads to removal of listener if that - * one isShutdown. - */ - def hasListener(listener: ActorRef): Boolean = listeners.contains(listener) - - protected[akka] def notifyListeners(message: => Any) { - if (hasListeners) { - val msg = message - val iterator = listeners.iterator - while (iterator.hasNext) { - val listener = iterator.next - // Uncomment if those exceptions are so frequent as to bottleneck - // if (listener.isShutdown) iterator.remove() else - try { - listener ! msg - } catch { - case e: ActorInitializationException => - if (listener.isShutdown) iterator.remove() - } - } - } - } - - /** - * Execute <code>f</code> with each listener as argument. ActorInitializationException is not handled. - */ - protected[akka] def foreachListener(f: (ActorRef) => Unit) { - val iterator = listeners.iterator - while (iterator.hasNext) { - val listener = iterator.next - if (listener.isRunning) f(listener) - } - } -} diff --git a/test/files/presentation/akka/src/akka/util/LockUtil.scala b/test/files/presentation/akka/src/akka/util/LockUtil.scala deleted file mode 100644 index 4aaefadc4a..0000000000 --- a/test/files/presentation/akka/src/akka/util/LockUtil.scala +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.util.concurrent.locks.{ ReentrantReadWriteLock, ReentrantLock } -import java.util.concurrent.atomic.{ AtomicBoolean } -import akka.event.EventHandler - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -final class ReentrantGuard { - val lock = new ReentrantLock - - final def withGuard[T](body: => T): T = { - lock.lock - try { - body - } finally { - lock.unlock - } - } - - final def tryWithGuard[T](body: => T): T = { - while (!lock.tryLock) { Thread.sleep(10) } // wait on the monitor to be unlocked - try { - body - } finally { - lock.unlock - } - } -} - -/** - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -class ReadWriteGuard { - private val rwl = new ReentrantReadWriteLock - val readLock = rwl.readLock - val writeLock = rwl.writeLock - - def withWriteGuard[T](body: => T): T = { - writeLock.lock - try { - body - } finally { - writeLock.unlock - } - } - - def withReadGuard[T](body: => T): T = { - readLock.lock - try { - body - } finally { - readLock.unlock - } - } -} - -/** - * A very simple lock that uses CCAS (Compare Compare-And-Swap) - * Does not keep track of the owner and isn't Reentrant, so don't nest and try to stick to the if*-methods - */ -class SimpleLock { - val acquired = new AtomicBoolean(false) - - def ifPossible(perform: () => Unit): Boolean = { - if (tryLock()) { - try { - perform - } finally { - unlock() - } - true - } else false - } - - def ifPossibleYield[T](perform: () => T): Option[T] = { - if (tryLock()) { - try { - Some(perform()) - } finally { - unlock() - } - } else None - } - - def ifPossibleApply[T, R](value: T)(function: (T) => R): Option[R] = { - if (tryLock()) { - try { - Some(function(value)) - } finally { - unlock() - } - } else None - } - - def tryLock() = { - if (acquired.get) false - else acquired.compareAndSet(false, true) - } - - def tryUnlock() = { - acquired.compareAndSet(true, false) - } - - def locked = acquired.get - - def unlock() { - acquired.set(false) - } -} - -/** - * An atomic switch that can be either on or off - */ -class Switch(startAsOn: Boolean = false) { - private val switch = new AtomicBoolean(startAsOn) - - protected def transcend(from: Boolean, action: => Unit): Boolean = synchronized { - if (switch.compareAndSet(from, !from)) { - try { - action - } catch { - case e: Throwable => - EventHandler.error(e, this, e.getMessage) - switch.compareAndSet(!from, from) // revert status - throw e - } - true - } else false - } - - def switchOff(action: => Unit): Boolean = transcend(from = true, action) - def switchOn(action: => Unit): Boolean = transcend(from = false, action) - - def switchOff: Boolean = synchronized { switch.compareAndSet(true, false) } - def switchOn: Boolean = synchronized { switch.compareAndSet(false, true) } - - def ifOnYield[T](action: => T): Option[T] = { - if (switch.get) Some(action) - else None - } - - def ifOffYield[T](action: => T): Option[T] = { - if (!switch.get) Some(action) - else None - } - - def ifOn(action: => Unit): Boolean = { - if (switch.get) { - action - true - } else false - } - - def ifOff(action: => Unit): Boolean = { - if (!switch.get) { - action - true - } else false - } - - def whileOnYield[T](action: => T): Option[T] = synchronized { - if (switch.get) Some(action) - else None - } - - def whileOffYield[T](action: => T): Option[T] = synchronized { - if (!switch.get) Some(action) - else None - } - - def whileOn(action: => Unit): Boolean = synchronized { - if (switch.get) { - action - true - } else false - } - - def whileOff(action: => Unit): Boolean = synchronized { - if (switch.get) { - action - true - } else false - } - - def ifElseYield[T](on: => T)(off: => T) = synchronized { - if (switch.get) on else off - } - - def isOn = switch.get - def isOff = !isOn -} diff --git a/test/files/presentation/akka/src/akka/util/ReflectiveAccess.scala b/test/files/presentation/akka/src/akka/util/ReflectiveAccess.scala deleted file mode 100644 index f38d1f9b98..0000000000 --- a/test/files/presentation/akka/src/akka/util/ReflectiveAccess.scala +++ /dev/null @@ -1,232 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import akka.dispatch.{ Future, CompletableFuture, MessageInvocation } -import akka.config.{ Config, ModuleNotAvailableException } - -import java.net.InetSocketAddress -import akka.remoteinterface.RemoteSupport -import akka.actor._ -import akka.event.EventHandler - -/** - * Helper class for reflective access to different modules in order to allow optional loading of modules. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ -object ReflectiveAccess { - - val loader = getClass.getClassLoader - - def isRemotingEnabled = Remote.isEnabled - lazy val isTypedActorEnabled = TypedActorModule.isEnabled - - def ensureRemotingEnabled = Remote.ensureEnabled - def ensureTypedActorEnabled = TypedActorModule.ensureEnabled - - /** - * Reflective access to the RemoteClient module. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ - object Remote { - val TRANSPORT = Config.config.getString("akka.remote.layer", "akka.remote.netty.NettyRemoteSupport") - - private[akka] val configDefaultAddress = - new InetSocketAddress(Config.config.getString("akka.remote.server.hostname", "localhost"), - Config.config.getInt("akka.remote.server.port", 2552)) - - lazy val isEnabled = remoteSupportClass.isDefined - - def ensureEnabled = if (!isEnabled) { - val e = new ModuleNotAvailableException("Can't load the remoting module, make sure that akka-remote.jar is on the classpath") - EventHandler.debug(this, e.toString) - throw e - } - val remoteSupportClass = getClassFor[RemoteSupport](TRANSPORT) match { - case Right(value) => Some(value) - case Left(exception) => - EventHandler.debug(this, exception.toString) - None - } - - protected[akka] val defaultRemoteSupport: Option[() => RemoteSupport] = - remoteSupportClass map { remoteClass => - () => createInstance[RemoteSupport]( - remoteClass, - Array[Class[_]](), - Array[AnyRef]()) match { - case Right(value) => value - case Left(exception) => - val e = new ModuleNotAvailableException( - "Can't instantiate [%s] - make sure that akka-remote.jar is on the classpath".format(remoteClass.getName), exception) - EventHandler.debug(this, e.toString) - throw e - } - } - } - - /** - * Reflective access to the TypedActors module. - * - * @author <a href="http://jonasboner.com">Jonas Bonér</a> - */ - object TypedActorModule { - - type TypedActorObject = { - def isJoinPoint(message: Any): Boolean - def isJoinPointAndOneWay(message: Any): Boolean - def actorFor(proxy: AnyRef): Option[ActorRef] - def proxyFor(actorRef: ActorRef): Option[AnyRef] - def stop(anyRef: AnyRef): Unit - } - - lazy val isEnabled = typedActorObjectInstance.isDefined - - def ensureEnabled = if (!isTypedActorEnabled) throw new ModuleNotAvailableException( - "Can't load the typed actor module, make sure that akka-typed-actor.jar is on the classpath") - - val typedActorObjectInstance: Option[TypedActorObject] = - getObjectFor[TypedActorObject]("akka.actor.TypedActor$") match { - case Right(value) => Some(value) - case Left(exception) => - EventHandler.debug(this, exception.toString) - None - } - - def resolveFutureIfMessageIsJoinPoint(message: Any, future: Future[_]): Boolean = { - ensureEnabled - if (typedActorObjectInstance.get.isJoinPointAndOneWay(message)) { - future.asInstanceOf[CompletableFuture[Option[_]]].completeWithResult(None) - } - typedActorObjectInstance.get.isJoinPoint(message) - } - } - - object AkkaCloudModule { - - type Mailbox = { - def enqueue(message: MessageInvocation) - def dequeue: MessageInvocation - } - - type Serializer = { - def toBinary(obj: AnyRef): Array[Byte] - def fromBinary(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef - } - - lazy val isEnabled = clusterObjectInstance.isDefined - - val clusterObjectInstance: Option[AnyRef] = - getObjectFor[AnyRef]("akka.cloud.cluster.Cluster$") match { - case Right(value) => Some(value) - case Left(exception) => - EventHandler.debug(this, exception.toString) - None - } - - val serializerClass: Option[Class[_]] = - getClassFor("akka.serialization.Serializer") match { - case Right(value) => Some(value) - case Left(exception) => - EventHandler.debug(this, exception.toString) - None - } - - def ensureEnabled = if (!isEnabled) throw new ModuleNotAvailableException( - "Feature is only available in Akka Cloud") - } - - val noParams = Array[Class[_]]() - val noArgs = Array[AnyRef]() - - def createInstance[T](clazz: Class[_], - params: Array[Class[_]], - args: Array[AnyRef]): Either[Exception, T] = try { - assert(clazz ne null) - assert(params ne null) - assert(args ne null) - val ctor = clazz.getDeclaredConstructor(params: _*) - ctor.setAccessible(true) - Right(ctor.newInstance(args: _*).asInstanceOf[T]) - } catch { - case e: Exception => Left(e) - } - - def createInstance[T](fqn: String, - params: Array[Class[_]], - args: Array[AnyRef], - classloader: ClassLoader = loader): Either[Exception, T] = try { - assert(params ne null) - assert(args ne null) - getClassFor(fqn) match { - case Right(value) => - val ctor = value.getDeclaredConstructor(params: _*) - ctor.setAccessible(true) - Right(ctor.newInstance(args: _*).asInstanceOf[T]) - case Left(exception) => Left(exception) //We could just cast this to Either[Exception, T] but it's ugly - } - } catch { - case e: Exception => - Left(e) - } - - //Obtains a reference to fqn.MODULE$ - def getObjectFor[T](fqn: String, classloader: ClassLoader = loader): Either[Exception, T] = try { - getClassFor(fqn) match { - case Right(value) => - val instance = value.getDeclaredField("MODULE$") - instance.setAccessible(true) - val obj = instance.get(null) - if (obj eq null) Left(new NullPointerException) else Right(obj.asInstanceOf[T]) - case Left(exception) => Left(exception) //We could just cast this to Either[Exception, T] but it's ugly - } - } catch { - case e: Exception => - Left(e) - } - - def getClassFor[T](fqn: String, classloader: ClassLoader = loader): Either[Exception, Class[T]] = try { - assert(fqn ne null) - - // First, use the specified CL - val first = try { - Right(classloader.loadClass(fqn).asInstanceOf[Class[T]]) - } catch { - case c: ClassNotFoundException => Left(c) - } - - if (first.isRight) first - else { - // Second option is to use the ContextClassLoader - val second = try { - Right(Thread.currentThread.getContextClassLoader.loadClass(fqn).asInstanceOf[Class[T]]) - } catch { - case c: ClassNotFoundException => Left(c) - } - - if (second.isRight) second - else { - val third = try { - if (classloader ne loader) Right(loader.loadClass(fqn).asInstanceOf[Class[T]]) else Left(null) //Horrid - } catch { - case c: ClassNotFoundException => Left(c) - } - - if (third.isRight) third - else { - try { - Right(Class.forName(fqn).asInstanceOf[Class[T]]) // Last option is Class.forName - } catch { - case c: ClassNotFoundException => Left(c) - } - } - } - } - } catch { - case e: Exception => Left(e) - } -} diff --git a/test/files/presentation/akka/src/akka/util/package.scala b/test/files/presentation/akka/src/akka/util/package.scala deleted file mode 100644 index 26a24929c9..0000000000 --- a/test/files/presentation/akka/src/akka/util/package.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se> - */ - -package akka.util - -import java.util.concurrent.TimeUnit - -package object duration { - implicit def intToDurationInt(n: Int) = new DurationInt(n) - implicit def longToDurationLong(n: Long) = new DurationLong(n) - implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d) - - implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2) - implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2) - implicit def durationToPair(d: Duration) = (d.length, d.unit) - - implicit def intMult(i: Int) = new { - def *(d: Duration) = d * i - } - implicit def longMult(l: Long) = new { - def *(d: Duration) = d * l - } - implicit def doubleMult(f: Double) = new { - def *(d: Duration) = d * f - } -} diff --git a/test/files/presentation/akka/src/com/eaio/util/lang/Hex.java b/test/files/presentation/akka/src/com/eaio/util/lang/Hex.java deleted file mode 100644 index 7794059517..0000000000 --- a/test/files/presentation/akka/src/com/eaio/util/lang/Hex.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Hex.java - * - * Created 04.07.2003. - * - * eaio: UUID - an implementation of the UUID specification Copyright (c) 2003-2009 Johann Burkard (jb@eaio.com) - * http://eaio.com. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -package com.eaio.util.lang; - -import java.io.IOException; - -/** - * Number-to-hexadecimal and hexadecimal-to-number conversions. - * - * @see <a href="http://johannburkard.de/software/uuid/">UUID</a> - * @author <a href="mailto:jb@eaio.com">Johann Burkard</a> - * @version $Id: Hex.java 1888 2009-03-15 12:43:24Z johann $ - */ -public final class Hex { - - /** - * No instances needed. - */ - private Hex() { - super(); - } - - private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', - 'f' }; - - /** - * Turns a <code>short</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the integer - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, short in) { - return append(a, (long) in, 4); - } - - /** - * Turns a <code>short</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the integer - * @param length the number of octets to produce - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, short in, int length) { - return append(a, (long) in, length); - } - - /** - * Turns an <code>int</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the integer - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, int in) { - return append(a, (long) in, 8); - } - - /** - * Turns an <code>int</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the integer - * @param length the number of octets to produce - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, int in, int length) { - return append(a, (long) in, length); - } - - /** - * Turns a <code>long</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the long - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, long in) { - return append(a, in, 16); - } - - /** - * Turns a <code>long</code> into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param in the long - * @param length the number of octets to produce - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, long in, int length) { - try { - int lim = (length << 2) - 4; - while (lim >= 0) { - a.append(DIGITS[(byte) (in >> lim) & 0x0f]); - lim -= 4; - } - } - catch (IOException ex) { - // Bla - } - return a; - } - - /** - * Turns a <code>byte</code> array into hex octets. - * - * @param a the {@link Appendable}, may not be <code>null</code> - * @param bytes the <code>byte</code> array - * @return {@link Appendable} - */ - public static Appendable append(Appendable a, byte[] bytes) { - try { - for (byte b : bytes) { - a.append(DIGITS[(byte) ((b & 0xF0) >> 4)]); - a.append(DIGITS[(byte) (b & 0x0F)]); - } - } - catch (IOException ex) { - // Bla - } - return a; - } - - /** - * Parses a <code>long</code> from a hex encoded number. This method will skip all characters that are not 0-9, - * A-F and a-f. - * <p> - * Returns 0 if the {@link CharSequence} does not contain any interesting characters. - * - * @param s the {@link CharSequence} to extract a <code>long</code> from, may not be <code>null</code> - * @return a <code>long</code> - * @throws NullPointerException if the {@link CharSequence} is <code>null</code> - */ - public static long parseLong(CharSequence s) { - long out = 0; - byte shifts = 0; - char c; - for (int i = 0; i < s.length() && shifts < 16; i++) { - c = s.charAt(i); - if ((c > 47) && (c < 58)) { - ++shifts; - out <<= 4; - out |= c - 48; - } - else if ((c > 64) && (c < 71)) { - ++shifts; - out <<= 4; - out |= c - 55; - } - else if ((c > 96) && (c < 103)) { - ++shifts; - out <<= 4; - out |= c - 87; - } - } - return out; - } - - /** - * Parses a <code>short</code> from a hex encoded number. This method will skip all characters that are not 0-9, - * A-F and a-f. - * <p> - * Returns 0 if the {@link CharSequence} does not contain any interesting characters. - * - * @param s the {@link CharSequence} to extract a <code>short</code> from, may not be <code>null</code> - * @return a <code>short</code> - * @throws NullPointerException if the {@link CharSequence} is <code>null</code> - */ - public static short parseShort(String s) { - short out = 0; - byte shifts = 0; - char c; - for (int i = 0; i < s.length() && shifts < 4; i++) { - c = s.charAt(i); - if ((c > 47) && (c < 58)) { - ++shifts; - out <<= 4; - out |= c - 48; - } - else if ((c > 64) && (c < 71)) { - ++shifts; - out <<= 4; - out |= c - 55; - } - else if ((c > 96) && (c < 103)) { - ++shifts; - out <<= 4; - out |= c - 87; - } - } - return out; - } - -} diff --git a/test/files/presentation/akka/src/com/eaio/uuid/MACAddressParser.java b/test/files/presentation/akka/src/com/eaio/uuid/MACAddressParser.java deleted file mode 100644 index c077147470..0000000000 --- a/test/files/presentation/akka/src/com/eaio/uuid/MACAddressParser.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * MACAddressParserTest.java - * - * Created 30.01.2006. - * - * eaio: UUID - an implementation of the UUID specification - * Copyright (c) 2003-2009 Johann Burkard (jb@eaio.com) http://eaio.com. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -package com.eaio.uuid; - -/** - * The MAC address parser attempts to find the following patterns: - * <ul> - * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li> - * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li> - * </ul> - * - * @see <a href="http://johannburkard.de/software/uuid/">UUID</a> - * @author <a href="mailto:jb@eaio.com">Johann Burkard</a> - * @version $Id: MACAddressParser.java 1888 2009-03-15 12:43:24Z johann $ - */ -class MACAddressParser { - - /** - * No instances needed. - */ - private MACAddressParser() { - super(); - } - - /** - * Attempts to find a pattern in the given String. - * - * @param in the String, may not be <code>null</code> - * @return the substring that matches this pattern or <code>null</code> - */ - static String parse(String in) { - - String out = in; - - // lanscan - - int hexStart = out.indexOf("0x"); - if (hexStart != -1 && out.indexOf("ETHER") != -1) { - int hexEnd = out.indexOf(' ', hexStart); - if (hexEnd > hexStart + 2) { - out = out.substring(hexStart, hexEnd); - } - } - - else { - - int octets = 0; - int lastIndex, old, end; - - if (out.indexOf('-') > -1) { - out = out.replace('-', ':'); - } - - lastIndex = out.lastIndexOf(':'); - - if (lastIndex > out.length() - 2) { - out = null; - } - else { - - end = Math.min(out.length(), lastIndex + 3); - - ++octets; - old = lastIndex; - while (octets != 5 && lastIndex != -1 && lastIndex > 1) { - lastIndex = out.lastIndexOf(':', --lastIndex); - if (old - lastIndex == 3 || old - lastIndex == 2) { - ++octets; - old = lastIndex; - } - } - - if (octets == 5 && lastIndex > 1) { - out = out.substring(lastIndex - 2, end).trim(); - } - else { - out = null; - } - - } - - } - - if (out != null && out.startsWith("0x")) { - out = out.substring(2); - } - - return out; - } - -} diff --git a/test/files/presentation/akka/src/com/eaio/uuid/UUID.java b/test/files/presentation/akka/src/com/eaio/uuid/UUID.java deleted file mode 100644 index 6c49bcd1c8..0000000000 --- a/test/files/presentation/akka/src/com/eaio/uuid/UUID.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * UUID.java - * - * Created 07.02.2003 - * - * eaio: UUID - an implementation of the UUID specification - * Copyright (c) 2003-2009 Johann Burkard (jb@eaio.com) http://eaio.com. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -package com.eaio.uuid; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import org.omg.CORBA.portable.IDLEntity; - -import com.eaio.util.lang.Hex; - -/** - * Creates UUIDs according to the DCE Universal Token Identifier specification. - * <p> - * All you need to know: - * <pre> - * UUID u = new UUID(); - * </pre> - * - * @see <a href="http://www.opengroup.org/onlinepubs/9629399/apdxa.htm"> - * http://www.opengroup.org/onlinepubs/9629399/apdxa.htm - * </a> - * @see <a href="http://www.uddi.org/pubs/draft-leach-uuids-guids-01.txt"> - * http://www.uddi.org/pubs/draft-leach-uuids-guids-01.txt - * </a> - * @see <a href="http://johannburkard.de/software/uuid/">UUID</a> - * @author <a href="mailto:jb@eaio.de">Johann Burkard</a> - * @version $Id: UUID.java 1888 2009-03-15 12:43:24Z johann $ - */ -public class UUID implements Comparable<UUID>, Serializable, Cloneable, - IDLEntity { - - /** - * Hasn't ever changed between versions. - */ - static final long serialVersionUID = 7435962790062944603L; - - /** - * The time field of the UUID. - * - * @serial - */ - public long time; - - /** - * The clock sequence and node field of the UUID. - * - * @serial - */ - public long clockSeqAndNode; - - /** - * Constructor for UUID. Constructs a new, unique UUID. - * - * @see UUIDGen#newTime() - * @see UUIDGen#getClockSeqAndNode() - */ - public UUID() { - this(UUIDGen.newTime(), UUIDGen.getClockSeqAndNode()); - } - - /** - * Constructor for UUID. Constructs a UUID from two <code>long</code> values. - * - * @param time the upper 64 bits - * @param clockSeqAndNode the lower 64 bits - */ - public UUID(long time, long clockSeqAndNode) { - this.time = time; - this.clockSeqAndNode = clockSeqAndNode; - } - - /** - * Copy constructor for UUID. Values of the given UUID are copied. - * - * @param u the UUID, may not be <code>null</code> - */ - public UUID(UUID u) { - this(u.time, u.clockSeqAndNode); - } - - /** - * Parses a textual representation of a UUID. - * <p> - * No validation is performed. If the {@link CharSequence} is shorter than 36 characters, - * {@link ArrayIndexOutOfBoundsException}s will be thrown. - * - * @param s the {@link CharSequence}, may not be <code>null</code> - */ - public UUID(CharSequence s) { - this(Hex.parseLong(s.subSequence(0, 18)), Hex.parseLong(s.subSequence( - 19, 36))); - } - - /** - * Compares this UUID to another Object. Throws a {@link ClassCastException} if - * the other Object is not an instance of the UUID class. Returns a value - * smaller than zero if the other UUID is "larger" than this UUID and a value - * larger than zero if the other UUID is "smaller" than this UUID. - * - * @param t the other UUID, may not be <code>null</code> - * @return a value < 0, 0 or a value > 0 - * @see java.lang.Comparable#compareTo(java.lang.Object) - * @throws ClassCastException - */ - public int compareTo(UUID t) { - if (this == t) { - return 0; - } - if (time > t.time) { - return 1; - } - if (time < t.time) { - return -1; - } - if (clockSeqAndNode > t.clockSeqAndNode) { - return 1; - } - if (clockSeqAndNode < t.clockSeqAndNode) { - return -1; - } - return 0; - } - - /** - * Tweaked Serialization routine. - * - * @param out the ObjectOutputStream - * @throws IOException - */ - private void writeObject(ObjectOutputStream out) throws IOException { - out.writeLong(time); - out.writeLong(clockSeqAndNode); - } - - /** - * Tweaked Serialization routine. - * - * @param in the ObjectInputStream - * @throws IOException - */ - private void readObject(ObjectInputStream in) throws IOException { - time = in.readLong(); - clockSeqAndNode = in.readLong(); - } - - /** - * Returns this UUID as a String. - * - * @return a String, never <code>null</code> - * @see java.lang.Object#toString() - * @see #toAppendable(Appendable) - */ - @Override - public final String toString() { - return toAppendable(null).toString(); - } - - /** - * Appends a String representation of this to the given {@link StringBuffer} or - * creates a new one if none is given. - * - * @param in the StringBuffer to append to, may be <code>null</code> - * @return a StringBuffer, never <code>null</code> - * @see #toAppendable(Appendable) - */ - public StringBuffer toStringBuffer(StringBuffer in) { - StringBuffer out = in; - if (out == null) { - out = new StringBuffer(36); - } - else { - out.ensureCapacity(out.length() + 36); - } - return (StringBuffer) toAppendable(out); - } - - /** - * Appends a String representation of this object to the given {@link Appendable} object. - * <p> - * For reasons I'll probably never understand, Sun has decided to have a number of I/O classes implement - * Appendable which forced them to destroy an otherwise nice and simple interface with {@link IOException}s. - * <p> - * I decided to ignore any possible IOExceptions in this method. - * - * @param a the Appendable object, may be <code>null</code> - * @return an Appendable object, defaults to a {@link StringBuilder} if <code>a</code> is <code>null</code> - */ - public Appendable toAppendable(Appendable a) { - Appendable out = a; - if (out == null) { - out = new StringBuilder(36); - } - try { - Hex.append(out, (int) (time >> 32)).append('-'); - Hex.append(out, (short) (time >> 16)).append('-'); - Hex.append(out, (short) time).append('-'); - Hex.append(out, (short) (clockSeqAndNode >> 48)).append('-'); - Hex.append(out, clockSeqAndNode, 12); - } - catch (IOException ex) { - // What were they thinking? - } - return out; - } - - /** - * Returns a hash code of this UUID. The hash code is calculated by XOR'ing the - * upper 32 bits of the time and clockSeqAndNode fields and the lower 32 bits of - * the time and clockSeqAndNode fields. - * - * @return an <code>int</code> representing the hash code - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return (int) ((time >> 32) ^ time ^ (clockSeqAndNode >> 32) ^ clockSeqAndNode); - } - - /** - * Clones this UUID. - * - * @return a new UUID with identical values, never <code>null</code> - */ - @Override - public Object clone() { - try { - return super.clone(); - } - catch (CloneNotSupportedException ex) { - // One of Sun's most epic fails. - return null; - } - } - - /** - * Returns the time field of the UUID (upper 64 bits). - * - * @return the time field - */ - public final long getTime() { - return time; - } - - /** - * Returns the clock and node field of the UUID (lower 64 bits). - * - * @return the clockSeqAndNode field - */ - public final long getClockSeqAndNode() { - return clockSeqAndNode; - } - - /** - * Compares two Objects for equality. - * - * @see java.lang.Object#equals(Object) - * @param obj the Object to compare this UUID with, may be <code>null</code> - * @return <code>true</code> if the other Object is equal to this UUID, - * <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof UUID)) { - return false; - } - return compareTo((UUID) obj) == 0; - } - - /** - * Returns the nil UUID (a UUID whose values are both set to zero). - * <p> - * Starting with version 2.0, this method does return a new UUID instance every - * time it is called. Earlier versions returned one instance. This has now been - * changed because this UUID has public, non-final instance fields. Returning a - * new instance is therefore more safe. - * - * @return a nil UUID, never <code>null</code> - */ - public static UUID nilUUID() { - return new UUID(0, 0); - } - -} diff --git a/test/files/presentation/akka/src/com/eaio/uuid/UUIDGen.java b/test/files/presentation/akka/src/com/eaio/uuid/UUIDGen.java deleted file mode 100644 index 7b63f65447..0000000000 --- a/test/files/presentation/akka/src/com/eaio/uuid/UUIDGen.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * UUIDGen.java - * - * Created on 09.08.2003. - * - * eaio: UUID - an implementation of the UUID specification - * Copyright (c) 2003-2009 Johann Burkard (jb@eaio.com) http://eaio.com. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -package com.eaio.uuid; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Enumeration; - -import com.eaio.util.lang.Hex; - -/** - * This class contains methods to generate UUID fields. These methods have been - * refactored out of {@link com.eaio.uuid.UUID}. - * <p> - * Starting with version 2, this implementation tries to obtain the MAC address - * of the network card. Under Microsoft Windows, the <code>ifconfig</code> - * command is used which may pop up a command window in Java Virtual Machines - * prior to 1.4 once this class is initialized. The command window is closed - * automatically. - * <p> - * The MAC address code has been tested extensively in Microsoft Windows, - * Linux, Solaris 8, HP-UX 11, but should work in MacOS X and BSDs, too. - * <p> - * If you use JDK 6 or later, the code in {@link InterfaceAddress} will be used. - * - * @see <a href="http://johannburkard.de/software/uuid/">UUID</a> - * @author <a href="mailto:jb@eaio.de">Johann Burkard</a> - * @version $Id: UUIDGen.java 2914 2010-04-23 11:35:00Z johann $ - * @see com.eaio.uuid.UUID - */ -public final class UUIDGen { - - /** - * No instances needed. - */ - private UUIDGen() { - super(); - } - - /** - * The last time value. Used to remove duplicate UUIDs. - */ - private static long lastTime = Long.MIN_VALUE; - - /** - * The cached MAC address. - */ - private static String macAddress = null; - - /** - * The current clock and node value. - */ - private static long clockSeqAndNode = 0x8000000000000000L; - - static { - - try { - Class.forName("java.net.InterfaceAddress"); - macAddress = Class.forName( - "com.eaio.uuid.UUIDGen$HardwareAddressLookup").newInstance().toString(); - } - catch (ExceptionInInitializerError err) { - // Ignored. - } - catch (ClassNotFoundException ex) { - // Ignored. - } - catch (LinkageError err) { - // Ignored. - } - catch (IllegalAccessException ex) { - // Ignored. - } - catch (InstantiationException ex) { - // Ignored. - } - catch (SecurityException ex) { - // Ignored. - } - - if (macAddress == null) { - - Process p = null; - BufferedReader in = null; - - try { - String osname = System.getProperty("os.name", ""); - - if (osname.startsWith("Windows")) { - p = Runtime.getRuntime().exec( - new String[] { "ipconfig", "/all" }, null); - } - // Solaris code must appear before the generic code - else if (osname.startsWith("Solaris") - || osname.startsWith("SunOS")) { - String hostName = getFirstLineOfCommand( - "uname", "-n" ); - if (hostName != null) { - p = Runtime.getRuntime().exec( - new String[] { "/usr/sbin/arp", hostName }, - null); - } - } - else if (new File("/usr/sbin/lanscan").exists()) { - p = Runtime.getRuntime().exec( - new String[] { "/usr/sbin/lanscan" }, null); - } - else if (new File("/sbin/ifconfig").exists()) { - p = Runtime.getRuntime().exec( - new String[] { "/sbin/ifconfig", "-a" }, null); - } - - if (p != null) { - in = new BufferedReader(new InputStreamReader( - p.getInputStream()), 128); - String l = null; - while ((l = in.readLine()) != null) { - macAddress = MACAddressParser.parse(l); - if (macAddress != null - && Hex.parseShort(macAddress) != 0xff) { - break; - } - } - } - - } - catch (SecurityException ex) { - // Ignore it. - } - catch (IOException ex) { - // Ignore it. - } - finally { - if (p != null) { - if (in != null) { - try { - in.close(); - } - catch (IOException ex) { - // Ignore it. - } - } - try { - p.getErrorStream().close(); - } - catch (IOException ex) { - // Ignore it. - } - try { - p.getOutputStream().close(); - } - catch (IOException ex) { - // Ignore it. - } - p.destroy(); - } - } - - } - - if (macAddress != null) { - clockSeqAndNode |= Hex.parseLong(macAddress); - } - else { - try { - byte[] local = InetAddress.getLocalHost().getAddress(); - clockSeqAndNode |= (local[0] << 24) & 0xFF000000L; - clockSeqAndNode |= (local[1] << 16) & 0xFF0000; - clockSeqAndNode |= (local[2] << 8) & 0xFF00; - clockSeqAndNode |= local[3] & 0xFF; - } - catch (UnknownHostException ex) { - clockSeqAndNode |= (long) (Math.random() * 0x7FFFFFFF); - } - } - - // Skip the clock sequence generation process and use random instead. - - clockSeqAndNode |= (long) (Math.random() * 0x3FFF) << 48; - - } - - /** - * Returns the current clockSeqAndNode value. - * - * @return the clockSeqAndNode value - * @see UUID#getClockSeqAndNode() - */ - public static long getClockSeqAndNode() { - return clockSeqAndNode; - } - - /** - * Generates a new time field. Each time field is unique and larger than the - * previously generated time field. - * - * @return a new time value - * @see UUID#getTime() - */ - public static long newTime() { - return createTime(System.currentTimeMillis()); - } - - /** - * Creates a new time field from the given timestamp. Note that even identical - * values of <code>currentTimeMillis</code> will produce different time fields. - * - * @param currentTimeMillis the timestamp - * @return a new time value - * @see UUID#getTime() - */ - public static synchronized long createTime(long currentTimeMillis) { - - long time; - - // UTC time - - long timeMillis = (currentTimeMillis * 10000) + 0x01B21DD213814000L; - - if (timeMillis > lastTime) { - lastTime = timeMillis; - } - else { - timeMillis = ++lastTime; - } - - // time low - - time = timeMillis << 32; - - // time mid - - time |= (timeMillis & 0xFFFF00000000L) >> 16; - - // time hi and version - - time |= 0x1000 | ((timeMillis >> 48) & 0x0FFF); // version 1 - - return time; - - } - - /** - * Returns the MAC address. Not guaranteed to return anything. - * - * @return the MAC address, may be <code>null</code> - */ - public static String getMACAddress() { - return macAddress; - } - - /** - * Returns the first line of the shell command. - * - * @param commands the commands to run - * @return the first line of the command - * @throws IOException - */ - static String getFirstLineOfCommand(String... commands) throws IOException { - - Process p = null; - BufferedReader reader = null; - - try { - p = Runtime.getRuntime().exec(commands); - reader = new BufferedReader(new InputStreamReader( - p.getInputStream()), 128); - - return reader.readLine(); - } - finally { - if (p != null) { - if (reader != null) { - try { - reader.close(); - } - catch (IOException ex) { - // Ignore it. - } - } - try { - p.getErrorStream().close(); - } - catch (IOException ex) { - // Ignore it. - } - try { - p.getOutputStream().close(); - } - catch (IOException ex) { - // Ignore it. - } - p.destroy(); - } - } - - } - - /** - * Scans MAC addresses for good ones. - */ - static class HardwareAddressLookup { - - /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - String out = null; - try { - Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces(); - if (ifs != null) { - while (ifs.hasMoreElements()) { - NetworkInterface iface = ifs.nextElement(); - byte[] hardware = iface.getHardwareAddress(); - if (hardware != null && hardware.length == 6 - && hardware[1] != (byte) 0xff) { - out = Hex.append(new StringBuilder(36), hardware).toString(); - break; - } - } - } - } - catch (SocketException ex) { - // Ignore it. - } - return out; - } - - } - -} diff --git a/test/files/presentation/akka/src/com/eaio/uuid/UUIDHelper.java b/test/files/presentation/akka/src/com/eaio/uuid/UUIDHelper.java deleted file mode 100644 index 7abbe85895..0000000000 --- a/test/files/presentation/akka/src/com/eaio/uuid/UUIDHelper.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.eaio.uuid; - - -/** -* com/eaio/uuid/UUIDHelper.java . -* Generated by the IDL-to-Java compiler (portable), version "3.1" -* from uuid.idl -* Sonntag, 7. März 2004 21.35 Uhr CET -*/ - - -/** - * The UUID struct. - */ -abstract public class UUIDHelper -{ - private static String _id = "IDL:com/eaio/uuid/UUID:1.0"; - - public static void insert (org.omg.CORBA.Any a, com.eaio.uuid.UUID that) - { - org.omg.CORBA.portable.OutputStream out = a.create_output_stream (); - a.type (type ()); - write (out, that); - a.read_value (out.create_input_stream (), type ()); - } - - public static com.eaio.uuid.UUID extract (org.omg.CORBA.Any a) - { - return read (a.create_input_stream ()); - } - - private static org.omg.CORBA.TypeCode __typeCode = null; - private static boolean __active = false; - synchronized public static org.omg.CORBA.TypeCode type () - { - if (__typeCode == null) - { - synchronized (org.omg.CORBA.TypeCode.class) - { - if (__typeCode == null) - { - if (__active) - { - return org.omg.CORBA.ORB.init().create_recursive_tc ( _id ); - } - __active = true; - org.omg.CORBA.StructMember[] _members0 = new org.omg.CORBA.StructMember [2]; - org.omg.CORBA.TypeCode _tcOf_members0 = null; - _tcOf_members0 = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_longlong); - _members0[0] = new org.omg.CORBA.StructMember ( - "time", - _tcOf_members0, - null); - _tcOf_members0 = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_longlong); - _members0[1] = new org.omg.CORBA.StructMember ( - "clockSeqAndNode", - _tcOf_members0, - null); - __typeCode = org.omg.CORBA.ORB.init ().create_struct_tc (com.eaio.uuid.UUIDHelper.id (), "UUID", _members0); - __active = false; - } - } - } - return __typeCode; - } - - public static String id () - { - return _id; - } - - public static com.eaio.uuid.UUID read (org.omg.CORBA.portable.InputStream istream) - { - com.eaio.uuid.UUID value = new com.eaio.uuid.UUID (); - value.time = istream.read_longlong (); - value.clockSeqAndNode = istream.read_longlong (); - return value; - } - - public static void write (org.omg.CORBA.portable.OutputStream ostream, com.eaio.uuid.UUID value) - { - ostream.write_longlong (value.time); - ostream.write_longlong (value.clockSeqAndNode); - } - -} diff --git a/test/files/presentation/akka/src/com/eaio/uuid/UUIDHolder.java b/test/files/presentation/akka/src/com/eaio/uuid/UUIDHolder.java deleted file mode 100644 index d5531f5e00..0000000000 --- a/test/files/presentation/akka/src/com/eaio/uuid/UUIDHolder.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.eaio.uuid; - -/** -* com/eaio/uuid/UUIDHolder.java . -* Generated by the IDL-to-Java compiler (portable), version "3.1" -* from uuid.idl -* Sonntag, 7. März 2004 21.35 Uhr CET -*/ - - -/** - * The UUID struct. - */ -public final class UUIDHolder implements org.omg.CORBA.portable.Streamable -{ - public com.eaio.uuid.UUID value = null; - - public UUIDHolder () - { - } - - public UUIDHolder (com.eaio.uuid.UUID initialValue) - { - value = initialValue; - } - - public void _read (org.omg.CORBA.portable.InputStream i) - { - value = com.eaio.uuid.UUIDHelper.read (i); - } - - public void _write (org.omg.CORBA.portable.OutputStream o) - { - com.eaio.uuid.UUIDHelper.write (o, value); - } - - public org.omg.CORBA.TypeCode _type () - { - return com.eaio.uuid.UUIDHelper.type (); - } - -} diff --git a/test/files/presentation/akka/src/pi.scala b/test/files/presentation/akka/src/pi.scala deleted file mode 100644 index b4c644052c..0000000000 --- a/test/files/presentation/akka/src/pi.scala +++ /dev/null @@ -1,108 +0,0 @@ - -import akka.actor.{Actor, PoisonPill} -import Actor._ -import akka.routing.{Routing, CyclicIterator} -import Routing._ - -import java.util.concurrent.CountDownLatch - -object Pi extends App { - - calculate/*#*/(nrOfWorkers = 4, nrOfElements = 10000, nrOfMessages = 10000) - - // ==================== - // ===== Messages ===== - // ==================== - sealed trait PiMessage - case object Calculate extends PiMessage/*#*/ - case class Work(start: Int, nrOfElements: Int) extends PiMessage - case class Result(value: Double) extends PiMessage - - // ================== - // ===== Worker ===== - // ================== - class Worker extends Actor/*#*/ { - - // define the work - def calculatePiFor(start: Int, nrOfElements: Int): Double = { - var acc = 0.0 - for (i <- start until (start + nrOfElements)) - acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1) - acc - } - - def receive /*?*/ = { - case Work(start, nrOfElements) => - self reply/*#*/ Result(calculatePiFor(start, nrOfElements)) // perform the work // TODO: this currently returns wrong position for the symbol - } - } - - // ================== - // ===== Master ===== - // ================== - class Master( - nrOfWorkers: Int, nrOfMessages: Int, nrOfElements: Int, latch: CountDownLatch) - extends Actor { - - var pi: Double = _ - var nrOfResults: Int = _ - var start: Long = _ - - // create the workers - val workers = Vector.fill(nrOfWorkers)(actorOf[Worker]./*!*/start()) - - // wrap them with a load-balancing router - val router = Routing./*!*/loadBalancerActor(CyclicIterator(workers))./*!*/start() - - // message handler - def receive = { - case Calculate => - // schedule work - //for (start <- 0 until nrOfMessages) router ! Work(start, nrOfElements) - for (i <- 0 until nrOfMessages) router ! Work(i * nrOfElements, nrOfElements) - - // send a PoisonPill to all workers telling them to shut down themselves - router./*!*/!(Broadcast(PoisonPill)) - - // send a PoisonPill to the router, telling him to shut himself down - router ! PoisonPill - - case Result(value) => - // handle result from the worker - pi += value - nrOfResults/*#*/ += 1 - if (nrOfResults == nrOfMessages) self./*!*/stop() - } - - override def preStart() { - start = System.currentTimeMillis - } - - override def postStop() { - // tell the world that the calculation is complete - println( - "\n\tPi estimate: \t\t%s\n\tCalculation time: \t%s millis" - .format(pi, (System.currentTimeMillis - start))) - latch/*#*/.countDown() - } - } - - // ================== - // ===== Run it ===== - // ================== - def calculate(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int) { - - // this latch is only plumbing to know when the calculation is completed - val latch = new CountDownLatch(1) - - // create the master - val master = actorOf( - new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)).start() - - // start the calculation - master ! Calculate - - // wait for master to shut down - latch.await() - } -} |