65 lines
No EOL
3 KiB
ReStructuredText
65 lines
No EOL
3 KiB
ReStructuredText
Throttling Actor Messages
|
||
=========================
|
||
|
||
Introduction
|
||
------------
|
||
|
||
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 <http://www.cordinc.com/blog/2010/04/java-multichannel-asynchronous.html>`_
|
||
discusses a throttler with stronger guarantees (it solves problem 2 from above).
|
||
Future versions of this module may feature throttlers with better guarantees. |