in finagle-core/src/main/scala/com/twitter/finagle/service/TimeoutFilter.scala [349:421]
def this(
timeoutFn: () => Duration,
exceptionFn: Duration => RequestTimeoutException,
timer: Timer
) =
this(
timeoutFn,
exceptionFn,
timer,
TimeoutFilter.PropagateDeadlines.Default,
TimeoutFilter.PreferDeadlineOverTimeout.Default)
def this(
timeout: Tunable[Duration],
exceptionFn: Duration => RequestTimeoutException,
timer: Timer
) =
this(
() => timeout().getOrElse(TimeoutFilter.Param.Default),
exceptionFn,
timer,
TimeoutFilter.PropagateDeadlines.Default,
TimeoutFilter.PreferDeadlineOverTimeout.Default
)
def this(timeout: Duration, exception: RequestTimeoutException, timer: Timer) =
this(() => timeout, _ => exception, timer, TimeoutFilter.PropagateDeadlines.Default)
def this(timeout: Duration, timer: Timer) =
this(timeout, new IndividualRequestTimeoutException(timeout), timer)
private[this] val deadlineStat = statsReceiver.stat(
Some("A histogram of propagated deadlines of requests in milliseconds"),
"current_deadline")
private[this] val inExperimentDeadlineCounter =
statsReceiver.counter(Some("A counter of requests that enabled deadlineOnly"), "deadline_only")
private[this] val inExperimentDeadlineLtTimeout = statsReceiver.counter(
Some("Indicates that deadline is stricter than timeout for requests in experiment"),
"deadline_lt_timeout_experiment")
private[this] val deadlineLtTimeout = statsReceiver.counter(
Some("Indicates that deadline is stricter than timeout"),
"deadline_lt_timeout")
private[this] val deadlineAnnotation = rolePrefix + DeadlineAnnotation
private[this] val timeoutAnnotation = rolePrefix + TimeoutAnnotation
private[this] class InternalTimeoutException extends Exception with NoStackTrace
private[this] val internalTimeoutEx = new InternalTimeoutException
def apply(request: Req, service: Service[Req, Rep]): Future[Rep] = {
val timeout = timeoutFn()
val timeoutDeadline = Deadline.ofTimeout(timeout)
var trace: Tracing = null
val deadlineOnly = preferDeadlineOverTimeout && {
trace = Trace()
DeadlineOnlyToggle(trace)
}
if (propagateDeadlines) {
val deadline = Deadline.current match {
case Some(current) => determineExperiment(trace, deadlineOnly, timeoutDeadline, current)
case None => timeoutDeadline
}
val finalTimeout = if (deadlineOnly) deadline.remaining else timeout
Contexts.broadcast.let(Deadline, deadline) {
applyTimeout(request, service, finalTimeout)
}
} else {
Contexts.broadcast.letClear(Deadline) {
applyTimeout(request, service, timeout)
}
}
}