From 1c830d224e0b56496553afb25b088061a1ad20cc Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 12 May 2017 06:54:46 -0700 Subject: [PATCH] Remove docs for the (deprecated) contrib subproject (#22926) --- akka-contrib/docs/ReliableProxy.png | Bin 32304 -> 0 bytes akka-contrib/docs/aggregator.rst | 109 ----------------- akka-contrib/docs/circuitbreaker.rst | 59 ---------- akka-contrib/docs/index.rst | 82 ------------- akka-contrib/docs/jul.rst | 17 --- akka-contrib/docs/peek-mailbox.rst | 59 ---------- akka-contrib/docs/receive-pipeline.rst | 142 ---------------------- akka-contrib/docs/reliable-proxy.rst | 155 ------------------------- akka-contrib/docs/throttle.rst | 70 ----------- akka-contrib/docs/throttler.png | Bin 4036 -> 0 bytes 10 files changed, 693 deletions(-) delete mode 100644 akka-contrib/docs/ReliableProxy.png delete mode 100644 akka-contrib/docs/aggregator.rst delete mode 100644 akka-contrib/docs/circuitbreaker.rst delete mode 100644 akka-contrib/docs/index.rst delete mode 100644 akka-contrib/docs/jul.rst delete mode 100644 akka-contrib/docs/peek-mailbox.rst delete mode 100644 akka-contrib/docs/receive-pipeline.rst delete mode 100644 akka-contrib/docs/reliable-proxy.rst delete mode 100644 akka-contrib/docs/throttle.rst delete mode 100644 akka-contrib/docs/throttler.png diff --git a/akka-contrib/docs/ReliableProxy.png b/akka-contrib/docs/ReliableProxy.png deleted file mode 100644 index 81575fd9f24d28dee5f4fe62fb157a31b03ee7bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32304 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 diff --git a/akka-contrib/docs/aggregator.rst b/akka-contrib/docs/aggregator.rst deleted file mode 100644 index 41ee19c35b..0000000000 --- a/akka-contrib/docs/aggregator.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. _aggregator: - -Aggregator Pattern -================== - -.. warning:: - **Deprecation warning** - ``Aggregator`` has been deprecated and is scheduled for removal - in the next major version. Feel free to copy the source into your project or create - a separate library outside of Akka. - -The aggregator pattern supports writing actors that aggregate data from multiple -other actors and updates its state based on those responses. It is even harder to -optionally aggregate more data based on the runtime state of the actor or take -certain actions (sending another message and get another response) based on two or -more previous responses. - -A common thought is to use the ask pattern to request information from other -actors. However, ask creates another actor specifically for the ask. We cannot -use a callback from the future to update the state as the thread executing the -callback is not defined. This will likely close-over the current actor. - -The aggregator pattern solves such scenarios. It makes sure we're -acting from the same actor in the scope of the actor receive. - -Introduction ------------- -The aggregator pattern allows match patterns to be dynamically added to and removed -from an actor from inside the message handling logic. All match patterns are called -from the receive loop and run in the thread handling the incoming message. These -dynamically added patterns and logic can safely read and/or modify this actor's -mutable state without risking integrity or concurrency issues. - -Usage ------ -To use the aggregator pattern, you need to extend the :class:`Aggregator` trait. -The trait takes care of :class:`receive` and actors extending this trait should -not override :class:`receive`. The trait provides the :class:`expect`, -:class:`expectOnce`, and :class:`unexpect` calls. The :class:`expect` and -:class:`expectOnce` calls return a handle that can be used for later de-registration -by passing the handle to :class:`unexpect`. - -:class:`expect` is often used for standing matches such as catching error messages or timeouts. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#expect-timeout - -:class:`expectOnce` is used for matching the initial message as well as other requested messages - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#initial-expect -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#expect-balance - -:class:`unexpect` can be used for expecting multiple responses until a timeout or when the logic -dictates such an :class:`expect` no longer applies. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#unexpect-sample - -As the name eludes, :class:`expect` keeps the partial function matching any -received messages until :class:`unexpect` is called or the actor terminates, -whichever comes first. On the other hand, :class:`expectOnce` removes the partial -function once a match has been established. - -It is a common pattern to register the initial expectOnce from the construction -of the actor to accept the initial message. Once that message is received, the -actor starts doing all aggregations and sends the response back to the original -requester. The aggregator should terminate after the response is sent (or timed -out). A different original request should use a different actor instance. - -As you can see, aggregator actors are generally stateful, short lived actors. - -Sample Use Case - AccountBalanceRetriever ------------------------------------------ -This example below shows a typical and intended use of the aggregator pattern. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#demo-code - -Sample Use Case - Multiple Response Aggregation and Chaining ------------------------------------------------------------- -A shorter example showing aggregating responses and chaining further requests. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/AggregatorSpec.scala#chain-sample - -Pitfalls --------- -* The current implementation does not match the sender of the message. This is - designed to work with :class:`ActorSelection` as well as :class:`ActorRef`. - Without the sender(), there is a chance a received message can be matched by - more than one partial function. The partial function that was registered via - :class:`expect` or :class:`expectOnce` first (chronologically) and is not yet - de-registered by :class:`unexpect` takes precedence in this case. Developers - should make sure the messages can be uniquely matched or the wrong logic can - be executed for a certain message. - -* The :class:`sender` referenced in any :class:`expect` or :class:`expectOnce` - logic refers to the sender() of that particular message and not the sender() of - the original message. The original sender() still needs to be saved so a final - response can be sent back. - -* :class:`context.become` is not supported when extending the :class:`Aggregator` - trait. - -* We strongly recommend against overriding :class:`receive`. If your use case - really dictates, you may do so with extreme caution. Always provide a pattern - match handling aggregator messages among your :class:`receive` pattern matches, - as follows:: - - case msg if handleMessage(msg) ⇒ // noop - // side effects of handleMessage does the actual match - - -Sorry, there is not yet a Java implementation of the aggregator pattern available. \ No newline at end of file diff --git a/akka-contrib/docs/circuitbreaker.rst b/akka-contrib/docs/circuitbreaker.rst deleted file mode 100644 index 1f1f93bdce..0000000000 --- a/akka-contrib/docs/circuitbreaker.rst +++ /dev/null @@ -1,59 +0,0 @@ -.. _circuit-breaker-proxy: - -Circuit-Breaker Actor -===================== - -This is an alternative implementation of the :ref:`Akka Circuit Breaker Pattern `. -The main difference is that it is intended to be used only for request-reply interactions with an actor using the Circuit-Breaker as a proxy of the target one -in order to provide the same failfast functionalities and a protocol similar to the circuit-breaker implementation in Akka. - -.. warning:: - **Deprecation warning** - ``CircuitBreakerProxy`` has been deprecated and is scheduled for removal - in the next major version. ``akka.pattern.CircuitBreaker`` with explicit ``ask`` requests can be used instead. - -Usage ------ - -Let's assume we have an actor wrapping a back-end service and able to respond to ``Request`` calls with a ``Response`` object -containing an ``Either[String, String]`` to map successful and failed responses. The service is also potentially slowing down -because of the workload. - -A simple implementation can be given by this class - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/circuitbreaker/sample/CircuitBreaker.scala#simple-service - - -If we want to interface with this service using the Circuit Breaker we can use two approaches: - -Using a non-conversational approach: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/circuitbreaker/sample/CircuitBreaker.scala#basic-sample - -Using the ``ask`` pattern, in this case it is useful to be able to map circuit open failures to the same type of failures -returned by the service (a ``Left[String]`` in our case): - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/circuitbreaker/sample/CircuitBreaker.scala#ask-sample - -If it is not possible to define a specific error response, you can map the Open Circuit notification to a failure. -That also means that your ``CircuitBreakerActor`` will be useful to protect you from time out for extra workload or -temporary failures in the target actor. -You can decide to do that in two ways: - -The first is to use the ``askWithCircuitBreaker`` method on the ``ActorRef`` or ``ActorSelection`` instance pointing to -your circuit breaker proxy (enabled by importing ``import akka.contrib.circuitbreaker.Implicits.askWithCircuitBreaker``) - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/circuitbreaker/sample/CircuitBreaker.scala#ask-with-circuit-breaker-sample - -The second is to map the future response of your ``ask`` pattern application with the ``failForOpenCircuit`` -enabled by importing ``import akka.contrib.circuitbreaker.Implicits.futureExtensions`` - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/circuitbreaker/sample/CircuitBreaker.scala#ask-with-failure-sample - -Direct Communication With The Target Actor -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To send messages to the `target` actor without expecting any response you can wrap your message in a ``TellOnly`` or a ``Passthrough`` -envelope. The difference between the two is that ``TellOnly`` will forward the message only when in closed mode and -``Passthrough`` will do it in any state. You can for example use the ``Passthrough`` envelope to wrap a ``PoisonPill`` -message to terminate the target actor. That will cause the circuit breaker proxy to be terminated too - diff --git a/akka-contrib/docs/index.rst b/akka-contrib/docs/index.rst deleted file mode 100644 index 0789e90136..0000000000 --- a/akka-contrib/docs/index.rst +++ /dev/null @@ -1,82 +0,0 @@ -.. _akka-contrib: - -External Contributions -====================== - -.. warning:: - **Deprecation warning** - ``akka-contrib`` has been deprecated and is scheduled for removal - in the next major version. The reason is to reduce the amount of things to maintain in - the core Akka projects. Contributions to the core of Akka or its satellite projects - are welcome. Contributions that don't fit into existing modules can be hosted in - new Akka Github repositories in the ``akka`` Github organization or outside of it - depending on what kind of library it is. Please ask. - -This subproject provides a home to modules contributed by external developers -which may or may not move into the officially supported code base over time. -The conditions under which this transition can occur include: - -* there must be enough interest in the module to warrant inclusion in the - standard distribution, -* the module must be actively maintained and -* code quality must be good enough to allow efficient maintenance by the Akka - core development team - -If a contributions turns out to not “take off” it may be removed again at a -later time. - -Caveat Emptor -------------- - -A module in this subproject doesn't have to obey the rule of staying binary -compatible between minor releases. Breaking API changes may be introduced in -minor releases without notice as we refine and simplify based on your feedback. -A module may be dropped in any release without prior deprecation. The Lightbend -subscription does not cover support for these modules. - -The Current List of Modules ---------------------------- - -.. toctree:: - - reliable-proxy - throttle - jul - peek-mailbox - aggregator - receive-pipeline - circuitbreaker - -Suggested Way of Using these Contributions ------------------------------------------- - -Since the Akka team does not restrict updates to this subproject even during -otherwise binary compatible releases, and modules may be removed without -deprecation, it is suggested to copy the source files into your own code base, -changing the package name. This way you can choose when to update or which -fixes to include (to keep binary compatibility if needed) and later releases of -Akka do not potentially break your application. - -Suggested Format of Contributions ---------------------------------- - -Each contribution should be a self-contained unit, consisting of one source -file or one exclusively used package, without dependencies to other modules in -this subproject; it may depend on everything else in the Akka distribution, -though. This ensures that contributions may be moved into the standard -distribution individually. The module shall be within a subpackage of -``akka.contrib``. - -Each module must be accompanied by a test suite which verifies that the -provided features work, possibly complemented by integration and unit tests. -The tests should follow the :ref:`developer_guidelines` and go into the -``src/test/scala`` or ``src/test/java`` directories (with package name matching -the module which is being tested). As an example, if the module were called -``akka.contrib.pattern.ReliableProxy``, then the test suite should be called -``akka.contrib.pattern.ReliableProxySpec``. - -Each module must also have proper documentation in `reStructured Text`_ format. -The documentation should be a single ``.rst`` file in the -``akka-contrib/docs`` directory, including a link from ``index.rst`` (this file). - -.. _reStructured Text: http://sphinx.pocoo.org/rest.html - diff --git a/akka-contrib/docs/jul.rst b/akka-contrib/docs/jul.rst deleted file mode 100644 index 2122ed3bdc..0000000000 --- a/akka-contrib/docs/jul.rst +++ /dev/null @@ -1,17 +0,0 @@ -Java Logging (JUL) -================== - -This extension module provides a logging backend which uses the `java.util.logging` (j.u.l) -API to do the endpoint logging for `akka.event.Logging`. - -Provided with this module is an implementation of `akka.event.LoggingAdapter` which is independent of any `ActorSystem` being in place. This means that j.u.l can be used as the backend, via the Akka Logging API, for both Actor and non-Actor codebases. - -To enable j.u.l as the `akka.event.Logging` backend, use the following Akka config: - - loggers = ["akka.contrib.jul.JavaLogger"] - -To access the `akka.event.Logging` API from non-Actor code, mix in `akka.contrib.jul.JavaLogging`. - -This module is preferred over SLF4J with its JDK14 backend, due to integration issues resulting in the incorrect handling of `threadId`, `className` and `methodName`. - -This extension module was contributed by Sam Halliday. diff --git a/akka-contrib/docs/peek-mailbox.rst b/akka-contrib/docs/peek-mailbox.rst deleted file mode 100644 index 7aceb88826..0000000000 --- a/akka-contrib/docs/peek-mailbox.rst +++ /dev/null @@ -1,59 +0,0 @@ -.. _mailbox-acking: - -Mailbox with Explicit Acknowledgement -===================================== - -.. warning:: - **Deprecation warning** - ``PeekMailbox`` has been deprecated and is scheduled for removal - in the next major version. Use an explicit supervisor or proxy actor instead. - -When an Akka actor is processing a message and an exception occurs, the normal -behavior is for the actor to drop that message, and then continue with the next -message after it has been restarted. This is in some cases not the desired -solution, e.g. when using failure and supervision to manage a connection to an -unreliable resource; the actor could after the restart go into a buffering mode -(i.e. change its behavior) and retry the real processing later, when the -unreliable resource is back online. - -One way to do this is by sending all messages through the supervisor and -buffering them there, acknowledging successful processing in the child; another -way is to build an explicit acknowledgement mechanism into the mailbox. The -idea with the latter is that a message is reprocessed in case of failure until -the mailbox is told that processing was successful. - -The pattern is implemented `here -<@github@/akka-contrib/src/main/scala/akka/contrib/mailbox/PeekMailbox.scala>`_. -A demonstration of how to use it (although for brevity not a perfect example) -is the following: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/mailbox/PeekMailboxSpec.scala - :include: demo - :exclude: business-logic-elided - -Running this application (try it in the Akka sources by saying -``sbt akka-contrib/test:run``) may produce the following output (note the -processing of “World” on lines 2 and 16): - -.. code-block:: none - - Hello - World - [ERROR] [12/17/2012 16:28:36.581] [MySystem-peek-dispatcher-5] [akka://MySystem/user/myActor] DONTWANNA - java.lang.Exception: DONTWANNA - at akka.contrib.mailbox.MyActor.doStuff(PeekMailbox.scala:105) - at akka.contrib.mailbox.MyActor$$anonfun$receive$1.applyOrElse(PeekMailbox.scala:98) - at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425) - at akka.actor.ActorCell.invoke(ActorCell.scala:386) - at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230) - at akka.dispatch.Mailbox.run(Mailbox.scala:212) - at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:502) - at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262) - at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975) - at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478) - at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104) - World - -Normally one would want to make processing idempotent (i.e. it does not matter -if a message is processed twice) or ``context.become`` a different behavior -upon restart; the above example included the ``println(msg)`` call just to -demonstrate the re-processing. diff --git a/akka-contrib/docs/receive-pipeline.rst b/akka-contrib/docs/receive-pipeline.rst deleted file mode 100644 index 90b222f410..0000000000 --- a/akka-contrib/docs/receive-pipeline.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. _receive-pipeline: - -Receive Pipeline Pattern -======================== - -.. warning:: - **Deprecation warning** - ``ReceivePipeline`` has been deprecated and is scheduled for removal - in the next major version. Feel free to copy the source into your project or create - a separate library outside of Akka. - -The Receive Pipeline Pattern lets you define general interceptors for your messages -and plug an arbitrary amount of them into your Actors. -It's useful for defining cross aspects to be applied to all or many of your Actors. - -Some Possible Use Cases ------------------------ -* Measure the time spent for processing the messages -* Audit messages with an associated author -* Log all important messages -* Secure restricted messages -* Text internationalization - -Interceptors ------------- -Multiple interceptors can be added to actors that mixin the :class:`ReceivePipeline` trait. -These interceptors internally define layers of decorators around the actor's behavior. The first interceptor -defines an outer decorator which delegates to a decorator corresponding to the second interceptor and so on, -until the last interceptor which defines a decorator for the actor's :class:`Receive`. - -The first or outermost interceptor receives messages sent to the actor. - -For each message received by an interceptor, the interceptor will typically perform some -processing based on the message and decide whether -or not to pass the received message (or some other message) to the next interceptor. - -An :class:`Interceptor` is a type alias for -:class:`PartialFunction[Any, Delegation]`. The :class:`Any` input is the message -it receives from the previous interceptor (or, in the case of the first interceptor, -the message that was sent to the actor). -The :class:`Delegation` return type is used to control what (if any) -message is passed on to the next interceptor. - -A simple example ----------------- -To pass a transformed message to the actor -(or next inner interceptor) an interceptor can return :class:`Inner(newMsg)` where :class:`newMsg` is the transformed message. - -The following interceptor shows this. It intercepts :class:`Int` messages, -adds one to them and passes on the incremented value to the next interceptor. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#interceptor-sample1 - -Building the Pipeline ---------------------- -To give your Actor the ability to pipeline received messages in this way, you'll need to mixin with the -:class:`ReceivePipeline` trait. It has two methods for controlling the pipeline, :class:`pipelineOuter` -and :class:`pipelineInner`, both receiving an :class:`Interceptor`. -The first one adds the interceptor at the -beginning of the pipeline and the second one adds it at the end, just before the current -Actor's behavior. - -In this example we mixin our Actor with the :class:`ReceivePipeline` trait and -we add :class:`Increment` and :class:`Double` interceptors with :class:`pipelineInner`. -They will be applied in this very order. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#in-actor - -If we add :class:`Double` with :class:`pipelineOuter` it will be applied before :class:`Increment` so the output is 11 - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#in-actor-outer - -Interceptors Mixin ------------------- -Defining all the pipeline inside the Actor implementation is good for showing up the pattern, but it isn't -very practical. The real flexibility of this pattern comes when you define every interceptor in its own -trait and then you mixin any of them into your Actors. - -Let's see it in an example. We have the following model: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#mixin-model - -and these two interceptors defined, each one in its own trait: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#mixin-interceptors - -The first one intercepts any messages having -an internationalized text and replaces it with the resolved text before resuming with the chain. The second one -intercepts any message with an author defined and prints it before resuming the chain with the message unchanged. -But since :class:`I18n` adds the interceptor with :class:`pipelineInner` and :class:`Audit` adds it with -:class:`pipelineOuter`, the audit will happen before the internationalization. - -So if we mixin both interceptors in our Actor, we will see the following output for these example messages: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#mixin-actor - -Unhandled Messages ------------------- -With all that behaviors chaining occurring, what happens to unhandled messages? Let me explain it with -a simple rule. - -.. note:: - Every message not handled by an interceptor will be passed to the next one in the chain. If none - of the interceptors handles a message, the current Actor's behavior will receive it, and if the - behavior doesn't handle it either, it will be treated as usual with the unhandled method. - -But sometimes it is desired for interceptors to break the chain. You can do it by explicitly indicating -that the message has been completely handled by the interceptor by returning -:class:`HandledCompletely`. - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#unhandled - -Processing after delegation ---------------------------- -But what if you want to perform some action after the actor has processed the message (for example to -measure the message processing time)? - -In order to support such use cases, the :class:`Inner` return type has a method :class:`andAfter` which accepts -a code block that can perform some action after the message has been processed by subsequent inner interceptors. - -The following is a simple interceptor that times message processing: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReceivePipelineSpec.scala#interceptor-after - -.. note:: - The :class:`andAfter` code blocks are run on return from handling the message with the next inner handler and - on the same thread. It is therefore safe for the :class:`andAfter` logic to close over the interceptor's state. - -Using Receive Pipelines with Persistence ----------------------------------------- - -When using ``ReceivePipeline`` together with :ref:`PersistentActor` make sure to -mix-in the traits in the following order for them to properly co-operate:: - - class ExampleActor extends PersistentActor with ReceivePipeline { - /* ... */ - } - -The order is important here because of how both traits use internal "around" methods to implement their features, -and if mixed-in the other way around it would not work as expected. If you want to learn more about how exactly this -works, you can read up on Scala's `type linearization mechanism`_; - -.. _type linearization mechanism: http://ktoso.github.io/scala-types-of-types/#type-linearization-vs-the-diamond-problem \ No newline at end of file diff --git a/akka-contrib/docs/reliable-proxy.rst b/akka-contrib/docs/reliable-proxy.rst deleted file mode 100644 index da6ed1be12..0000000000 --- a/akka-contrib/docs/reliable-proxy.rst +++ /dev/null @@ -1,155 +0,0 @@ -.. _reliable-proxy: - -Reliable Proxy Pattern -====================== - -.. warning:: - **Deprecation warning** - ``ReliableProxy`` has been deprecated and is scheduled for removal - in the next major version. Use :ref:`at-least-once-delivery-scala` instead. - -Looking at :ref:`message-delivery-reliability` one might come to the conclusion that -Akka actors are made for blue-sky scenarios: sending messages is the only way -for actors to communicate, and then that is not even guaranteed to work. Is the -whole paradigm built on sand? Of course the answer is an emphatic “No!”. - -A local message send—within the same JVM instance—is not likely to fail, and if -it does the reason was one of - -* it was meant to fail (due to consciously choosing a bounded mailbox, which - upon overflow will have to drop messages) -* or it failed due to a catastrophic VM error, e.g. an - :class:`OutOfMemoryError`, a memory access violation (“segmentation fault”, - GPF, etc.), JVM bug—or someone calling ``System.exit()``. - -In all of these cases, the actor was very likely not in a position to process -the message anyway, so this part of the non-guarantee is not problematic. - -It is a lot more likely for an unintended message delivery failure to occur -when a message send crosses JVM boundaries, i.e. an intermediate unreliable -network is involved. If someone unplugs an ethernet cable, or a power failure -shuts down a router, messages will be lost while the actors would be able to -process them just fine. - -.. note:: - - This does not mean that message send semantics are different between local - and remote operations, it just means that in practice there is a difference - between how good the “best effort” is. - -Introducing the Reliable Proxy ------------------------------- - -.. image:: ReliableProxy.png - -To bridge the disparity between “local” and “remote” sends is the goal of this -pattern. When sending from A to B must be as reliable as in-JVM, regardless of -the deployment, then you can interject a reliable tunnel and send through that -instead. The tunnel consists of two end-points, where the ingress point P (the -“proxy”) is a child of A and the egress point E is a child of P, deployed onto -the same network node where B lives. Messages sent to P will be wrapped in an -envelope, tagged with a sequence number and sent to E, who verifies that the -received envelope has the right sequence number (the next expected one) and -forwards the contained message to B. When B receives this message, the -``sender()`` will be a reference to the sender() of the original message to P. -Reliability is added by E replying to orderly received messages with an ACK, so -that P can tick those messages off its resend list. If ACKs do not come in a -timely fashion, P will try to resend until successful. - -Exactly what does it guarantee? -------------------------------- - -Sending via a :class:`ReliableProxy` makes the message send exactly as reliable -as if the represented target were to live within the same JVM, provided that -the remote actor system does not terminate. In effect, both ends (i.e. JVM and -actor system) must be considered as one when evaluating the reliability of this -communication channel. The benefit is that the network in-between is taken out -of that equation. - -Connecting to the target -^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``proxy`` tries to connect to the ``target`` using the mechanism outlined in -:ref:`actorSelection-scala`. Once connected, if the ``tunnel`` terminates the ``proxy`` -will optionally try to reconnect to the target using using the same process. - -Note that during the reconnection process there is a possibility that a message -could be delivered to the ``target`` more than once. Consider the case where a message -is delivered to the ``target`` and the target system crashes before the ACK -is sent to the ``sender``. After the ``proxy`` reconnects to the ``target`` it -will start resending all of the messages that it has not received an ACK for, and -the message that it never got an ACK for will be redelivered. Either this possibility -should be considered in the design of the ``target`` or reconnection should be disabled. - -How to use it -------------- - -Since this implementation does not offer much in the way of configuration, -simply instantiate a proxy wrapping a target ``ActorPath``. From Java it looks -like this: - -.. includecode:: @contribSrc@/src/test/java/akka/contrib/pattern/ReliableProxyTest.java - :include: import,demo-proxy - -And from Scala like this: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReliableProxyDocSpec.scala#demo - -Since the :class:`ReliableProxy` actor is an :ref:`fsm-scala`, it also offers -the capability to subscribe to state transitions. If you need to know when all -enqueued messages have been received by the remote end-point (and consequently -been forwarded to the target), you can subscribe to the FSM notifications and -observe a transition from state :class:`ReliableProxy.Active` to state -:class:`ReliableProxy.Idle`. - -.. includecode:: @contribSrc@/src/test/java/akka/contrib/pattern/ReliableProxyTest.java#demo-transition - -From Scala it would look like so: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/pattern/ReliableProxyDocSpec.scala#demo-transition - -Configuration -^^^^^^^^^^^^^ - -* Set ``akka.reliable-proxy.debug`` to ``on`` to turn on extra debug logging for your - :class:`ReliableProxy` actors. -* ``akka.reliable-proxy.default-connect-interval`` is used only if you create a :class:`ReliableProxy` - with no reconnections (that is, ``reconnectAfter == None``). The default value is the value of the configuration - property ``akka.remote.retry-gate-closed-for``. For example, if ``akka.remote.retry-gate-closed-for`` is ``5 s`` - case the :class:`ReliableProxy` will send an ``Identify`` message to the *target* every 5 seconds - to try to resolve the :class:`ActorPath` to an :class:`ActorRef` so that messages can be sent to the *target*. - -The Actor Contract ------------------- - -Message it Processes -^^^^^^^^^^^^^^^^^^^^ - -* :class:`FSM.SubscribeTransitionCallBack` and :class:`FSM.UnsubscribeTransitionCallBack`, see :ref:`fsm-scala` -* :class:`ReliableProxy.Unsent`, see the API documentation for details. -* any other message is transferred through the reliable tunnel and forwarded to the designated target actor - -Messages it Sends -^^^^^^^^^^^^^^^^^ - -* :class:`FSM.CurrentState` and :class:`FSM.Transition`, see :ref:`fsm-scala` -* :class:`ReliableProxy.TargetChanged` is sent to the FSM transition subscribers if the proxy reconnects to a - new target. -* :class:`ReliableProxy.ProxyTerminated` is sent to the FSM transition subscribers if the proxy is stopped. - -Exceptions it Escalates -^^^^^^^^^^^^^^^^^^^^^^^ - -* no specific exception types -* any exception encountered by either the local or remote end-point are escalated (only fatal VM errors) - -Arguments it Takes -^^^^^^^^^^^^^^^^^^ - -* *target* is the :class:`ActorPath` to the actor to which the tunnel shall reliably deliver - messages, ``B`` in the above illustration. -* *retryAfter* is the timeout for receiving ACK messages from the remote - end-point; once it fires, all outstanding message sends will be retried. -* *reconnectAfter* is an optional interval between connection attempts. It is also used as the interval - between receiving a ``Terminated`` for the tunnel and attempting to reconnect to the target actor. -* *maxConnectAttempts* is an optional maximum number of attempts to connect to the target while in - the ``Connecting`` state. \ No newline at end of file diff --git a/akka-contrib/docs/throttle.rst b/akka-contrib/docs/throttle.rst deleted file mode 100644 index f4c342c283..0000000000 --- a/akka-contrib/docs/throttle.rst +++ /dev/null @@ -1,70 +0,0 @@ -Throttling Actor Messages -========================= - -Introduction ------------- - -.. warning:: - **Deprecation warning** - ``TimerBasedThrottler`` has been deprecated and is scheduled for removal - in the next major version. Use Akka Streams instead, see - :ref:`migration guide `. - -Suppose you are writing an application that makes HTTP requests to an external -web service and that this web service has a restriction in place: you may not -make more than 10 requests in 1 minute. You will get blocked or need to pay if -you don’t stay under this limit. In such a scenario you will want to employ -a *message throttler*. - -This extension module provides a simple implementation of a throttling actor, -the :class:`TimerBasedThrottler`. - - -How to use it -------------- - -You can use a :class:`TimerBasedThrottler` as follows. From Java it looks -like this: - -.. includecode:: @contribSrc@/src/test/java/akka/contrib/throttle/TimerBasedThrottlerTest.java#demo-code - -And from Scala like this: - -.. includecode:: @contribSrc@/src/test/scala/akka/contrib/throttle/TimerBasedThrottlerSpec.scala#demo-code - -Please refer to the JavaDoc/ScalaDoc documentation for the details. - - -The guarantees --------------- - -:class:`TimerBasedThrottler` uses a timer internally. When the throttler’s rate is 3 msg/s, -for example, the throttler will start a timer that triggers -every second and each time will give the throttler exactly three "vouchers"; -each voucher gives the throttler a right to deliver a message. In this way, -at most 3 messages will be sent out by the throttler in each interval. - -It should be noted that such timer-based throttlers provide relatively **weak guarantees**: - -* Only *start times* are taken into account. This may be a problem if, for example, the - throttler is used to throttle requests to an external web service. If a web request - takes very long on the server then the rate *observed on the server* may be higher. -* A timer-based throttler only makes guarantees for the intervals of its own timer. In - our example, no more than 3 messages are delivered within such intervals. Other - intervals on the timeline, however, may contain more calls. - -The two cases are illustrated in the two figures below, each showing a timeline and three -intervals of the timer. The message delivery times chosen by the throttler are indicated -by dots, and as you can see, each interval contains at most 3 point, so the throttler -works correctly. Still, there is in each example an interval (the red one) that is -problematic. In the first scenario, this is because the delivery times are merely the -start times of longer requests (indicated by the four bars above the timeline that start -at the dots), so that the server observes four requests during the red interval. In the -second scenario, the messages are centered around one of the points in time where the -timer triggers, causing the red interval to contain too many messages. - -.. image:: throttler.png - -For some application scenarios, the guarantees provided by a timer-based throttler might -be too weak. Charles Cordingley’s `blog post `_ -discusses a throttler with stronger guarantees (it solves problem 2 from above). -Future versions of this module may feature throttlers with better guarantees. \ No newline at end of file diff --git a/akka-contrib/docs/throttler.png b/akka-contrib/docs/throttler.png deleted file mode 100644 index eab1a52a34e7435e1e6cafcf3e6c511dab45f078..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4036 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 T<$x{&0|SGntDnm{r-UW|g*xXE