blob: 2062027e8122eeec7d89fb7d396d321d4bcf97a0 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/backoff/exponential_backoff.h>
#include <stdlib.h>
#include <lib/fxl/logging.h>
namespace backoff {
ExponentialBackoff::ExponentialBackoff(fit::function<uint64_t()> seed_generator)
: ExponentialBackoff(zx::msec(100), 2u, zx::sec(60 * 60),
std::move(seed_generator)) {}
ExponentialBackoff::ExponentialBackoff(zx::duration initial_delay,
uint32_t retry_factor,
zx::duration max_delay,
fit::function<uint64_t()> seed_generator)
: initial_delay_(initial_delay),
retry_factor_(retry_factor),
max_delay_(max_delay),
max_delay_divided_by_factor_(max_delay_ / retry_factor_),
rng_(seed_generator()) {
FXL_DCHECK(zx::duration() <= initial_delay_ && initial_delay_ <= max_delay_);
FXL_DCHECK(0 < retry_factor_);
FXL_DCHECK(zx::duration() <= max_delay_);
}
ExponentialBackoff::~ExponentialBackoff() {}
zx::duration ExponentialBackoff::GetNext() {
// Add a random component in [0, next_delay).
std::uniform_int_distribution<zx_duration_t> distribution(0u,
next_delay_.get());
zx::duration r(distribution(rng_));
zx::duration result =
max_delay_ - r >= next_delay_ ? next_delay_ + r : max_delay_;
// Calculate the next delay.
next_delay_ = next_delay_ <= max_delay_divided_by_factor_
? next_delay_ * retry_factor_
: max_delay_;
return result;
}
void ExponentialBackoff::Reset() { next_delay_ = initial_delay_; }
} // namespace backoff