Merge with master

This commit is contained in:
Viktor Klang 2011-12-15 14:10:08 +01:00
commit 009853f2f6
168 changed files with 2942 additions and 6005 deletions

View file

@ -40,7 +40,7 @@ along with the implementation of how the messages should be processed.
Here is an example:
.. includecode:: code/ActorDocSpec.scala
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
:include: imports1,my-actor
Please note that the Akka Actor ``receive`` message loop is exhaustive, which is
@ -53,8 +53,8 @@ thrown and the actor is restarted when an unknown message is received.
Creating Actors with default constructor
----------------------------------------
.. includecode:: code/ActorDocSpec.scala
:include: imports2,system-actorOf
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
:include: imports2,system-actorOf
The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to
the ``Actor`` instance which you can use to interact with the ``Actor``. The
@ -70,7 +70,7 @@ how the supervisor hierarchy is arranged. When using the context the current act
will be supervisor of the created child actor. When using the system it will be
a top level actor, that is supervised by the system (internal guardian actor).
.. includecode:: code/ActorDocSpec.scala#context-actorOf
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#context-actorOf
Actors are automatically started asynchronously when created.
When you create the ``Actor`` then it will automatically call the ``preStart``
@ -92,16 +92,24 @@ a call-by-name block in which you can create the Actor in any way you like.
Here is an example:
.. includecode:: code/ActorDocSpec.scala#creating-constructor
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-constructor
Props
-----
``Props`` is a configuration class to specify options for the creation
of actors. Here are some examples on how to create a ``Props`` instance.
.. includecode:: code/ActorDocSpec.scala#creating-props-config
Creating Actors with Props
--------------------------
``Props`` is a configuration object to specify additional things for the actor to
be created, such as the ``MessageDispatcher``.
Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method.
.. includecode:: code/ActorDocSpec.scala#creating-props
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-props
Creating Actors using anonymous classes
@ -109,7 +117,7 @@ Creating Actors using anonymous classes
When spawning actors for specific sub-tasks from within an actor, it may be convenient to include the code to be executed directly in place, using an anonymous class.
.. includecode:: code/ActorDocSpec.scala#anonymous-actor
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#anonymous-actor
.. warning::
@ -145,13 +153,16 @@ In addition, it offers:
You can import the members in the :obj:`context` to avoid prefixing access with ``context.``
.. includecode:: code/ActorDocSpec.scala#import-context
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#import-context
The remaining visible methods are user-overridable life-cycle hooks which are
described in the following::
def preStart() {}
def preRestart(reason: Throwable, message: Option[Any]) { postStop() }
def preRestart(reason: Throwable, message: Option[Any]) {
context.children foreach (context.stop(_))
postStop()
}
def postRestart(reason: Throwable) { preStart() }
def postStop() {}
@ -185,7 +196,7 @@ processing a message. This restart involves the hooks mentioned above:
message, e.g. when a supervisor does not trap the exception and is restarted
in turn by its supervisor. This method is the best place for cleaning up,
preparing hand-over to the fresh actor instance, etc.
By default it calls :meth:`postStop`.
By default it stops all children and calls :meth:`postStop`.
2. The initial factory from the ``actorOf`` call is used
to produce the fresh instance.
3. The new actors :meth:`postRestart` method is invoked with the exception
@ -287,7 +298,7 @@ To complete the future with an exception you need send a Failure message to the
This is not done automatically when an actor throws an exception while processing a
message.
.. includecode:: code/ActorDocSpec.scala#reply-exception
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#reply-exception
If the actor does not complete the future, it will expire after the timeout period,
which is taken from one of the following locations in order of precedence:
@ -336,7 +347,7 @@ type, it will throw the exception or a :class:`ClassCastException` (if you want
to get :obj:`None` in the latter case, use :meth:`Future.asSilently[T]`). In
case of a timeout, :obj:`None` is returned.
.. includecode:: code/ActorDocSpec.scala#using-ask
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-ask
Forward message
---------------
@ -368,7 +379,7 @@ This method should return a ``PartialFunction``, e.g. a match/case clause
which the message can be matched against the different case clauses using Scala
pattern matching. Here is an example:
.. includecode:: code/ActorDocSpec.scala
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
:include: imports1,my-actor
@ -398,19 +409,17 @@ received within a certain time. To receive this timeout you have to set the
``receiveTimeout`` property and declare a case handing the ReceiveTimeout
object.
.. includecode:: code/ActorDocSpec.scala#receive-timeout
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#receive-timeout
Stopping actors
===============
Actors are stopped by invoking the ``stop`` method of the ``ActorRef``.
The actual termination of the actor is performed asynchronously, i.e.
``stop`` may return before the actor is stopped.
.. code-block:: scala
actor.stop()
Actors are stopped by invoking the :meth:`stop` method of a ``ActorRefFactory``,
i.e. ``ActorContext`` or ``ActorSystem``. Typically the context is used for stopping
child actors and the system for stopping top level actors. The actual termination of
the actor is performed asynchronously, i.e. :meth:`stop` may return before the actor is
stopped.
Processing of the current message, if any, will continue before the actor is stopped,
but additional messages in the mailbox will not be processed. By default these
@ -464,7 +473,7 @@ pushed and popped.
To hotswap the Actor behavior using ``become``:
.. includecode:: code/ActorDocSpec.scala#hot-swap-actor
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#hot-swap-actor
The ``become`` method is useful for many different things, but a particular nice
example of it is in example where it is used to implement a Finite State Machine
@ -474,12 +483,12 @@ example of it is in example where it is used to implement a Finite State Machine
Here is another little cute example of ``become`` and ``unbecome`` in action:
.. includecode:: code/ActorDocSpec.scala#swapper
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#swapper
Encoding Scala Actors nested receives without accidentally leaking memory
-------------------------------------------------------------------------
See this `Unnested receive example <http://github.com/jboner/akka/blob/master/akka/akka-docs/scala/code/UnnestedReceives.scala>`_.
See this `Unnested receive example <http://github.com/jboner/akka/blob/master/akka/akka-docs/scala/code/akka/docs/actor/UnnestedReceives.scala>`_.
Downgrade
@ -555,4 +564,4 @@ A bit advanced but very useful way of defining a base message handler and then
extend that, either through inheritance or delegation, is to use
``PartialFunction.orElse`` chaining.
.. includecode:: code/ActorDocSpec.scala#receive-orElse
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#receive-orElse

View file

@ -1,147 +1,4 @@
Agents (Scala)
==============
.. sidebar:: Contents
.. contents:: :local:
Agents in Akka were inspired by `agents in Clojure <http://clojure.org/agents>`_.
Agents provide asynchronous change of individual locations. Agents are bound to a single storage location for their lifetime, and only allow mutation of that location (to a new state) to occur as a result of an action. Update actions are functions that are asynchronously applied to the Agent's state and whose return value becomes the Agent's new state. The state of an Agent should be immutable.
While updates to Agents are asynchronous, the state of an Agent is always immediately available for reading by any thread (using ``get`` or ``apply``) without any messages.
Agents are reactive. The update actions of all Agents get interleaved amongst threads in a thread pool. At any point in time, at most one ``send`` action for each Agent is being executed. Actions dispatched to an agent from another thread will occur in the order they were sent, potentially interleaved with actions dispatched to the same agent from other sources.
If an Agent is used within an enclosing transaction, then it will participate in that transaction. Agents are integrated with the STM - any dispatches made in a transaction are held until that transaction commits, and are discarded if it is retried or aborted.
Creating and stopping Agents
----------------------------
Agents are created by invoking ``Agent(value)`` passing in the Agent's initial value.
.. code-block:: scala
val agent = Agent(5)
An Agent will be running until you invoke ``close`` on it. Then it will be eligible for garbage collection (unless you hold on to it in some way).
.. code-block:: scala
agent.close()
Updating Agents
---------------
You update an Agent by sending a function that transforms the current value or by sending just a new value. The Agent will apply the new value or function atomically and asynchronously. The update is done in a fire-forget manner and you are only guaranteed that it will be applied. There is no guarantee of when the update will be applied but dispatches to an Agent from a single thread will occur in order. You apply a value or a function by invoking the ``send`` function.
.. code-block:: scala
// send a value
agent send 7
// send a function
agent send (_ + 1)
agent send (_ * 2)
You can also dispatch a function to update the internal state but on its own thread. This does not use the reactive thread pool and can be used for long-running or blocking operations. You do this with the ``sendOff`` method. Dispatches using either ``sendOff`` or ``send`` will still be executed in order.
.. code-block:: scala
// sendOff a function
agent sendOff (longRunningOrBlockingFunction)
Reading an Agent's value
------------------------
Agents can be dereferenced, e.g. you can get an Agent's value, by invoking the Agent with parenthesis like this:
.. code-block:: scala
val result = agent()
Or by using the get method.
.. code-block:: scala
val result = agent.get
Reading an Agent's current value does not involve any message passing and happens immediately. So while updates to an Agent are asynchronous, reading the state of an Agent is synchronous.
Awaiting an Agent's value
-------------------------
It is also possible to read the value after all currently queued ``send``\s have completed. You can do this with ``await``:
.. code-block:: scala
val result = agent.await
You can also get a ``Future`` to this value, that will be completed after the currently queued updates have completed:
.. code-block:: scala
val future = agent.future
// ...
val result = future.await.result.get
Transactional Agents
--------------------
If an Agent is used within an enclosing transaction, then it will participate in that transaction. If you send to an Agent within a transaction then the dispatch to the Agent will be held until that transaction commits, and discarded if the transaction is aborted.
.. code-block:: scala
import akka.agent.Agent
import akka.stm._
def transfer(from: Agent[Int], to: Agent[Int], amount: Int): Boolean = {
atomic {
if (from.get < amount) false
else {
from send (_ - amount)
to send (_ + amount)
true
}
}
}
val from = Agent(100)
val to = Agent(20)
val ok = transfer(from, to, 50)
from() // -> 50
to() // -> 70
Monadic usage
-------------
Agents are also monadic, allowing you to compose operations using for-comprehensions. In a monadic usage, new Agents are created leaving the original Agents untouched. So the old values (Agents) are still available as-is. They are so-called 'persistent'.
Example of a monadic usage:
.. code-block:: scala
val agent1 = Agent(3)
val agent2 = Agent(5)
// uses foreach
var result = 0
for (value <- agent1) {
result = value + 1
}
// uses map
val agent3 =
for (value <- agent1) yield value + 1
// uses flatMap
val agent4 = for {
value1 <- agent1
value2 <- agent2
} yield value1 + value2
agent1.close()
agent2.close()
agent3.close()
agent4.close()
The Akka Agents module has not been migrated to Akka 2.0-SNAPSHOT yet.

View file

@ -1,27 +0,0 @@
package akka.docs.stm
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
class StmDocSpec extends WordSpec with MustMatchers {
"simple counter example" in {
//#simple
import akka.stm._
val ref = Ref(0)
def counter = atomic {
ref alter (_ + 1)
}
counter
// -> 1
counter
// -> 2
//#simple
ref.get must be === 2
}
}

View file

@ -15,6 +15,7 @@ import akka.actor.ActorSystem
import org.scalatest.{ BeforeAndAfterAll, WordSpec }
import org.scalatest.matchers.MustMatchers
import akka.testkit._
import akka.util._
import akka.util.duration._
//#my-actor
@ -187,6 +188,23 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) {
system.stop(myActor)
}
"creating a Props config" in {
val dispatcher = system.dispatcherFactory.lookup("my-dispatcher")
//#creating-props-config
import akka.actor.Props
val props1 = Props()
val props2 = Props[MyActor]
val props3 = Props(new MyActor)
val props4 = Props(
creator = { () new MyActor },
dispatcher = dispatcher,
timeout = Timeout(100))
val props5 = props1.withCreator(new MyActor)
val props6 = props5.withDispatcher(dispatcher)
val props7 = props6.withTimeout(Timeout(100))
//#creating-props-config
}
"creating actor with Props" in {
//#creating-props
import akka.actor.Props

View file

@ -0,0 +1,53 @@
package akka.docs.actor
//#imports1
import akka.actor.Actor
import akka.actor.Props
import akka.util.duration._
//#imports1
import org.scalatest.{ BeforeAndAfterAll, WordSpec }
import org.scalatest.matchers.MustMatchers
import akka.testkit._
class SchedulerDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) {
"schedule a one-off task" in {
//#schedule-one-off-message
//Schedules to send the "foo"-message to the testActor after 50ms
system.scheduler.scheduleOnce(50 milliseconds, testActor, "foo")
//#schedule-one-off-message
expectMsg(1 second, "foo")
//#schedule-one-off-thunk
//Schedules a function to be executed (send the current time) to the testActor after 50ms
system.scheduler.scheduleOnce(50 milliseconds) {
testActor ! System.currentTimeMillis
}
//#schedule-one-off-thunk
}
"schedule a recurring task" in {
//#schedule-recurring
val Tick = "tick"
val tickActor = system.actorOf(Props(new Actor {
def receive = {
case Tick //Do something
}
}))
//This will schedule to send the Tick-message
//to the tickActor after 0ms repeating every 50ms
val cancellable =
system.scheduler.schedule(0 milliseconds,
50 milliseconds,
tickActor,
Tick)
//This cancels further Ticks to be sent
cancellable.cancel()
//#schedule-recurring
system.stop(tickActor)
}
}

View file

@ -16,27 +16,35 @@ object DispatcherDocSpec {
val config = """
//#my-dispatcher-config
my-dispatcher {
type = Dispatcher # Dispatcher is the name of the event-based dispatcher
daemonic = off # Toggles whether the threads created by this dispatcher should be daemons or not
core-pool-size-min = 2 # minimum number of threads to cap factor-based core number to
core-pool-size-factor = 2.0 # No of core threads ... ceil(available processors * factor)
core-pool-size-max = 10 # maximum number of threads to cap factor-based number to
throughput = 100 # Throughput defines the number of messages that are processed in a batch before the
# thread is returned to the pool. Set to 1 for as fair as possible.
# Dispatcher is the name of the event-based dispatcher
type = Dispatcher
# Toggles whether the threads created by this dispatcher should be daemons or not
daemonic = off
# minimum number of threads to cap factor-based core number to
core-pool-size-min = 2
# No of core threads ... ceil(available processors * factor)
core-pool-size-factor = 2.0
# maximum number of threads to cap factor-based number to
core-pool-size-max = 10
# Throughput defines the number of messages that are processed in a batch before the
# thread is returned to the pool. Set to 1 for as fair as possible.
throughput = 100
}
//#my-dispatcher-config
//#my-bounded-config
my-dispatcher-bounded-queue {
type = Dispatcher
core-pool-size-factor = 8.0
max-pool-size-factor = 16.0
task-queue-size = 100 # Specifies the bounded capacity of the task queue
task-queue-type = "array" # Specifies which type of task queue will be used, can be "array" or "linked" (default)
# Specifies the bounded capacity of the task queue
task-queue-size = 100
# Specifies which type of task queue will be used, can be "array" or "linked" (default)
task-queue-type = "array"
throughput = 3
}
//#my-bounded-config
//#my-balancing-config
my-balancing-dispatcher {
type = BalancingDispatcher

View file

@ -0,0 +1,74 @@
package akka.docs.extension
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
//#imports
import akka.actor._
import java.util.concurrent.atomic.AtomicLong
//#imports
//#extension
class CountExtensionImpl extends Extension {
//Since this Extension is a shared instance
// per ActorSystem we need to be threadsafe
private val counter = new AtomicLong(0)
//This is the operation this Extension provides
def increment() = counter.incrementAndGet()
}
//#extension
//#extensionid
object CountExtension
extends ExtensionId[CountExtensionImpl]
with ExtensionIdProvider {
//The lookup method is required by ExtensionIdProvider,
// so we return ourselves here, this allows us
// to configure our extension to be loaded when
// the ActorSystem starts up
override def lookup = CountExtension
//This method will be called by Akka
// to instantiate our Extension
override def createExtension(system: ActorSystemImpl) = new CountExtensionImpl
}
//#extensionid
//#extension-usage-actor
import akka.actor.Actor
class MyActor extends Actor {
def receive = {
case someMessage
CountExtension(context.system).increment()
}
}
//#extension-usage-actor
//#extension-usage-actor-trait
import akka.actor.Actor
trait Counting { self: Actor
def increment() = CountExtension(context.system).increment()
}
class MyCounterActor extends Actor with Counting {
def receive = {
case someMessage increment()
}
}
//#extension-usage-actor-trait
class ExtensionDocSpec extends WordSpec with MustMatchers {
"demonstrate how to create an extension in Scala" in {
val system: ActorSystem = null
intercept[Exception] {
//#extension-usage
CountExtension(system).increment
//#extension-usage
}
}
}

View file

@ -6,7 +6,7 @@ Dispatchers (Scala)
.. sidebar:: Contents
.. contents:: :local:
The Dispatcher is an important piece that allows you to configure the right semantics and parameters for optimal performance, throughput and scalability. Different Actors have different needs.
Akka supports dispatchers for both event-driven lightweight threads, allowing creation of millions of threads on a single workstation, and thread-based Actors, where each dispatcher is bound to a dedicated OS thread.
@ -127,9 +127,9 @@ Work-sharing event-based
The ``BalancingDispatcher`` is a variation of the ``Dispatcher`` in which Actors of the same type can be set up to
share this dispatcher and during execution time the different actors will steal messages from other actors if they
have less messages to process.
have less messages to process.
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.
best described as "work donating" because the actor of which work is being stolen takes the initiative.
This can be a great way to improve throughput at the cost of a little higher latency.
.. includecode:: code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-balancing-config
@ -152,8 +152,9 @@ if not specified otherwise.
akka {
actor {
default-dispatcher {
task-queue-size = 1000 # If negative (or zero) then an unbounded mailbox is used (default)
# If positive then a bounded mailbox is used and the capacity is set to the number specified
# If negative (or zero) then an unbounded mailbox is used (default)
# If positive then a bounded mailbox is used and the capacity is set to the number specified
task-queue-size = 1000
}
}
}

View file

@ -0,0 +1,53 @@
.. _extending-akka:
Akka Extensions
===============
.. sidebar:: Contents
.. contents:: :local:
Building an Extension
---------------------
So let's create a sample extension that just lets us count the number of times something has happened.
First, we define what our ``Extension`` should do:
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
:include: imports,extension
Then we need to create an ``ExtensionId`` for our extension so we can grab ahold of it.
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
:include: imports,extensionid
Wicked! Now all we need to do is to actually use it:
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
:include: extension-usage
Or from inside of an Akka Actor:
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
:include: extension-usage-actor
You can also hide extension behind traits:
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
:include: extension-usage-actor-trait
That's all there is to it!
Loading from Configuration
--------------------------
To be able to load extensions from your Akka configuration you must add FQCNs of implementations of either ``ExtensionId`` or ``ExtensionIdProvider``
in the "akka.extensions" section of the config you provide to your ``ActorSystem``.
Applicability
-------------
The sky is the limit!
By the way, did you know that Akka's ``Typed Actors``, ``Serialization`` and other features are implemented as Akka Extensions?

View file

@ -198,7 +198,7 @@ Then there's a method that's called ``fold`` that takes a start-value, a sequenc
.. code-block:: scala
val futures = for(i <- 1 to 1000) yield Future(i * 2) // Create a sequence of Futures
val futureSum = Future.fold(0)(futures)(_ + _)
That's all it takes!
@ -244,7 +244,7 @@ In this example, if an ``ArithmeticException`` was thrown while the ``Actor`` pr
Timeouts
--------
Waiting forever for a ``Future`` to be completed can be dangerous. It could cause your program to block indefinitly or produce a memory leak. ``Future`` has support for a timeout already builtin with a default of 5 seconds (taken from :ref:`configuration`). A timeout is an instance of ``akka.actor.Timeout`` which contains an ``akka.util.Duration``. A ``Duration`` can be finite, which needs a length and unit type, or infinite. An infinite ``Timeout`` can be dangerous since it will never actually expire.
Waiting forever for a ``Future`` to be completed can be dangerous. It could cause your program to block indefinitly or produce a memory leak. ``Future`` has support for a timeout already builtin with a default of 5 seconds (taken from :ref:`configuration`). A timeout is an instance of ``akka.util.Timeout`` which contains an ``akka.util.Duration``. A ``Duration`` can be finite, which needs a length and unit type, or infinite. An infinite ``Timeout`` can be dangerous since it will never actually expire.
A different ``Timeout`` can be supplied either explicitly or implicitly when a ``Future`` is created. An implicit ``Timeout`` has the benefit of being usable by a for-comprehension as well as being picked up by any methods looking for an implicit ``Timeout``, while an explicit ``Timeout`` can be used in a more controlled manner.
@ -262,7 +262,7 @@ Implicit ``Timeout`` example:
.. code-block:: scala
import akka.actor.Timeout
import akka.util.Timeout
import akka.util.duration._
implicit val longTimeout = Timeout(1 minute)

View file

@ -9,13 +9,14 @@ Scala API
actors
typed-actors
logging
scheduler
futures
dataflow
agents
stm
transactors
fault-tolerance
dispatchers
routing
fsm
testing
extending-akka

View file

@ -21,7 +21,7 @@ For convenience you can mixin the ``log`` member into actors, instead of definin
.. code-block:: scala
class MyActor extends Actor with akka.actor.ActorLogging {
class MyActor extends Actor with akka.actor.ActorLogging {
The second parameter to the ``Logging`` is the source of this logging channel.
The source object is translated to a String according to the following rules:
@ -31,14 +31,14 @@ The source object is translated to a String according to the following rules:
* in case of a class an approximation of its simpleName
* and in all other cases the simpleName of its class
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
is enabled.
Event Handler
=============
Logging is performed asynchronously through an event bus. You can configure which event handlers that should
subscribe to the logging events. That is done using the 'event-handlers' element in the :ref:`configuration`.
Logging is performed asynchronously through an event bus. You can configure which event handlers that should
subscribe to the logging events. That is done using the 'event-handlers' element in the :ref:`configuration`.
Here you can also define the log level.
.. code-block:: ruby
@ -46,10 +46,11 @@ Here you can also define the log level.
akka {
# Event handlers to register at boot time (Logging$DefaultLogger logs to STDOUT)
event-handlers = ["akka.event.Logging$DefaultLogger"]
loglevel = "DEBUG" # Options: ERROR, WARNING, INFO, DEBUG
# Options: ERROR, WARNING, INFO, DEBUG
loglevel = "DEBUG"
}
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j-scala`
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j-scala`
event handler available in the 'akka-slf4j' module.
Example of creating a listener:
@ -63,7 +64,7 @@ Example of creating a listener:
SLF4J
=====
Akka provides an event handler for `SL4FJ <http://www.slf4j.org/>`_. This module is available in the 'akka-slf4j.jar'.
Akka provides an event handler for `SL4FJ <http://www.slf4j.org/>`_. This module is available in the 'akka-slf4j.jar'.
It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4J backend, we recommend `Logback <http://logback.qos.ch/>`_:
.. code-block:: scala
@ -71,10 +72,10 @@ It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4
lazy val logback = "ch.qos.logback" % "logback-classic" % "1.0.0" % "runtime"
You need to enable the Slf4jEventHandler in the 'event-handlers' element in
the :ref:`configuration`. Here you can also define the log level of the event bus.
You need to enable the Slf4jEventHandler in the 'event-handlers' element in
the :ref:`configuration`. Here you can also define the log level of the event bus.
More fine grained log levels can be defined in the configuration of the SLF4J backend
(e.g. logback.xml). The String representation of the source object that is used when
(e.g. logback.xml). The String representation of the source object that is used when
creating the ``LoggingAdapter`` correspond to the name of the SL4FJ logger.
.. code-block:: ruby
@ -91,9 +92,9 @@ Since the logging is done asynchronously the thread in which the logging was per
Mapped Diagnostic Context (MDC) with attribute name ``sourceThread``.
With Logback the thread name is available with ``%X{sourceThread}`` specifier within the pattern layout configuration::
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>%date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n</pattern>
</layout>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>%date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n</pattern>
</layout>
</appender>

View file

@ -0,0 +1,53 @@
.. _scheduler-scala:
###################
Scheduler (Scala)
###################
Sometimes the need for making things happen in the future arises, and where do you go look then?
Look no further than ``ActorSystem``! There you find the :meth:`scheduler` method that returns an instance
of akka.actor.Scheduler, this instance is unique per ActorSystem and is used internally for scheduling things
to happen at specific points in time. Please note that the scheduled tasks are executed by the default
``MessageDispatcher`` of the ``ActorSystem``.
You can schedule sending of messages to actors and execution of tasks (functions or Runnable).
You will get a ``Cancellable`` back that you can call :meth:`cancel` on to cancel the execution of the
scheduled operation.
Some examples
-------------
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
:include: imports1,schedule-one-off-message
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
:include: schedule-one-off-thunk
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
:include: schedule-recurring
From ``akka.actor.ActorSystem``
-------------------------------
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala
:include: scheduler
The Scheduler interface
-----------------------
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/Scheduler.scala
:include: scheduler
The Cancellable interface
-------------------------
This allows you to ``cancel`` something that has been scheduled for execution.
.. warning::
This does not abort the execution of the task, if it had already been started.
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/Scheduler.scala
:include: cancellable

View file

@ -0,0 +1,6 @@
.. _transactors-scala:
Transactors (Scala)
===================
The Akka Transactors module has not been migrated to Akka 2.0-SNAPSHOT yet.

View file

@ -165,4 +165,4 @@ Here's an example on how you can use traits to mix in behavior in your Typed Act
.. includecode:: code/TypedActorDocSpec.scala#typed-actor-supercharge
.. includecode:: code/TypedActorDocSpec.scala#typed-actor-supercharge-usage
.. includecode:: code/TypedActorDocSpec.scala#typed-actor-supercharge-usage