public final class TailChoppingRoutingLogic extends java.lang.Object implements RoutingLogic, scala.Product, scala.Serializable
interval
has passed, the same message is sent
to the next routee. This process repeats until either a response is received from some routee, the
routees in the pool are exhausted, or the within
duration has passed since the first send. If no
routee sends a response in time, a Status.Failure
wrapping a AskTimeoutException
is sent to the sender.
The goal of this routing algorithm is to decrease tail latencies ("chop off the tail latency") in situations where multiple routees can perform the same piece of work, and where a routee may occasionally respond more slowly than expected. In this case, sending the same work request (also known as a "backup request") to another actor results in decreased response time - because it's less probable that multiple actors are under heavy load simultaneously. This technique is explained in depth in Jeff Dean's presentation on Achieving Rapid Response Times in Large Online Services.
param: scheduler schedules sending messages to routees
param: within expecting at least one reply within this duration, otherwise
it will reply with AskTimeoutException
in a Status.Failure
param: interval duration after which the message will be sent to the next routee
param: context execution context used by scheduler
Constructor and Description |
---|
TailChoppingRoutingLogic(Scheduler scheduler,
scala.concurrent.duration.FiniteDuration within,
scala.concurrent.duration.FiniteDuration interval,
scala.concurrent.ExecutionContext context) |
Modifier and Type | Method and Description |
---|---|
abstract static boolean |
canEqual(java.lang.Object that) |
scala.concurrent.ExecutionContext |
context() |
abstract static boolean |
equals(java.lang.Object that) |
scala.concurrent.duration.FiniteDuration |
interval() |
abstract static int |
productArity() |
abstract static java.lang.Object |
productElement(int n) |
static scala.collection.Iterator<java.lang.Object> |
productIterator() |
static java.lang.String |
productPrefix() |
Scheduler |
scheduler() |
Routee |
select(java.lang.Object message,
scala.collection.immutable.IndexedSeq<Routee> routees)
Pick the destination for a given message.
|
scala.concurrent.duration.FiniteDuration |
within() |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
public TailChoppingRoutingLogic(Scheduler scheduler, scala.concurrent.duration.FiniteDuration within, scala.concurrent.duration.FiniteDuration interval, scala.concurrent.ExecutionContext context)
public abstract static boolean canEqual(java.lang.Object that)
public abstract static boolean equals(java.lang.Object that)
public abstract static java.lang.Object productElement(int n)
public abstract static int productArity()
public static scala.collection.Iterator<java.lang.Object> productIterator()
public static java.lang.String productPrefix()
public Scheduler scheduler()
public scala.concurrent.duration.FiniteDuration within()
public scala.concurrent.duration.FiniteDuration interval()
public scala.concurrent.ExecutionContext context()
public Routee select(java.lang.Object message, scala.collection.immutable.IndexedSeq<Routee> routees)
RoutingLogic
routees
, but in the end it is up to the implementation to
return whatever Routee
to use for sending a specific message.
When implemented from Java it can be good to know that
routees.apply(index)
can be used to get an element
from the IndexedSeq
.
select
in interface RoutingLogic
message
- (undocumented)routees
- (undocumented)