| Index: sync/engine/backoff_delay_provider.cc
|
| diff --git a/sync/engine/backoff_delay_provider.cc b/sync/engine/backoff_delay_provider.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..af704427a84ec873faef7bdc090591f97a38dd2e
|
| --- /dev/null
|
| +++ b/sync/engine/backoff_delay_provider.cc
|
| @@ -0,0 +1,79 @@
|
| +// Copyright (c) 2012 The Chromium 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 "sync/engine/backoff_delay_provider.h"
|
| +
|
| +#include "base/rand_util.h"
|
| +#include "sync/internal_api/public/engine/polling_constants.h"
|
| +#include "sync/internal_api/public/sessions/model_neutral_state.h"
|
| +#include "sync/internal_api/public/util/syncer_error.h"
|
| +
|
| +using base::TimeDelta;
|
| +
|
| +namespace syncer {
|
| +
|
| +// static
|
| +BackoffDelayProvider* BackoffDelayProvider::FromDefaults() {
|
| + return new BackoffDelayProvider(
|
| + TimeDelta::FromSeconds(kInitialBackoffRetrySeconds),
|
| + TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds));
|
| +}
|
| +
|
| +// static
|
| +BackoffDelayProvider* BackoffDelayProvider::WithShortInitialRetryOverride() {
|
| + return new BackoffDelayProvider(
|
| + TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds),
|
| + TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds));
|
| +}
|
| +
|
| +BackoffDelayProvider::BackoffDelayProvider(
|
| + const base::TimeDelta& default_initial_backoff,
|
| + const base::TimeDelta& short_initial_backoff)
|
| + : default_initial_backoff_(default_initial_backoff),
|
| + short_initial_backoff_(short_initial_backoff) {
|
| +}
|
| +
|
| +BackoffDelayProvider::~BackoffDelayProvider() {}
|
| +
|
| +TimeDelta BackoffDelayProvider::GetDelay(const base::TimeDelta& last_delay) {
|
| + if (last_delay.InSeconds() >= kMaxBackoffSeconds)
|
| + return TimeDelta::FromSeconds(kMaxBackoffSeconds);
|
| +
|
| + // This calculates approx. base_delay_seconds * 2 +/- base_delay_seconds / 2
|
| + int64 backoff_s =
|
| + std::max(static_cast<int64>(1),
|
| + last_delay.InSeconds() * kBackoffRandomizationFactor);
|
| +
|
| + // Flip a coin to randomize backoff interval by +/- 50%.
|
| + int rand_sign = base::RandInt(0, 1) * 2 - 1;
|
| +
|
| + // Truncation is adequate for rounding here.
|
| + backoff_s = backoff_s +
|
| + (rand_sign * (last_delay.InSeconds() / kBackoffRandomizationFactor));
|
| +
|
| + // Cap the backoff interval.
|
| + backoff_s = std::max(static_cast<int64>(1),
|
| + std::min(backoff_s, kMaxBackoffSeconds));
|
| +
|
| + return TimeDelta::FromSeconds(backoff_s);
|
| +}
|
| +
|
| +TimeDelta BackoffDelayProvider::GetInitialDelay(
|
| + const sessions::ModelNeutralState& state) const {
|
| + if (SyncerErrorIsError(state.last_get_key_result))
|
| + return default_initial_backoff_;
|
| + // Note: If we received a MIGRATION_DONE on download updates, then commit
|
| + // should not have taken place. Moreover, if we receive a MIGRATION_DONE
|
| + // on commit, it means that download updates succeeded. Therefore, we only
|
| + // need to check if either code is equal to SERVER_RETURN_MIGRATION_DONE,
|
| + // and not if there were any more serious errors requiring the long retry.
|
| + if (state.last_download_updates_result == SERVER_RETURN_MIGRATION_DONE ||
|
| + state.commit_result == SERVER_RETURN_MIGRATION_DONE) {
|
| + return short_initial_backoff_;
|
| + }
|
| +
|
| + return default_initial_backoff_;
|
| +}
|
| +
|
| +} // namespace syncer
|
|
|