def this()

in finagle-core/src/main/scala/com/twitter/finagle/client/BackupRequestFilter.scala [389:490]


  def this(
    maxExtraLoadTunable: Tunable[Double],
    sendInterrupts: Boolean,
    minSendBackupAfterMs: Int,
    responseClassifier: ResponseClassifier,
    clientRetryBudget: RetryBudget,
    statsReceiver: StatsReceiver,
    timer: Timer,
    serviceName: String
  ) =
    this(
      maxExtraLoadTunable,
      sendInterrupts,
      minSendBackupAfterMs,
      responseClassifier,
      newRetryBudget = BackupRequestFilter.newRetryBudget,
      clientRetryBudget = clientRetryBudget,
      Stopwatch.systemMillis,
      statsReceiver,
      timer,
      () => new WindowedPercentileHistogram(timer),
      serviceName
    )

  def this(
    maxExtraLoadTunable: Tunable[Double],
    sendInterrupts: Boolean,
    minSendBackupAfterMs: Int,
    responseClassifier: ResponseClassifier,
    clientRetryBudget: RetryBudget,
    lowestDiscernibleMsValue: Int,
    highestTrackableMsValue: Int,
    statsReceiver: StatsReceiver,
    timer: Timer,
    serviceName: String
  ) =
    this(
      maxExtraLoadTunable,
      sendInterrupts,
      minSendBackupAfterMs,
      responseClassifier,
      newRetryBudget = BackupRequestFilter.newRetryBudget,
      clientRetryBudget = clientRetryBudget,
      Stopwatch.systemMillis,
      statsReceiver,
      timer,
      () =>
        new WindowedPercentileHistogram(
          WindowedPercentileHistogram.DefaultNumBuckets,
          WindowedPercentileHistogram.DefaultBucketSize,
          lowestDiscernibleMsValue,
          highestTrackableMsValue,
          timer
        ),
      serviceName
    )
  @volatile private[this] var backupRequestRetryBudget: RetryBudget =
    newRetryBudget(getAndValidateMaxExtraLoad(maxExtraLoadTunable), nowMs)

  private[this] val SupersededRequestFailure = Failure
    .ignorable(SupersededRequestFailureWhy)
    .withSource(Failure.Source.Service, serviceName)
    .withSource(Failure.Source.AppId, ServerInfo().id)

  private[this] def percentileFromMaxExtraLoad(maxExtraLoad: Double): Double =
    1.0 - maxExtraLoad

  private[this] val windowedPercentile: WindowedPercentileHistogram =
    windowedPercentileHistogramFac()

  // Prevent sending a backup on the first request
  @volatile private[this] var sendBackupAfterMillis: Int = Int.MaxValue

  // For testing
  private[client] def sendBackupAfterDuration: Duration =
    Duration.fromMilliseconds(sendBackupAfterMillis)

  private[this] val sendAfterStat = statsReceiver.stat("send_backup_after_ms")
  private[this] val backupsSent = statsReceiver.counter("backups_sent")

  // Indicates that the backup request returned first and it succeeded.
  private[this] val backupsWon = statsReceiver.counter("backups_won")

  private[this] val budgetExhausted = statsReceiver.counter("budget_exhausted")

  // schedule timer to refresh `sendBackupAfter`, and refresh `backupRequestRetryBudget` in response
  // to changes to the value of `maxExtraLoadTunable`,
  private[this] val refreshTimerTask: TimerTask = {
    @volatile var curMaxExtraLoad = getAndValidateMaxExtraLoad(maxExtraLoadTunable)
    @volatile var percentile = percentileFromMaxExtraLoad(curMaxExtraLoad)
    timer.schedule(RefreshPercentileInterval) {
      val newMaxExtraLoad = getAndValidateMaxExtraLoad(maxExtraLoadTunable)
      if (curMaxExtraLoad != newMaxExtraLoad) {
        curMaxExtraLoad = newMaxExtraLoad
        percentile = percentileFromMaxExtraLoad(curMaxExtraLoad)
        backupRequestRetryBudget = newRetryBudget(curMaxExtraLoad, nowMs)
      }
      sendBackupAfterMillis =
        Math.max(minSendBackupAfterMs, windowedPercentile.percentile(percentile))
      sendAfterStat.add(sendBackupAfterMillis)
    }
  }