Applied patch from bruce.mitchener, with minor adjustment
This commit is contained in:
parent
b1db0f42d5
commit
a60bbc5f59
39 changed files with 78 additions and 78 deletions
|
|
@ -8,7 +8,7 @@ import akka.actor.Actor
|
||||||
import Actor._
|
import Actor._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the behaviour of the executor based event driven dispatcher when multiple actors are being dispatched on it.
|
* Tests the behavior of the executor based event driven dispatcher when multiple actors are being dispatched on it.
|
||||||
*
|
*
|
||||||
* @author Jan Van Besien
|
* @author Jan Van Besien
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -322,7 +322,7 @@ trait Actor {
|
||||||
* <p/>
|
* <p/>
|
||||||
* For example fields like:
|
* For example fields like:
|
||||||
* <pre>
|
* <pre>
|
||||||
* self.dispactcher = ...
|
* self.dispatcher = ...
|
||||||
* self.trapExit = ...
|
* self.trapExit = ...
|
||||||
* self.faultHandler = ...
|
* self.faultHandler = ...
|
||||||
* self.lifeCycle = ...
|
* self.lifeCycle = ...
|
||||||
|
|
@ -417,7 +417,7 @@ trait Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes tha Actor's behavior to become the new 'Receive' (PartialFunction[Any, Unit]) handler.
|
* Changes the Actor's behavior to become the new 'Receive' (PartialFunction[Any, Unit]) handler.
|
||||||
* Puts the behavior on top of the hotswap stack.
|
* 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
|
* If "discardOld" is true, an unbecome will be issued prior to pushing the new behavior to the stack
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ trait ActorRef extends ActorRefShared with java.lang.Comparable[ActorRef] { scal
|
||||||
* Akka Java API. <p/>
|
* Akka Java API. <p/>
|
||||||
* Sends a one-way asynchronous message. E.g. fire-and-forget semantics.
|
* Sends a one-way asynchronous message. E.g. fire-and-forget semantics.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Allows you to pass along the sender of the messag.
|
* Allows you to pass along the sender of the message.
|
||||||
* <p/>
|
* <p/>
|
||||||
* <pre>
|
* <pre>
|
||||||
* actor.sendOneWay(message, context);
|
* actor.sendOneWay(message, context);
|
||||||
|
|
@ -291,14 +291,14 @@ trait ActorRef extends ActorRefShared with java.lang.Comparable[ActorRef] { scal
|
||||||
/**
|
/**
|
||||||
* Akka Java API. <p/>
|
* Akka Java API. <p/>
|
||||||
* @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef)
|
* @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef)
|
||||||
* Uses the defualt timeout of the Actor (setTimeout()) and omits the sender reference
|
* Uses the default timeout of the Actor (setTimeout()) and omits the sender reference
|
||||||
*/
|
*/
|
||||||
def sendRequestReply(message: AnyRef): AnyRef = sendRequestReply(message, timeout, null)
|
def sendRequestReply(message: AnyRef): AnyRef = sendRequestReply(message, timeout, null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Akka Java API. <p/>
|
* Akka Java API. <p/>
|
||||||
* @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef)
|
* @see sendRequestReply(message: AnyRef, timeout: Long, sender: ActorRef)
|
||||||
* Uses the defualt timeout of the Actor (setTimeout())
|
* Uses the default timeout of the Actor (setTimeout())
|
||||||
*/
|
*/
|
||||||
def sendRequestReply(message: AnyRef, sender: ActorRef): AnyRef = sendRequestReply(message, timeout, sender)
|
def sendRequestReply(message: AnyRef, sender: ActorRef): AnyRef = sendRequestReply(message, timeout, sender)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ object FSM {
|
||||||
* different concerns in different places; you may choose to use
|
* different concerns in different places; you may choose to use
|
||||||
* <code>when</code> for describing the properties of a state, including of
|
* <code>when</code> for describing the properties of a state, including of
|
||||||
* course initiating transitions, but you can describe the transitions using
|
* course initiating transitions, but you can describe the transitions using
|
||||||
* <code>onTransision</code> to avoid having to duplicate that code among
|
* <code>onTransition</code> to avoid having to duplicate that code among
|
||||||
* multiple paths which lead to a transition:
|
* multiple paths which lead to a transition:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import akka.japi.{Creator, Procedure}
|
||||||
*
|
*
|
||||||
* } else if (msg.equals("UseSender") && getContext().getSender().isDefined()) {
|
* } else if (msg.equals("UseSender") && getContext().getSender().isDefined()) {
|
||||||
* // Reply to original sender of message using the sender reference
|
* // Reply to original sender of message using the sender reference
|
||||||
* // also passing along my own refererence (the context)
|
* // also passing along my own reference (the context)
|
||||||
* getContext().getSender().get().sendOneWay(msg, context);
|
* getContext().getSender().get().sendOneWay(msg, context);
|
||||||
*
|
*
|
||||||
* } else if (msg.equals("UseSenderFuture") && getContext().getSenderFuture().isDefined()) {
|
* } else if (msg.equals("UseSenderFuture") && getContext().getSenderFuture().isDefined()) {
|
||||||
|
|
@ -36,7 +36,7 @@ import akka.japi.{Creator, Procedure}
|
||||||
* getContext().sendOneWay(msg)
|
* getContext().sendOneWay(msg)
|
||||||
*
|
*
|
||||||
* } else if (msg.equals("ForwardMessage")) {
|
* } else if (msg.equals("ForwardMessage")) {
|
||||||
* // Retreive an actor from the ActorRegistry by ID and get an ActorRef back
|
* // Retrieve an actor from the ActorRegistry by ID and get an ActorRef back
|
||||||
* ActorRef actorRef = Actor.registry.actorsFor("some-actor-id").head();
|
* ActorRef actorRef = Actor.registry.actorsFor("some-actor-id").head();
|
||||||
*
|
*
|
||||||
* } else throw new IllegalArgumentException("Unknown message: " + message);
|
* } else throw new IllegalArgumentException("Unknown message: " + message);
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ import java.util.concurrent.{ TimeUnit, ExecutorService, RejectedExecutionExcept
|
||||||
* @param throughput positive integer indicates the dispatcher will only process so much messages at a time from the
|
* @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
|
* mailbox, without checking the mailboxes of other actors. Zero or negative means the dispatcher
|
||||||
* always continues until the mailbox is empty.
|
* always continues until the mailbox is empty.
|
||||||
* Larger values (or zero or negative) increase througput, smaller values increase fairness
|
* Larger values (or zero or negative) increase throughput, smaller values increase fairness
|
||||||
*/
|
*/
|
||||||
class ExecutorBasedEventDrivenDispatcher(
|
class ExecutorBasedEventDrivenDispatcher(
|
||||||
_name: String,
|
_name: String,
|
||||||
|
|
|
||||||
|
|
@ -357,12 +357,12 @@ sealed trait Future[+T] {
|
||||||
/**
|
/**
|
||||||
* When this Future is completed, apply the provided function to the
|
* When this Future is completed, apply the provided function to the
|
||||||
* Future. If the Future has already been completed, this will apply
|
* Future. If the Future has already been completed, this will apply
|
||||||
* immediatly.
|
* immediately.
|
||||||
*/
|
*/
|
||||||
def onComplete(func: Future[T] => Unit): Future[T]
|
def onComplete(func: Future[T] => Unit): Future[T]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the future is compeleted with a valid result, apply the provided
|
* When the future is completed with a valid result, apply the provided
|
||||||
* PartialFunction to the result.
|
* PartialFunction to the result.
|
||||||
* <pre>
|
* <pre>
|
||||||
* val result = future receive {
|
* val result = future receive {
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ trait ListenerManagement {
|
||||||
def hasListeners: Boolean = !listeners.isEmpty
|
def hasListeners: Boolean = !listeners.isEmpty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a specfic listener is registered. ActorInitializationException leads to removal of listener if that
|
* Checks if a specific listener is registered. ActorInitializationException leads to removal of listener if that
|
||||||
* one isShutdown.
|
* one isShutdown.
|
||||||
*/
|
*/
|
||||||
def hasListener(listener: ActorRef): Boolean = listeners.contains(listener)
|
def hasListener(listener: ActorRef): Boolean = listeners.contains(listener)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Akka Actor
|
||||||
----------
|
----------
|
||||||
|
|
||||||
# is now dependency free, with the exception of the dependency on the ``scala-library.jar``
|
# is now dependency free, with the exception of the dependency on the ``scala-library.jar``
|
||||||
# does not bundle any logging anymore, but you can subscribe to events within Akka by registering an event handler on akka.aevent.EventHandler or by specifying the ``FQN`` of an Actor in the akka.conf under akka.event-handlers; there is an ``akka-slf4j`` module which still provides the Logging trait and a default ``SLF4J`` logger adapter.
|
# does not bundle any logging anymore, but you can subscribe to events within Akka by registering an event handler on akka.event.EventHandler or by specifying the ``FQN`` of an Actor in the akka.conf under akka.event-handlers; there is an ``akka-slf4j`` module which still provides the Logging trait and a default ``SLF4J`` logger adapter.
|
||||||
Don't forget to add a SLF4J backend though, we recommend:
|
Don't forget to add a SLF4J backend though, we recommend:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ download) use the ``dist`` command::
|
||||||
The distribution zip can be found in the dist directory and is called
|
The distribution zip can be found in the dist directory and is called
|
||||||
``akka-modules-{version}.zip``.
|
``akka-modules-{version}.zip``.
|
||||||
|
|
||||||
To run the mircokernel, unzip the zip file, change into the unzipped directory,
|
To run the microkernel, unzip the zip file, change into the unzipped directory,
|
||||||
set the ``AKKA_HOME`` environment variable, and run the main jar file. For
|
set the ``AKKA_HOME`` environment variable, and run the main jar file. For
|
||||||
example:
|
example:
|
||||||
|
|
||||||
|
|
@ -282,7 +282,7 @@ akka-camel
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
* Depends on akka-actor
|
* Depends on akka-actor
|
||||||
* camel-core-2.5.0.jar
|
* camel-core-2.7.0.jar
|
||||||
* commons-logging-api-1.1.jar
|
* commons-logging-api-1.1.jar
|
||||||
* commons-management-1.0.jar
|
* commons-management-1.0.jar
|
||||||
|
|
||||||
|
|
@ -290,7 +290,7 @@ akka-camel-typed
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
* Depends on akka-typed-actor
|
* Depends on akka-typed-actor
|
||||||
* camel-core-2.5.0.jar
|
* camel-core-2.7.0.jar
|
||||||
* commons-logging-api-1.1.jar
|
* commons-logging-api-1.1.jar
|
||||||
* commons-management-1.0.jar
|
* commons-management-1.0.jar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ SVT (Swedish Television)
|
||||||
|
|
||||||
*Our system is highly asynchronous so the actor style of doing things is a perfect fit. I don’t know about how you feel about concurrency in a big system, but rolling your own abstractions is not a very easy thing to do. When using Akka you can almost forget about all that. Synchronizing between threads, locking and protecting access to state etc. Akka is not just about actors, but that’s one of the most pleasurable things to work with. It’s easy to add new ones and it’s easy to design with actors. You can fire up work actors tied to a specific dispatcher etc. I could make the list of benefits much longer, but I’m at work right now. I suggest you try it out and see how it fits your requirements.*
|
*Our system is highly asynchronous so the actor style of doing things is a perfect fit. I don’t know about how you feel about concurrency in a big system, but rolling your own abstractions is not a very easy thing to do. When using Akka you can almost forget about all that. Synchronizing between threads, locking and protecting access to state etc. Akka is not just about actors, but that’s one of the most pleasurable things to work with. It’s easy to add new ones and it’s easy to design with actors. You can fire up work actors tied to a specific dispatcher etc. I could make the list of benefits much longer, but I’m at work right now. I suggest you try it out and see how it fits your requirements.*
|
||||||
|
|
||||||
*We saw a perfect businness reson for using Akka. It lets you concentrate on the business logic instead of the low level things. It’s easy to teach others and the business intent is clear just by reading the code. We didn’t chose Akka just for fun. It’s a business critical application that’s used in broadcasting. Even live broadcasting. We wouldn’t have been where we are today in such a short time without using Akka. We’re two developers that have done great things in such a short amount of time and part of this is due to Akka. As I said, it lets us focus on the business logic instead of low level things such as concurrency, locking, performence etc."*
|
*We saw a perfect business reason for using Akka. It lets you concentrate on the business logic instead of the low level things. It’s easy to teach others and the business intent is clear just by reading the code. We didn’t chose Akka just for fun. It’s a business critical application that’s used in broadcasting. Even live broadcasting. We wouldn’t have been where we are today in such a short time without using Akka. We’re two developers that have done great things in such a short amount of time and part of this is due to Akka. As I said, it lets us focus on the business logic instead of low level things such as concurrency, locking, performance etc."*
|
||||||
|
|
||||||
Tapad
|
Tapad
|
||||||
-----
|
-----
|
||||||
|
|
@ -107,7 +107,7 @@ LShift
|
||||||
|
|
||||||
* *"Diffa is an open source data analysis tool that automatically establishes data differences between two or more real-time systems.*
|
* *"Diffa is an open source data analysis tool that automatically establishes data differences between two or more real-time systems.*
|
||||||
* Diffa will help you compare local or distributed systems for data consistency, without having to stop them running or implement manual cross-system comparisons. The interface provides you with simple visual summary of any consistency breaks and tools to investigate the issues.*
|
* Diffa will help you compare local or distributed systems for data consistency, without having to stop them running or implement manual cross-system comparisons. The interface provides you with simple visual summary of any consistency breaks and tools to investigate the issues.*
|
||||||
* Diffa is the ideal tool to use to investigate where or when inconsistencies are occuring, or simply to provide confidence that your systems are running in perfect sync. It can be used operationally as an early warning system, in deployment for release verification, or in development with other enterprise diagnosis tools to help troubleshoot faults."*
|
* Diffa is the ideal tool to use to investigate where or when inconsistencies are occurring, or simply to provide confidence that your systems are running in perfect sync. It can be used operationally as an early warning system, in deployment for release verification, or in development with other enterprise diagnosis tools to help troubleshoot faults."*
|
||||||
|
|
||||||
`<http://diffa.lshift.net/>`_
|
`<http://diffa.lshift.net/>`_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ Creating a PriorityExecutorBasedEventDrivenDispatcher using PriorityGenerator:
|
||||||
ref.setDispatcher(new PriorityExecutorBasedEventDrivenDispatcher("foo", gen));
|
ref.setDispatcher(new PriorityExecutorBasedEventDrivenDispatcher("foo", gen));
|
||||||
|
|
||||||
ref.start(); // Start the actor
|
ref.start(); // Start the actor
|
||||||
ref.getDispatcher().suspend(ref); // Suspening the actor so it doesn't start to treat the messages before we have enqueued all of them :-)
|
ref.getDispatcher().suspend(ref); // Suspending the actor so it doesn't start to treat the messages before we have enqueued all of them :-)
|
||||||
ref.sendOneWay("lowpriority");
|
ref.sendOneWay("lowpriority");
|
||||||
ref.sendOneWay("lowpriority");
|
ref.sendOneWay("lowpriority");
|
||||||
ref.sendOneWay("highpriority");
|
ref.sendOneWay("highpriority");
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ Creating a PriorityExecutorBasedEventDrivenDispatcher using PriorityGenerator:
|
||||||
a.dispatcher = new PriorityExecutorBasedEventDrivenDispatcher("foo", gen)
|
a.dispatcher = new PriorityExecutorBasedEventDrivenDispatcher("foo", gen)
|
||||||
a.start // Start the Actor
|
a.start // Start the Actor
|
||||||
|
|
||||||
a.dispatcher.suspend(a) // Suspening the actor so it doesn't start to treat the messages before we have enqueued all of them :-)
|
a.dispatcher.suspend(a) // Suspending the actor so it doesn't start to treat the messages before we have enqueued all of them :-)
|
||||||
|
|
||||||
a ! 'lowpriority
|
a ! 'lowpriority
|
||||||
a ! 'lowpriority
|
a ! 'lowpriority
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ The Actor’s supervision can be declaratively defined by creating a ‘Supervis
|
||||||
|
|
||||||
Supervisors created like this are implicitly instantiated and started.
|
Supervisors created like this are implicitly instantiated and started.
|
||||||
|
|
||||||
To cofigure a handler function for when the actor underlying the supervisor recieves a MaximumNumberOfRestartsWithinTimeRangeReached message, you can specify
|
To configure a handler function for when the actor underlying the supervisor receives a MaximumNumberOfRestartsWithinTimeRangeReached message, you can specify
|
||||||
a Procedure2<ActorRef,MaximumNumberOfRestartsWithinTimeRangeReached> when creating the SupervisorConfig. This handler will be called with the ActorRef of the supervisor and the
|
a Procedure2<ActorRef,MaximumNumberOfRestartsWithinTimeRangeReached> when creating the SupervisorConfig. This handler will be called with the ActorRef of the supervisor and the
|
||||||
MaximumNumberOfRestartsWithinTimeRangeReached message.
|
MaximumNumberOfRestartsWithinTimeRangeReached message.
|
||||||
|
|
||||||
|
|
@ -213,7 +213,7 @@ Here is an example:
|
||||||
true)
|
true)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Programmatical linking and supervision of Untyped Actors
|
Programmatic linking and supervision of Untyped Actors
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Untyped Actors can at runtime create, spawn, link and supervise other actors. Linking and unlinking is done using one of the 'link' and 'unlink' methods available in the 'ActorRef' (therefore prefixed with getContext() in these examples).
|
Untyped Actors can at runtime create, spawn, link and supervise other actors. Linking and unlinking is done using one of the 'link' and 'unlink' methods available in the 'ActorRef' (therefore prefixed with getContext() in these examples).
|
||||||
|
|
@ -459,10 +459,10 @@ In the supervised TypedActor you can override the ‘preRestart’ and ‘postRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Programatical linking and supervision of TypedActors
|
Programatic linking and supervision of TypedActors
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TypedActors can be linked an unlinked just like UntypedActors:
|
TypedActors can be linked and unlinked just like UntypedActors:
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ The Actor's supervision can be declaratively defined by creating a "Supervisor'
|
||||||
|
|
||||||
Supervisors created like this are implicitly instantiated and started.
|
Supervisors created like this are implicitly instantiated and started.
|
||||||
|
|
||||||
To cofigure a handler function for when the actor underlying the supervisor recieves a MaximumNumberOfRestartsWithinTimeRangeReached message, you can specify a function of type
|
To configure a handler function for when the actor underlying the supervisor receives a MaximumNumberOfRestartsWithinTimeRangeReached message, you can specify a function of type
|
||||||
(ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached) => Unit when creating the SupervisorConfig. This handler will be called with the ActorRef of the supervisor and the
|
(ActorRef, MaximumNumberOfRestartsWithinTimeRangeReached) => Unit when creating the SupervisorConfig. This handler will be called with the ActorRef of the supervisor and the
|
||||||
MaximumNumberOfRestartsWithinTimeRangeReached message.
|
MaximumNumberOfRestartsWithinTimeRangeReached message.
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ Here is an example:
|
||||||
**true**)
|
**true**)
|
||||||
:: Nil))
|
:: Nil))
|
||||||
|
|
||||||
Programmatical linking and supervision of Actors
|
Programmatic linking and supervision of Actors
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Actors can at runtime create, spawn, link and supervise other actors. Linking and unlinking is done using one of the 'link' and 'unlink' methods available in the 'ActorRef' (therefore prefixed with 'self' in these examples).
|
Actors can at runtime create, spawn, link and supervise other actors. Linking and unlinking is done using one of the 'link' and 'unlink' methods available in the 'ActorRef' (therefore prefixed with 'self' in these examples).
|
||||||
|
|
@ -411,10 +411,10 @@ Then you can retrieve the Typed Actor as follows:
|
||||||
Restart callbacks
|
Restart callbacks
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Programatical linking and supervision of TypedActors
|
Programatic linking and supervision of TypedActors
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TypedActors can be linked an unlinked just like actors - in fact the linking is done on the underlying actor:
|
TypedActors can be linked and unlinked just like actors - in fact the linking is done on the underlying actor:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Use with Actors
|
||||||
|
|
||||||
There are generally two ways of getting a reply from an ``Actor``: the first is by a sent message (``actor ! msg``), which only works if the original sender was an ``Actor``) and the second is through a ``Future``.
|
There are generally two ways of getting a reply from an ``Actor``: the first is by a sent message (``actor ! msg``), which only works if the original sender was an ``Actor``) and the second is through a ``Future``.
|
||||||
|
|
||||||
Using an ``Actor``\'s ``!!!`` method to send a message will return a Future. To wait for and retreive the actual result the simplest method is:
|
Using an ``Actor``\'s ``!!!`` method to send a message will return a Future. To wait for and retrieve the actual result the simplest method is:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ If we do the opposite:
|
||||||
|
|
||||||
Our little string has been processed long before our 1 second sleep has finished. Because of this, the dispatcher has moved onto other messages that need processing and can no longer calculate the length of the string for us, instead it gets calculated in the current thread just as if we weren't using a Future.
|
Our little string has been processed long before our 1 second sleep has finished. Because of this, the dispatcher has moved onto other messages that need processing and can no longer calculate the length of the string for us, instead it gets calculated in the current thread just as if we weren't using a Future.
|
||||||
|
|
||||||
Normally this works quite well for us as it means there is very little overhead to running a quick Function. If there is a possiblity of the Function taking a non-trivial amount of time to process it might be better to have this done concurrently, and for that we use 'flatMap':
|
Normally this works quite well for us as it means there is very little overhead to running a quick Function. If there is a possibility of the Function taking a non-trivial amount of time to process it might be better to have this done concurrently, and for that we use 'flatMap':
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -150,7 +150,7 @@ The example for comprehension above is an example of composing Futures. A common
|
||||||
|
|
||||||
Here we have 2 actors processing a single message each. In the for comprehension we need to add the expected types in order to work with the results. Once the 2 results are available, they are being added together and sent to a third actor, which replies with a String, which we assign to 'result'.
|
Here we have 2 actors processing a single message each. In the for comprehension we need to add the expected types in order to work with the results. Once the 2 results are available, they are being added together and sent to a third actor, which replies with a String, which we assign to 'result'.
|
||||||
|
|
||||||
This is fine when dealing with a known amount of Actors, but can grow unwieldly if we have more then a handful. The 'sequence' and 'traverse' helper methods can make it easier to handle more complex use cases. Both of these methods are ways of turning a Traversable[Future[A]] into a Future[Traversable[A]]. For example:
|
This is fine when dealing with a known amount of Actors, but can grow unwieldy if we have more then a handful. The 'sequence' and 'traverse' helper methods can make it easier to handle more complex use cases. Both of these methods are ways of turning a Traversable[Future[A]] into a Future[Traversable[A]]. For example:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Download the release you need (Akka core or Akka Modules) from `<http://akka.io/
|
||||||
Microkernel
|
Microkernel
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
The Akka Modules distribution includes the mircokernel. To run the microkernel:
|
The Akka Modules distribution includes the microkernel. To run the microkernel:
|
||||||
|
|
||||||
* Set the AKKA_HOME environment variable to the root of the Akka distribution.
|
* Set the AKKA_HOME environment variable to the root of the Akka distribution.
|
||||||
* Run ``java -jar akka-modules-1.0.jar``. This will boot up the microkernel and deploy all samples applications from './deploy' dir.
|
* Run ``java -jar akka-modules-1.0.jar``. This will boot up the microkernel and deploy all samples applications from './deploy' dir.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ Guice Integration
|
||||||
|
|
||||||
Module stability: **STABLE**
|
Module stability: **STABLE**
|
||||||
|
|
||||||
All Typed Actors supports dependency injection using `Guice <http://code.google.com/p/google-guice/>`_ annotations (such as ‘@Inject’ etc.).
|
All Typed Actors support dependency injection using `Guice <http://code.google.com/p/google-guice/>`_ annotations (such as ‘@Inject’ etc.).
|
||||||
The ‘TypedActorManager’ class understands Guice and will do the wiring for you.
|
The ‘TypedActorManager’ class understands Guice and will do the wiring for you.
|
||||||
|
|
||||||
External Guice modules
|
External Guice modules
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ Endpoints are actors that handle request messages. Minimally there must be an in
|
||||||
Preparations
|
Preparations
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
In order to use Mist you have to register the MistServlet in *web.xml* or do the analogous for the embedded server if running in Akka Micrkernel:
|
In order to use Mist you have to register the MistServlet in *web.xml* or do the analogous for the embedded server if running in Akka Microkernel:
|
||||||
|
|
||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@ As noted above, hook functions are non-exclusive. This means multiple actors can
|
||||||
def receive = handleHttpRequest
|
def receive = handleHttpRequest
|
||||||
|
|
||||||
//
|
//
|
||||||
// this guy completes requests after other actions have occured
|
// this guy completes requests after other actions have occurred
|
||||||
//
|
//
|
||||||
lazy val complete = actorOf[ActionCompleteActor].start()
|
lazy val complete = actorOf[ActionCompleteActor].start()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Managing the Remote Service
|
||||||
Starting remote service in user code as a library
|
Starting remote service in user code as a library
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Here is how to start up the server and specify the hostname and port programatically:
|
Here is how to start up the server and specify the hostname and port programmatically:
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
|
|
@ -314,7 +314,7 @@ The API for server managed remote actors is really simple. 2 methods only:
|
||||||
|
|
||||||
Actors created like this are automatically started.
|
Actors created like this are automatically started.
|
||||||
|
|
||||||
You can also register an actor by its UUD rather than ID or handle. This is done by prefixing the handle with the "uuid:" protocol.
|
You can also register an actor by its UUID rather than ID or handle. This is done by prefixing the handle with the "uuid:" protocol.
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Starting up the remote service
|
||||||
Starting remote service in user code as a library
|
Starting remote service in user code as a library
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Here is how to start up the RemoteNode and specify the hostname and port programatically:
|
Here is how to start up the RemoteNode and specify the hostname and port programmatically:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -318,7 +318,7 @@ The API for server managed remote actors is really simple. 2 methods only:
|
||||||
|
|
||||||
Actors created like this are automatically started.
|
Actors created like this are automatically started.
|
||||||
|
|
||||||
You can also register an actor by its UUD rather than ID or handle. This is done by prefixing the handle with the "uuid:" protocol.
|
You can also register an actor by its UUID rather than ID or handle. This is done by prefixing the handle with the "uuid:" protocol.
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -645,7 +645,7 @@ So a simple listener actor can look like this:
|
||||||
case RemoteServerClientConnected(server, clientAddress) => ... // act upon client connection
|
case RemoteServerClientConnected(server, clientAddress) => ... // act upon client connection
|
||||||
case RemoteServerClientDisconnected(server, clientAddress) => ... // act upon client disconnection
|
case RemoteServerClientDisconnected(server, clientAddress) => ... // act upon client disconnection
|
||||||
case RemoteServerClientClosed(server, clientAddress) => ... // act upon client connection close
|
case RemoteServerClientClosed(server, clientAddress) => ... // act upon client connection close
|
||||||
case RemoteServerWriteFailed(request, casue, server, clientAddress) => ... // act upon server write failure
|
case RemoteServerWriteFailed(request, cause, server, clientAddress) => ... // act upon server write failure
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ How does it work (at least for REST actors)?
|
||||||
# The browser will send the *service ticket* to the web application encoded in the header value of the *Authorization*header
|
# The browser will send the *service ticket* to the web application encoded in the header value of the *Authorization*header
|
||||||
# The web application must validate the ticket based on a shared secret between the web application and the kerberos server. As a result the web application will know the name of the user
|
# The web application must validate the ticket based on a shared secret between the web application and the kerberos server. As a result the web application will know the name of the user
|
||||||
|
|
||||||
To activate the kerberos/SPNEGO authentication for your REST actor you need to enable the kerberos/SPNGEOauthentication actor in the akka.conf like this:
|
To activate the kerberos/SPNEGO authentication for your REST actor you need to enable the kerberos/SPNEGOauthentication actor in the akka.conf like this:
|
||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ Each serialization interface/trait in
|
||||||
Note however that if you are using one of the Serializable interfaces then you don’t have to do anything else in regard to sending remote messages.
|
Note however that if you are using one of the Serializable interfaces then you don’t have to do anything else in regard to sending remote messages.
|
||||||
|
|
||||||
The ones currently supported are (besides the default which is regular Java serialization):
|
The ones currently supported are (besides the default which is regular Java serialization):
|
||||||
* ScalaJON (Scala only)
|
* ScalaJSON (Scala only)
|
||||||
* JavaJSON (Java but some Scala structures)
|
* JavaJSON (Java but some Scala structures)
|
||||||
* SBinary (Scala only)
|
* SBinary (Scala only)
|
||||||
* Protobuf (Scala and Java)
|
* Protobuf (Scala and Java)
|
||||||
|
|
@ -439,7 +439,7 @@ Here are the steps that you need to follow:
|
||||||
Serializer API using reflection
|
Serializer API using reflection
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
You can also use the Serializer abstraction to serialize using reflection based serialization API of sjson. But we recommend using the type class based one, because reflection based serialization has limitations due to type erasure. Here's an example of reflection based serialization:
|
You can also use the Serializer abstraction to serialize using the reflection based serialization API of sjson. But we recommend using the type class based one, because reflection based serialization has limitations due to type erasure. Here's an example of reflection based serialization:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -672,7 +672,7 @@ Consider the following Scala class:
|
||||||
}
|
}
|
||||||
|
|
||||||
Because of erasure, you need to add the type hint declaratively through the annotation @JSONTypeHint that
|
Because of erasure, you need to add the type hint declaratively through the annotation @JSONTypeHint that
|
||||||
SJSON will pick up during serialization. No we can say:
|
SJSON will pick up during serialization. Now we can say:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -683,7 +683,7 @@ SJSON will pick up during serialization. No we can say:
|
||||||
c should equal(serializer.in[Contact](co))
|
c should equal(serializer.in[Contact](co))
|
||||||
}
|
}
|
||||||
|
|
||||||
With optional generic data members, we need to provide the hint to SJSON through another annotation@OptionTypeHint.
|
With optional generic data members, we need to provide the hint to SJSON through another annotation @OptionTypeHint.
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -714,7 +714,7 @@ Serialization works ok with optional members annotated as above.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also specify a custom ClassLoader while using SJSON serializer:
|
You can also specify a custom ClassLoader while using the SJSON serializer:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -915,7 +915,7 @@ For your POJOs to be able to serialize themselves you have to extend the JavaJSO
|
||||||
SerializerFactory factory = new SerializerFactory();
|
SerializerFactory factory = new SerializerFactory();
|
||||||
MyMessage messageCopy = factory.getJavaJSON().in(json);
|
MyMessage messageCopy = factory.getJavaJSON().in(json);
|
||||||
|
|
||||||
Use the akka.serialization.SerializerFactory.getJavaJSON to do generic JSONserialization, e.g. serialize object that does not extend JavaJSON using the JSON serializer.
|
Use the akka.serialization.SerializerFactory.getJavaJSON to do generic JSON serialization, e.g. serialize object that does not extend JavaJSON using the JSON serializer.
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
|
|
@ -948,7 +948,7 @@ If you need to serialize your own user-defined objects then you have to do three
|
||||||
## toBytes: Array[Byte]
|
## toBytes: Array[Byte]
|
||||||
# Create an implicit sbinary.Format[T] object for your class. Which means that you have to define its two methods:
|
# Create an implicit sbinary.Format[T] object for your class. Which means that you have to define its two methods:
|
||||||
## reads(in: Input): T; in which you read in all the fields in your object, using read[FieldType](in)and recreate it.
|
## reads(in: Input): T; in which you read in all the fields in your object, using read[FieldType](in)and recreate it.
|
||||||
## writes(out: Output, value: T): Unit; in which you write out all the fields in your object, usingwrite[FieldType](out, value.field).
|
## writes(out: Output, value: T): Unit; in which you write out all the fields in your object, using write[FieldType](out, value.field).
|
||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
`<code format="scala">`_
|
`<code format="scala">`_
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
Scalable Solutions
|
Scalable Solutions
|
||||||
==================
|
==================
|
||||||
|
|
||||||
Scalable Solutions AB is commercial entity behind Akka, providing support, consulting and training around Akka.
|
Scalable Solutions AB is the commercial entity behind Akka, providing support, consulting and training around Akka.
|
||||||
`<http://scalablesolutions.se>`_
|
`<http://scalablesolutions.se>`_
|
||||||
|
|
||||||
YourKit
|
YourKit
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ The Akka Software Transactional Memory implementation
|
||||||
|
|
||||||
Read consistency is that all value
|
Read consistency is that all value
|
||||||
|
|
||||||
**Read concistency and MVCC**
|
**Read consistency and MVCC**
|
||||||
*****************************
|
*****************************
|
||||||
|
|
||||||
A lot of STM (like the Clojure STM) implementations are Multi Version Concurrency Control Based (MVCC) based (TL2 of david dice could be seen as MVCC).
|
A lot of STM (like the Clojure STM) implementations are Multi Version Concurrency Control Based (MVCC) based (TL2 of david dice could be seen as MVCC).
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Overview
|
||||||
|
|
||||||
Testing actors comprises several aspects, which can have different weight according to the concrete project at hand:
|
Testing actors comprises several aspects, which can have different weight according to the concrete project at hand:
|
||||||
* If you have a collection of actors which performs a certain function, you may want to apply defined stimuli and observe the delivery of the desired result messages to a test actor; in this case the ***TestKit*** trait will likely interest you.
|
* If you have a collection of actors which performs a certain function, you may want to apply defined stimuli and observe the delivery of the desired result messages to a test actor; in this case the ***TestKit*** trait will likely interest you.
|
||||||
* If you encounter undesired behaviour (exceptions, dead-locks) and want to nail down the cause, it might help to run the actors in question using the ***CallingThreadDispatcher***; this dispatcher is strictly less powerful than the general purpose ones, but its deterministic behaviour and complete message stack can help debugging, unless your setup depends on concurrent execution for correctness.
|
* If you encounter undesired behavior (exceptions, dead-locks) and want to nail down the cause, it might help to run the actors in question using the ***CallingThreadDispatcher***; this dispatcher is strictly less powerful than the general purpose ones, but its deterministic behavior and complete message stack can help debugging, unless your setup depends on concurrent execution for correctness.
|
||||||
* For real unit tests of one actor body at a time, there soon will be a special ***TestActorRef*** which allows access to the innards and enables running without a dispatcher.
|
* For real unit tests of one actor body at a time, there soon will be a special ***TestActorRef*** which allows access to the innards and enables running without a dispatcher.
|
||||||
|
|
||||||
TestKit
|
TestKit
|
||||||
|
|
@ -42,7 +42,7 @@ CallingThreadDispatcher
|
||||||
|
|
||||||
This special purpose dispatcher was conceived to enable collection of the full stack trace accumulated during processing of a complete message chain. The idea is to run invocations always on the calling thread, except when the target actor is already running on the current thread; in that case it is necessary to queue the invocation and run it after the current invocation on that actor has finished processing. This design implies that any invocation which blocks waiting on some future action to be done by the current thread will dead-lock. Hence, the CallingThreadDispatcher offers strictly more possibilities to dead-lock than a standard dispatcher.
|
This special purpose dispatcher was conceived to enable collection of the full stack trace accumulated during processing of a complete message chain. The idea is to run invocations always on the calling thread, except when the target actor is already running on the current thread; in that case it is necessary to queue the invocation and run it after the current invocation on that actor has finished processing. This design implies that any invocation which blocks waiting on some future action to be done by the current thread will dead-lock. Hence, the CallingThreadDispatcher offers strictly more possibilities to dead-lock than a standard dispatcher.
|
||||||
|
|
||||||
One nice property is that this feature can help verify that your design is dead-lock free: if you run only on this dispatcher and utilitze only one thread, then a successful run implies that for the given set of inputs there cannot be a dead-lock. (This is unfortunately not a hard guarantee, as long as your actor behavior depends on the dispatcher used, e.g. you could sabotage it by explicitly dead-locking only if self.dispatcher != CallingThreadDispatcher.)
|
One nice property is that this feature can help verify that your design is dead-lock free: if you run only on this dispatcher and utilize only one thread, then a successful run implies that for the given set of inputs there cannot be a dead-lock. (This is unfortunately not a hard guarantee, as long as your actor behavior depends on the dispatcher used, e.g. you could sabotage it by explicitly dead-locking only if self.dispatcher != CallingThreadDispatcher.)
|
||||||
|
|
||||||
TestActorRef (coming soon ...)
|
TestActorRef (coming soon ...)
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ Example of coordinating an increment, similar to the explicitly coordinated exam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
To exeucte directly before or after the coordinated transaction, override the ``before`` and ``after`` methods. These methods also expect partial functions like the receive method. They do not execute within the transaction.
|
To execute directly before or after the coordinated transaction, override the ``before`` and ``after`` methods. These methods also expect partial functions like the receive method. They do not execute within the transaction.
|
||||||
|
|
||||||
To completely bypass coordinated transactions override the ``normally`` method. Any message matched by ``normally`` will not be matched by the other methods, and will not be involved in coordinated transactions. In this method you can implement normal actor behavior, or use the normal STM atomic for local transactions.
|
To completely bypass coordinated transactions override the ``normally`` method. Any message matched by ``normally`` will not be matched by the other methods, and will not be involved in coordinated transactions. In this method you can implement normal actor behavior, or use the normal STM atomic for local transactions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ Using ``sendTo`` to coordinate transactions but pass-on a different message than
|
||||||
case SomeMessage => sendTo(actor1 -> Message1, actor2 -> Message2)
|
case SomeMessage => sendTo(actor1 -> Message1, actor2 -> Message2)
|
||||||
}
|
}
|
||||||
|
|
||||||
To exeucte directly before or after the coordinated transaction, override the ``before`` and ``after`` methods. These methods also expect partial functions like the receive method. They do not execute within the transaction.
|
To execute directly before or after the coordinated transaction, override the ``before`` and ``after`` methods. These methods also expect partial functions like the receive method. They do not execute within the transaction.
|
||||||
|
|
||||||
To completely bypass coordinated transactions override the ``normally`` method. Any message matched by ``normally`` will not be matched by the other methods, and will not be involved in coordinated transactions. In this method you can implement normal actor behavior, or use the normal STM atomic for local transactions.
|
To completely bypass coordinated transactions override the ``normally`` method. Any message matched by ``normally`` will not be matched by the other methods, and will not be involved in coordinated transactions. In this method you can implement normal actor behavior, or use the normal STM atomic for local transactions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -358,7 +358,7 @@ It responds to two different messages; 'ChatMessage' and 'GetChatLog'. The 'Chat
|
||||||
|
|
||||||
The 'GetChatLog' message handler retrieves all the messages in the chat log storage inside an atomic block, iterates over them using the 'map' combinator transforming them from 'Array[Byte] to 'String'. Then it invokes the 'reply(message)' function that will send the chat log to the original sender; the 'ChatClient'.
|
The 'GetChatLog' message handler retrieves all the messages in the chat log storage inside an atomic block, iterates over them using the 'map' combinator transforming them from 'Array[Byte] to 'String'. Then it invokes the 'reply(message)' function that will send the chat log to the original sender; the 'ChatClient'.
|
||||||
|
|
||||||
You might rememeber that the 'ChatServer' was supervising the 'ChatStorage' actor. When we discussed that we showed you the supervising Actor's view. Now is the time for the supervised Actor's side of things. First, a supervised Actor need to define a life-cycle in which it declares if it should be seen as a:
|
You might remember that the 'ChatServer' was supervising the 'ChatStorage' actor. When we discussed that we showed you the supervising Actor's view. Now is the time for the supervised Actor's side of things. First, a supervised Actor need to define a life-cycle in which it declares if it should be seen as a:
|
||||||
|
|
||||||
* 'Permanent': which means that the actor will always be restarted.
|
* 'Permanent': which means that the actor will always be restarted.
|
||||||
* 'Temporary': which means that the actor will not be restarted, but it will be shut down through the regular shutdown process so the 'postStop' callback function will called.
|
* 'Temporary': which means that the actor will not be restarted, but it will be shut down through the regular shutdown process so the 'postStop' callback function will called.
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ Methods that return void are turned into ‘fire-and-forget’ semantics by asyn
|
||||||
Request-reply message send
|
Request-reply message send
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Methods that return something (e.g. non-void methods) are turned into ‘send-and-recieve-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
|
Methods that return something (e.g. non-void methods) are turned into ‘send-and-receive-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ The same holds for the 'request-reply-with-future' described below.
|
||||||
Request-reply-with-future message send
|
Request-reply-with-future message send
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Methods that return a 'akka.dispatch.Future<TYPE>' are turned into ‘send-and-recieve-with-future’ semantics by asynchronously firing off the message and returns immediately with a Future. You need to use the 'future(...)' method in the TypedActor base class to resolve the Future that the client code is waiting on.
|
Methods that return a 'akka.dispatch.Future<TYPE>' are turned into ‘send-and-receive-with-future’ semantics by asynchronously firing off the message and returns immediately with a Future. You need to use the 'future(...)' method in the TypedActor base class to resolve the Future that the client code is waiting on.
|
||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Methods that return void are turned into ‘fire-and-forget’ semantics by asyn
|
||||||
Request-reply message send
|
Request-reply message send
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Methods that return something (e.g. non-void methods) are turned into ‘send-and-recieve-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
|
Methods that return something (e.g. non-void methods) are turned into ‘send-and-receive-eventually’ semantics by asynchronously firing off the message and wait on the reply using a Future.
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ Generally it is preferred to use fire-forget messages as much as possible since
|
||||||
Request-reply-with-future message send
|
Request-reply-with-future message send
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Methods that return a 'akka.dispatch.Future<TYPE>' are turned into ‘send-and-recieve-with-future’ semantics by asynchronously firing off the message and returns immediately with a Future. You need to use the 'future(...)' method in the TypedActor base class to resolve the Future that the client code is waiting on.
|
Methods that return a 'akka.dispatch.Future<TYPE>' are turned into ‘send-and-receive-with-future’ semantics by asynchronously firing off the message and returns immediately with a Future. You need to use the 'future(...)' method in the TypedActor base class to resolve the Future that the client code is waiting on.
|
||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ You can also create & start the actor in one statement:
|
||||||
|
|
||||||
ActorRef myActor = actorOf(SampleUntypedActor.class).start();
|
ActorRef myActor = actorOf(SampleUntypedActor.class).start();
|
||||||
|
|
||||||
The call to 'actorOf' returns an instance of 'ActorRef'. This is a handle to the 'UntypedActor' instance which you can use to interact with the Actor, like send messages to it etc. more on this shortly. The 'ActorRef' is immutble and has a one to one relationship with the Actor it represents. The 'ActorRef' is also serializable and network-aware. This means that you can serialize it, send it over the wire and use it on a remote host and it will still be representing the same Actor on the original node, across the network.
|
The call to 'actorOf' returns an instance of 'ActorRef'. This is a handle to the 'UntypedActor' instance which you can use to interact with the Actor, like send messages to it etc. more on this shortly. The 'ActorRef' is immutable and has a one to one relationship with the Actor it represents. The 'ActorRef' is also serializable and network-aware. This means that you can serialize it, send it over the wire and use it on a remote host and it will still be representing the same Actor on the original node, across the network.
|
||||||
|
|
||||||
Creating Actors with non-default constructor
|
Creating Actors with non-default constructor
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
@ -103,7 +103,7 @@ Messages are sent to an Actor through one of the 'send' methods.
|
||||||
* 'sendRequestReply' means “send-and-reply-eventually”, e.g. send a message asynchronously and wait for a reply through a Future. Here you can specify a timeout. Using timeouts is very important. If no timeout is specified then the actor’s default timeout (set by the 'getContext().setTimeout(..)' method in the 'ActorRef') is used. This method throws an 'ActorTimeoutException' if the call timed out.
|
* 'sendRequestReply' means “send-and-reply-eventually”, e.g. send a message asynchronously and wait for a reply through a Future. Here you can specify a timeout. Using timeouts is very important. If no timeout is specified then the actor’s default timeout (set by the 'getContext().setTimeout(..)' method in the 'ActorRef') is used. This method throws an 'ActorTimeoutException' if the call timed out.
|
||||||
* 'sendRequestReplyFuture' sends a message asynchronously and returns a 'Future'.
|
* 'sendRequestReplyFuture' sends a message asynchronously and returns a 'Future'.
|
||||||
|
|
||||||
In all these methods you have the option of passing along your 'ActorRef' context variable. Make it a practive of doing so because it will allow the receiver actors to be able to respond to your message, since the sender reference is sent along with the message.
|
In all these methods you have the option of passing along your 'ActorRef' context variable. Make it a practice of doing so because it will allow the receiver actors to be able to respond to your message, since the sender reference is sent along with the message.
|
||||||
|
|
||||||
Fire-forget
|
Fire-forget
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
@ -138,7 +138,7 @@ Here are some examples:
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
UnypedActorRef actorRef = ...
|
UntypedActorRef actorRef = ...
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object result = actorRef.sendRequestReply("Hello", getContext(), 1000);
|
Object result = actorRef.sendRequestReply("Hello", getContext(), 1000);
|
||||||
|
|
@ -256,7 +256,7 @@ The 'replyUnsafe' method throws an 'IllegalStateException' if unable to determin
|
||||||
Reply using the sender reference
|
Reply using the sender reference
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
If the sender reference (the sender's 'ActorRef') is passed into one ofe the 'send*' methods it will be implicitly passed along together with the message and will be available in the 'Option<ActorRef> getSender()' method on the 'ActorRef. This means that you can use this field to send a message back to the sender.
|
If the sender reference (the sender's 'ActorRef') is passed into one of the 'send*' methods it will be implicitly passed along together with the message and will be available in the 'Option<ActorRef> getSender()' method on the 'ActorRef. This means that you can use this field to send a message back to the sender.
|
||||||
|
|
||||||
On this 'Option' you can invoke 'boolean isDefined()' or 'boolean isEmpty()' to check if the sender is available or not, and if it is call 'get()' to get the reference. It's important to know that 'getSender().get()' will throw an exception if there is no sender in scope. The same pattern holds for using the 'getSenderFuture()' in the section below.
|
On this 'Option' you can invoke 'boolean isDefined()' or 'boolean isEmpty()' to check if the sender is available or not, and if it is call 'get()' to get the reference. It's important to know that 'getSender().get()' will throw an exception if there is no sender in scope. The same pattern holds for using the 'getSenderFuture()' in the section below.
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ On this 'Option' you can invoke 'boolean isDefined()' or 'boolean isEmpty()' to
|
||||||
String msg = (String)message;
|
String msg = (String)message;
|
||||||
if (msg.equals("Hello")) {
|
if (msg.equals("Hello")) {
|
||||||
// Reply to original sender of message using the sender reference
|
// Reply to original sender of message using the sender reference
|
||||||
// also passing along my own refererence (the context)
|
// also passing along my own reference (the context)
|
||||||
if (getContext().getSender().isDefined)
|
if (getContext().getSender().isDefined)
|
||||||
getContext().getSender().get().sendOneWay(msg + " from " + getContext().getUuid(), getContext());
|
getContext().getSender().get().sendOneWay(msg + " from " + getContext().getUuid(), getContext());
|
||||||
}
|
}
|
||||||
|
|
@ -279,7 +279,7 @@ Reply using the sender future
|
||||||
|
|
||||||
If a message was sent with the 'sendRequestReply' or 'sendRequestReplyFuture' methods, which both implements request-reply semantics using Future's, then you either have the option of replying using the 'reply' method as above. This method will then resolve the Future. But you can also get a reference to the Future directly and resolve it yourself or if you would like to store it away to resolve it later, or pass it on to some other Actor to resolve it.
|
If a message was sent with the 'sendRequestReply' or 'sendRequestReplyFuture' methods, which both implements request-reply semantics using Future's, then you either have the option of replying using the 'reply' method as above. This method will then resolve the Future. But you can also get a reference to the Future directly and resolve it yourself or if you would like to store it away to resolve it later, or pass it on to some other Actor to resolve it.
|
||||||
|
|
||||||
The reference to the Future resides in the 'ActorRef' instance and can be retreived using 'Option<CompletableFuture> getSenderFuture()'.
|
The reference to the Future resides in the 'ActorRef' instance and can be retrieved using 'Option<CompletableFuture> getSenderFuture()'.
|
||||||
|
|
||||||
CompletableFuture is a future with methods for 'completing the future:
|
CompletableFuture is a future with methods for 'completing the future:
|
||||||
* completeWithResult(..)
|
* completeWithResult(..)
|
||||||
|
|
@ -337,7 +337,7 @@ Actors are started by invoking the ‘start’ method.
|
||||||
ActorRef actor = actorOf(SampleUntypedActor.class);
|
ActorRef actor = actorOf(SampleUntypedActor.class);
|
||||||
myActor.start();
|
myActor.start();
|
||||||
|
|
||||||
You can create and start the Actor in a oneliner like this:
|
You can create and start the Actor in a one liner like this:
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -372,7 +372,7 @@ Actors are started by invoking the ``start`` method.
|
||||||
val actor = actorOf[MyActor]
|
val actor = actorOf[MyActor]
|
||||||
actor.start()
|
actor.start()
|
||||||
|
|
||||||
You can create and start the ``Actor`` in a oneliner like this:
|
You can create and start the ``Actor`` in a one liner like this:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ B and C.
|
||||||
case object B extends ExampleState
|
case object B extends ExampleState
|
||||||
case object C extends ExampleState
|
case object C extends ExampleState
|
||||||
|
|
||||||
Now lets create an object representing the FSM and defining the behaviour.
|
Now lets create an object representing the FSM and defining the behavior.
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ Akka Actor
|
||||||
==========
|
==========
|
||||||
|
|
||||||
# is now dependency free, with the exception of the dependency on the ``scala-library.jar``
|
# is now dependency free, with the exception of the dependency on the ``scala-library.jar``
|
||||||
# does not bundle any logging anymore, but you can subscribe to events within Akka by registering an event handler on akka.aevent.EventHandler or by specifying the ``FQN`` of an Actor in the akka.conf under akka.event-handlers; there is an ``akka-slf4j`` module which still provides the Logging trait and a default ``SLF4J`` logger adapter.
|
# does not bundle any logging anymore, but you can subscribe to events within Akka by registering an event handler on akka.event.EventHandler or by specifying the ``FQN`` of an Actor in the akka.conf under akka.event-handlers; there is an ``akka-slf4j`` module which still provides the Logging trait and a default ``SLF4J`` logger adapter.
|
||||||
Don't forget to add a SLF4J backend though, we recommend:
|
Don't forget to add a SLF4J backend though, we recommend:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ trait NettyRemoteClientModule extends RemoteClientModule { self: ListenerManagem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the abstract baseclass for netty remote clients, currently there's only an
|
* This is the abstract baseclass for netty remote clients, currently there's only an
|
||||||
* ActiveRemoteClient, but otehrs could be feasible, like a PassiveRemoteClient that
|
* ActiveRemoteClient, but others could be feasible, like a PassiveRemoteClient that
|
||||||
* reuses an already established connection.
|
* reuses an already established connection.
|
||||||
*/
|
*/
|
||||||
abstract class RemoteClient private[akka] (
|
abstract class RemoteClient private[akka] (
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class Ticket434Spec extends AkkaRemoteTest {
|
||||||
latch.await(1, unit) must be (true)
|
latch.await(1, unit) must be (true)
|
||||||
}
|
}
|
||||||
|
|
||||||
"should be possible to set the acor id and uuuid" in {
|
"should be possible to set the actor id and uuid" in {
|
||||||
val uuid = newUuid
|
val uuid = newUuid
|
||||||
val actorInfo = ActorInfoProtocol.newBuilder
|
val actorInfo = ActorInfoProtocol.newBuilder
|
||||||
.setUuid(UuidProtocol.newBuilder.setHigh(uuid.getTime).setLow(uuid.getClockSeqAndNode).build)
|
.setUuid(UuidProtocol.newBuilder.setHigh(uuid.getTime).setLow(uuid.getClockSeqAndNode).build)
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ case class SendTo(actor: ActorRef, message: Option[Any] = None)
|
||||||
* }}}
|
* }}}
|
||||||
* <br/>
|
* <br/>
|
||||||
*
|
*
|
||||||
* To exeucte directly before or after the coordinated transaction, override
|
* To execute directly before or after the coordinated transaction, override
|
||||||
* the `before` and `after` methods. These methods also expect partial functions
|
* the `before` and `after` methods. These methods also expect partial functions
|
||||||
* like the receive method. They do not execute within the transaction.
|
* like the receive method. They do not execute within the transaction.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class TypedActorRegistrySpec extends WordSpec with MustMatchers {
|
||||||
|
|
||||||
"Typed Actor" should {
|
"Typed Actor" should {
|
||||||
|
|
||||||
"be able to be retreived from the registry by class" in {
|
"be able to be retrieved from the registry by class" in {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
||||||
val actors = Actor.registry.typedActorsFor(classOf[My])
|
val actors = Actor.registry.typedActorsFor(classOf[My])
|
||||||
|
|
@ -24,7 +24,7 @@ class TypedActorRegistrySpec extends WordSpec with MustMatchers {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
"be able to be retreived from the registry by manifest" in {
|
"be able to be retrieved from the registry by manifest" in {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
||||||
val option = Actor.registry.typedActorFor[My]
|
val option = Actor.registry.typedActorFor[My]
|
||||||
|
|
@ -33,7 +33,7 @@ class TypedActorRegistrySpec extends WordSpec with MustMatchers {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
"be able to be retreived from the registry by class two times" in {
|
"be able to be retrieved from the registry by class two times" in {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
||||||
val actors1 = Actor.registry.typedActorsFor(classOf[My])
|
val actors1 = Actor.registry.typedActorsFor(classOf[My])
|
||||||
|
|
@ -43,7 +43,7 @@ class TypedActorRegistrySpec extends WordSpec with MustMatchers {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
"be able to be retreived from the registry by manifest two times" in {
|
"be able to be retrieved from the registry by manifest two times" in {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
val my = TypedActor.newInstance[My](classOf[My], classOf[MyImpl], 3000)
|
||||||
val option1 = Actor.registry.typedActorFor[My]
|
val option1 = Actor.registry.typedActorFor[My]
|
||||||
|
|
@ -55,7 +55,7 @@ class TypedActorRegistrySpec extends WordSpec with MustMatchers {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
"be able to be retreived from the registry by manifest two times (even when created in supervisor)" in {
|
"be able to be retrieved from the registry by manifest two times (even when created in supervisor)" in {
|
||||||
Actor.registry.shutdownAll()
|
Actor.registry.shutdownAll()
|
||||||
val manager = new TypedActorConfigurator
|
val manager = new TypedActorConfigurator
|
||||||
manager.configure(
|
manager.configure(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue