The idea is to filter the sources, replacing @<var>@ occurrences with the mapping for <var> (which is currently hard-coded). @@ -> @. In order to make this work, I had to move the doc sources one directory down (into akka-docs/rst) so that the filtered result could be in a sibling directory so that relative links (to _sphinx plugins or real code) would continue to work. While I was at it I also changed it so that WARNINGs and ERRORs are not swallowed into the debug dump anymore but printed at [warn] level (minimum). One piece of fallout is that the (online) html build is now run after the normal one, not in parallel.
This commit is contained in:
parent
c0f60da8cc
commit
9bc01ae265
266 changed files with 270 additions and 182 deletions
BIN
akka-docs/rst/modules/camel-async-interact.png
Normal file
BIN
akka-docs/rst/modules/camel-async-interact.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
akka-docs/rst/modules/camel-async-sequence.png
Normal file
BIN
akka-docs/rst/modules/camel-async-sequence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
BIN
akka-docs/rst/modules/camel-custom-route.png
Normal file
BIN
akka-docs/rst/modules/camel-custom-route.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
akka-docs/rst/modules/camel-pubsub.png
Normal file
BIN
akka-docs/rst/modules/camel-pubsub.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
akka-docs/rst/modules/camel-pubsub2.png
Normal file
BIN
akka-docs/rst/modules/camel-pubsub2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
13
akka-docs/rst/modules/camel.rst
Normal file
13
akka-docs/rst/modules/camel.rst
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
.. _camel-module:
|
||||
|
||||
#######
|
||||
Camel
|
||||
#######
|
||||
|
||||
.. note::
|
||||
The Akka Camel module has not been migrated to Akka 2.1-SNAPSHOT yet.
|
||||
|
||||
It might not make it into Akka 2.0 final but will then hopefully be
|
||||
re-introduce in an upcoming release. It might also be backported to
|
||||
2.0 final.
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package docs.actor.mailbox
|
||||
|
||||
import language.postfixOps
|
||||
|
||||
//#imports
|
||||
import akka.actor.Props
|
||||
|
||||
//#imports
|
||||
|
||||
import org.scalatest.{ BeforeAndAfterAll, WordSpec }
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
import akka.testkit.AkkaSpec
|
||||
import akka.actor.{ Actor, ExtendedActorSystem }
|
||||
|
||||
class MyActor extends Actor {
|
||||
def receive = {
|
||||
case x ⇒
|
||||
}
|
||||
}
|
||||
|
||||
object DurableMailboxDocSpec {
|
||||
val config = """
|
||||
//#dispatcher-config
|
||||
my-dispatcher {
|
||||
mailbox-type = akka.actor.mailbox.filebased.FileBasedMailboxType
|
||||
}
|
||||
//#dispatcher-config
|
||||
"""
|
||||
}
|
||||
|
||||
class DurableMailboxDocSpec extends AkkaSpec(DurableMailboxDocSpec.config) {
|
||||
|
||||
"configuration of dispatcher with durable mailbox" in {
|
||||
//#dispatcher-config-use
|
||||
val myActor = system.actorOf(Props[MyActor].
|
||||
withDispatcher("my-dispatcher"), name = "myactor")
|
||||
//#dispatcher-config-use
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//#custom-mailbox
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.ActorContext
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.ActorSystem
|
||||
import akka.dispatch.Envelope
|
||||
import akka.dispatch.MailboxType
|
||||
import akka.dispatch.MessageQueue
|
||||
import akka.actor.mailbox.DurableMessageQueue
|
||||
import akka.actor.mailbox.DurableMessageSerialization
|
||||
import akka.pattern.CircuitBreaker
|
||||
import scala.concurrent.util.duration._
|
||||
|
||||
class MyMailboxType(systemSettings: ActorSystem.Settings, config: Config)
|
||||
extends MailboxType {
|
||||
|
||||
override def create(owner: Option[ActorRef], system: Option[ActorSystem]): MessageQueue = (owner zip system) headOption match {
|
||||
case Some((o, s: ExtendedActorSystem)) ⇒ new MyMessageQueue(o, s)
|
||||
case _ ⇒ throw new IllegalArgumentException("requires an owner (i.e. does not work with BalancingDispatcher)")
|
||||
}
|
||||
}
|
||||
|
||||
class MyMessageQueue(_owner: ActorRef, _system: ExtendedActorSystem)
|
||||
extends DurableMessageQueue(_owner, _system) with DurableMessageSerialization {
|
||||
|
||||
val storage = new QueueStorage
|
||||
// A real-world implmentation would use configuration to set the last
|
||||
// three parameters below
|
||||
val breaker = CircuitBreaker(system.scheduler, 5, 30.seconds, 1.minute)
|
||||
|
||||
def enqueue(receiver: ActorRef, envelope: Envelope): Unit = breaker.withSyncCircuitBreaker {
|
||||
val data: Array[Byte] = serialize(envelope)
|
||||
storage.push(data)
|
||||
}
|
||||
|
||||
def dequeue(): Envelope = breaker.withSyncCircuitBreaker {
|
||||
val data: Option[Array[Byte]] = storage.pull()
|
||||
data.map(deserialize).orNull
|
||||
}
|
||||
|
||||
def hasMessages: Boolean = breaker.withSyncCircuitBreaker { !storage.isEmpty }
|
||||
|
||||
def numberOfMessages: Int = breaker.withSyncCircuitBreaker { storage.size }
|
||||
|
||||
/**
|
||||
* Called when the mailbox is disposed.
|
||||
* An ordinary mailbox would send remaining messages to deadLetters,
|
||||
* but the purpose of a durable mailbox is to continue
|
||||
* with the same message queue when the actor is started again.
|
||||
*/
|
||||
def cleanUp(owner: ActorRef, deadLetters: MessageQueue): Unit = ()
|
||||
|
||||
}
|
||||
//#custom-mailbox
|
||||
|
||||
// dummy
|
||||
class QueueStorage {
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
val queue = new ConcurrentLinkedQueue[Array[Byte]]
|
||||
def push(data: Array[Byte]): Unit = queue.offer(data)
|
||||
def pull(): Option[Array[Byte]] = Option(queue.poll())
|
||||
def isEmpty: Boolean = queue.isEmpty
|
||||
def size: Int = queue.size
|
||||
}
|
||||
|
||||
//#custom-mailbox-test
|
||||
import akka.actor.mailbox.DurableMailboxSpec
|
||||
|
||||
object MyMailboxSpec {
|
||||
val config = """
|
||||
MyStorage-dispatcher {
|
||||
mailbox-type = docs.actor.mailbox.MyMailboxType
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
class MyMailboxSpec extends DurableMailboxSpec("MyStorage", MyMailboxSpec.config) {
|
||||
override def atStartup() {
|
||||
}
|
||||
|
||||
override def atTermination() {
|
||||
}
|
||||
|
||||
"MyMailbox" must {
|
||||
"deliver a message" in {
|
||||
val actor = createMailboxTestActor()
|
||||
implicit val sender = testActor
|
||||
actor ! "hello"
|
||||
expectMsg("hello")
|
||||
}
|
||||
|
||||
// add more tests
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package docs.actor.mailbox
|
||||
|
||||
import org.scalatest.junit.JUnitSuite
|
||||
|
||||
class DurableMailboxDocTest extends DurableMailboxDocTestBase with JUnitSuite
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package docs.actor.mailbox;
|
||||
|
||||
//#imports
|
||||
import akka.actor.Props;
|
||||
import akka.actor.ActorRef;
|
||||
|
||||
//#imports
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import akka.testkit.AkkaSpec;
|
||||
import com.typesafe.config.ConfigFactory;
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.actor.UntypedActor;
|
||||
|
||||
public class DurableMailboxDocTestBase {
|
||||
|
||||
ActorSystem system;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
system = ActorSystem.create("MySystem",
|
||||
ConfigFactory.parseString(DurableMailboxDocSpec.config()).withFallback(AkkaSpec.testConf()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
system.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configDefinedDispatcher() {
|
||||
//#dispatcher-config-use
|
||||
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class).
|
||||
withDispatcher("my-dispatcher"), "myactor");
|
||||
//#dispatcher-config-use
|
||||
myActor.tell("test", null);
|
||||
}
|
||||
|
||||
public static class MyUntypedActor extends UntypedActor {
|
||||
public void onReceive(Object message) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
104
akka-docs/rst/modules/durable-mailbox.rst
Normal file
104
akka-docs/rst/modules/durable-mailbox.rst
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
|
||||
.. _durable-mailboxes:
|
||||
|
||||
###################
|
||||
Durable Mailboxes
|
||||
###################
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
A durable mailbox is a mailbox which stores the messages on durable storage.
|
||||
What this means in practice is that if there are pending messages in the actor's
|
||||
mailbox when the node of the actor resides on crashes, then when you restart the
|
||||
node, the actor will be able to continue processing as if nothing had happened;
|
||||
with all pending messages still in its mailbox.
|
||||
|
||||
You configure durable mailboxes through the dispatcher. The actor is oblivious
|
||||
to which type of mailbox it is using.
|
||||
|
||||
This gives you an excellent way of creating bulkheads in your application, where
|
||||
groups of actors sharing the same dispatcher also share the same backing
|
||||
storage. Read more about that in the :ref:`dispatchers-scala` documentation.
|
||||
|
||||
One basic file based durable mailbox is provided by Akka out-of-the-box.
|
||||
Other implementations can easily be added. Some are available as separate community
|
||||
Open Source projects, such as:
|
||||
|
||||
* `AMQP Durable Mailbox <https://github.com/drexin/akka-amqp-mailbox>`_
|
||||
|
||||
|
||||
A durable mailbox is like any other mailbox not likely to be transactional. It's possible
|
||||
if the actor crashes after receiving a message, but before completing processing of
|
||||
it, that the message could be lost.
|
||||
|
||||
.. warning::
|
||||
|
||||
A durable mailbox typically doesn't work with blocking message send, i.e. the message
|
||||
send operations that are relying on futures; ``?`` or ``ask``. If the node
|
||||
has crashed and then restarted, the thread that was blocked waiting for the
|
||||
reply is gone and there is no way we can deliver the message.
|
||||
|
||||
|
||||
File-based durable mailbox
|
||||
==========================
|
||||
|
||||
This mailbox is backed by a journaling transaction log on the local file
|
||||
system. It is the simplest to use since it does not require an extra
|
||||
infrastructure piece to administer, but it is usually sufficient and just what
|
||||
you need.
|
||||
|
||||
In the configuration of the dispatcher you specify the fully qualified class name
|
||||
of the mailbox:
|
||||
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: dispatcher-config
|
||||
|
||||
Here is an example of how to create an actor with a durable dispatcher, in Scala:
|
||||
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: imports,dispatcher-config-use
|
||||
|
||||
Corresponding example in Java:
|
||||
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocTestBase.java
|
||||
:include: imports,dispatcher-config-use
|
||||
|
||||
You can also configure and tune the file-based durable mailbox. This is done in
|
||||
the ``akka.actor.mailbox.file-based`` section in the :ref:`configuration`.
|
||||
|
||||
.. literalinclude:: ../../../akka-durable-mailboxes/akka-file-mailbox/src/main/resources/reference.conf
|
||||
:language: none
|
||||
|
||||
How to implement a durable mailbox
|
||||
==================================
|
||||
|
||||
Here is an example of how to implement a custom durable mailbox. Essentially it consists of
|
||||
a configurator (MailboxType) and a queue implementation (DurableMessageQueue).
|
||||
|
||||
The envelope contains the message sent to the actor, and information about sender. It is the
|
||||
envelope that needs to be stored. As a help utility you can mixin DurableMessageSerialization
|
||||
to serialize and deserialize the envelope using the ordinary :ref:`serialization-scala`
|
||||
mechanism. This optional and you may store the envelope data in any way you like. Durable
|
||||
mailboxes are an excellent fit for usage of circuit breakers. These are described in the
|
||||
:ref:`circuit-breaker` documentation.
|
||||
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: custom-mailbox
|
||||
|
||||
To facilitate testing of a durable mailbox you may use ``DurableMailboxSpec`` as base class.
|
||||
It implements a few basic tests and helps you setup the a fixture. More tests can be
|
||||
added in concrete subclass like this:
|
||||
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: custom-mailbox-test
|
||||
|
||||
You find DurableMailboxDocSpec in ``akka-mailboxes-common-test-2.1-SNAPSHOT.jar``.
|
||||
Add this dependency::
|
||||
|
||||
"com.typesafe.akka" % "akka-mailboxes-common-test" % "2.1-SNAPSHOT"
|
||||
|
||||
For more inspiration you can look at the old implementations based on Redis, MongoDB, Beanstalk,
|
||||
and ZooKeeper, which can be found in Akka git repository tag
|
||||
`v2.0.1 <https://github.com/akka/akka/tree/v2.0.1/akka-durable-mailboxes>`_.
|
||||
38
akka-docs/rst/modules/http.rst
Normal file
38
akka-docs/rst/modules/http.rst
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
.. _http-module:
|
||||
|
||||
HTTP
|
||||
####
|
||||
|
||||
Play2 Mini
|
||||
==========
|
||||
|
||||
The Akka team recommends the `Play2 Mini <https://github.com/typesafehub/play2-mini>`_ framework when building RESTful
|
||||
service applications that integrates with Akka. It provides a REST API on top of `Play2 <https://github.com/playframework/Play20/>`_.
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
Easiest way to get started with `Play2 Mini <https://github.com/typesafehub/play2-mini>`_ is to use the
|
||||
G8 project templates, as described in the `Play2 Mini Documentation <https://github.com/typesafehub/play2-mini>`_.
|
||||
|
||||
If you already have an Akka project and want to add Play2 Mini, you must first add the following to
|
||||
your ``libraryDependencies``::
|
||||
|
||||
libraryDependencies += "com.typesafe" %% "play-mini" % "<version-number>"
|
||||
|
||||
In case you need to start Play2 Mini programatically you can use::
|
||||
|
||||
play.core.server.NettyServer.main(Array())
|
||||
|
||||
|
||||
Akka Mist
|
||||
=========
|
||||
|
||||
If you are using Akka Mist (Akka's old HTTP/REST module) with Akka 1.x and wish to upgrade to 2.x
|
||||
there is now a port of Akka Mist to Akka 2.x. You can find it `here <https://github.com/thenewmotion/akka-http>`_.
|
||||
|
||||
Other Alternatives
|
||||
==================
|
||||
|
||||
There are a bunch of other alternatives for using Akka with HTTP/REST. You can find some of them
|
||||
among the `Community Projects <http://akka.io/community>`_.
|
||||
9
akka-docs/rst/modules/index.rst
Normal file
9
akka-docs/rst/modules/index.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Modules
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
durable-mailbox
|
||||
http
|
||||
camel
|
||||
Loading…
Add table
Add a link
Reference in a new issue