diff --git a/akka-docs/dev/code/akka/docs/extension/ExtensionDocSpec.scala b/akka-docs/dev/code/akka/docs/extension/ExtensionDocSpec.scala new file mode 100644 index 0000000000..58f9639559 --- /dev/null +++ b/akka-docs/dev/code/akka/docs/extension/ExtensionDocSpec.scala @@ -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 + } + } + +} diff --git a/akka-docs/dev/extending-akka.rst b/akka-docs/dev/extending-akka.rst new file mode 100644 index 0000000000..8af8e43b7f --- /dev/null +++ b/akka-docs/dev/extending-akka.rst @@ -0,0 +1,71 @@ +.. _extending-akka: + +Akka Extensions +=============== + +.. sidebar:: Contents + + .. contents:: :local: + +If you want to add features to Akka, there is a very elegant, but powerful mechanism for doing so. +It's called Akka Extensions and is comprised of 2 basic components: an ``Extension`` and an ``ExtensionId``. + +Extensions will only be loaded once per ``ActorSystem``, which will be managed by Akka. +You can choose to have your Extension loaded on-demand or at ``ActorSystem`` creation time through the Akka configuration. +Details on how to make that happens are below, in the "Loading from Configuration" section. + +.. warning:: + + Since an extension is a way to hook into Akka itself, the implementor of the extension needs to + ensure the thread safety of his/her extension. + +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``. + +Building an Extension (Java) +---------------------------- + +So let's create a sample extension that just lets us count the number of times something has happened. + +FIXME + +Building an Extension (Scala) +----------------------------- + +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! + +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? \ No newline at end of file diff --git a/akka-docs/dev/index.rst b/akka-docs/dev/index.rst index 17fcb2427c..8ea96ee473 100644 --- a/akka-docs/dev/index.rst +++ b/akka-docs/dev/index.rst @@ -5,6 +5,7 @@ Information for Developers :maxdepth: 2 building-akka + extending-akka multi-jvm-testing developer-guidelines documentation diff --git a/akka-docs/dev/team.rst b/akka-docs/dev/team.rst index 36e0cd1339..8c70e016d2 100644 --- a/akka-docs/dev/team.rst +++ b/akka-docs/dev/team.rst @@ -1,7 +1,9 @@ + .. _team: -Team -===== +###### + Team +###### =================== ========================== ==================================== Name Role Email