1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_ENGINE_CYCLE_NUDGE_TRACKER_H_
#define COMPONENTS_SYNC_ENGINE_CYCLE_NUDGE_TRACKER_H_
#include <stddef.h>
#include <map>
#include <memory>
#include <optional>
#include "base/compiler_specific.h"
#include "base/time/time.h"
#include "components/sync/base/data_type.h"
#include "components/sync/base/sync_invalidation.h"
#include "components/sync/engine/cycle/data_type_tracker.h"
namespace sync_pb {
class GetUpdateTriggers;
enum SyncEnums_GetUpdatesOrigin : int;
} // namespace sync_pb
namespace syncer {
// A class to track the outstanding work required to bring the client back into
// sync with the server.
class NudgeTracker {
public:
NudgeTracker();
NudgeTracker(const NudgeTracker&) = delete;
NudgeTracker& operator=(const NudgeTracker&) = delete;
~NudgeTracker();
// Returns true if there is a good reason for performing a sync cycle.
// This does not take into account whether or not this is a good *time* to
// perform a sync cycle; that's the scheduler's job.
bool IsSyncRequired(DataTypeSet types) const;
// Returns true if there is a good reason for performing a get updates
// request as part of the next sync cycle.
bool IsGetUpdatesRequired(DataTypeSet types) const;
// Tells this class that a commit message has been sent (note that each sync
// cycle may include an arbitrary number of commit messages).
void RecordSuccessfulCommitMessage(DataTypeSet types);
// Tells this class that all required update fetching or committing has
// completed successfully, as the result of a "normal" sync cycle.
// Any blocked data types will ignore this, but non-blocked types and the
// overall state will still get updated.
void RecordSuccessfulSyncCycleIfNotBlocked(DataTypeSet types);
// Tells this class that the initial sync has happened for the given `types`,
// generally due to a "configuration" cycle.
void RecordInitialSyncDone(DataTypeSet types);
// Takes note of a local change.
// Returns the current nudge delay for local changes to `type`.
base::TimeDelta RecordLocalChange(DataType type, bool is_single_client);
// Takes note of a locally issued request to refresh a data type.
// Returns the nudge delay for a local refresh.
base::TimeDelta RecordLocalRefreshRequest(DataTypeSet types);
// Takes note of the receipt of an invalidation notice from the server.
// Returns the nudge delay for a remote invalidation.
base::TimeDelta GetRemoteInvalidationDelay(DataType type) const;
// Take note that an initial sync is pending for this type.
void RecordInitialSyncRequired(DataType type);
// Takes note that the conflict happended for this type, need to sync to
// resolve conflict locally.
void RecordCommitConflict(DataType type);
// These functions should be called to keep this class informed of the status
// of the connection to the invalidations server.
void OnInvalidationsEnabled();
void OnInvalidationsDisabled();
// Marks `types` as being throttled from `now` until `now` + `length`.
void SetTypesThrottledUntil(DataTypeSet types,
base::TimeDelta length,
base::TimeTicks now);
// Marks `type` as being backed off from `now` until `now` + `length`.
void SetTypeBackedOff(DataType type,
base::TimeDelta length,
base::TimeTicks now);
// Removes any throttling and backoff that have expired.
void UpdateTypeThrottlingAndBackoffState();
void SetHasPendingInvalidations(DataType type,
bool has_pending_invalidations);
// Returns the time of the next type unthrottling or unbackoff.
base::TimeDelta GetTimeUntilNextUnblock() const;
// Returns the time of for type last backing off interval.
base::TimeDelta GetTypeLastBackoffInterval(DataType type) const;
// Returns true if any type is currenlty throttled or backed off.
bool IsAnyTypeBlocked() const;
// Returns true if `type` is currently blocked.
bool IsTypeBlocked(DataType type) const;
// Returns `type`'s blocking mode.
WaitInterval::BlockingMode GetTypeBlockingMode(DataType type) const;
// Returns the set of currently throttled or backed off types.
DataTypeSet GetBlockedTypes() const;
// Returns the set of types with local changes pending.
DataTypeSet GetNudgedTypes() const;
// Returns the set of types that have pending invalidations.
DataTypeSet GetNotifiedTypes() const;
// Returns the set of types that have pending refresh requests.
DataTypeSet GetRefreshRequestedTypes() const;
// Returns the 'origin' of the GetUpdate request.
sync_pb::SyncEnums_GetUpdatesOrigin GetOrigin() const;
// Fills a GetUpdatesTrigger message for the next GetUpdates request. This is
// used by the DownloadUpdatesCommand to dump lots of useful per-type state
// information into the GetUpdate request before sending it off to the server.
void FillProtoMessage(DataType type, sync_pb::GetUpdateTriggers* msg) const;
// Update the per-datatype local change nudge delay. No update happens
// if `delay` is too small (less than the smallest default delay).
void UpdateLocalChangeDelay(DataType type, const base::TimeDelta& delay);
// UpdateLocalChangeDelay() usually rejects a delay update if the value
// is too small. This method ignores that check.
void SetLocalChangeDelayIgnoringMinForTest(DataType type,
const base::TimeDelta& delay);
// Updates the parameters for commit quotas for the data types that can
// receive commits via extension APIs. Empty optional means using the
// defaults.
void SetQuotaParamsForExtensionTypes(
std::optional<int> max_tokens,
std::optional<base::TimeDelta> refill_interval,
std::optional<base::TimeDelta> depleted_quota_nudge_delay);
private:
using TypeTrackerMap = std::map<DataType, std::unique_ptr<DataTypeTracker>>;
friend class SyncSchedulerImplTest;
TypeTrackerMap type_trackers_;
// Tracks whether or not invalidations are currently enabled.
bool invalidations_enabled_ = false;
// This flag is set if suspect that some technical malfunction or known bug
// may have left us with some unserviced invalidations.
//
// Keeps track of whether or not we're fully in sync with the invalidation
// server. This can be false even if invalidations are enabled and working
// correctly. For example, until we get ack-tracking working properly, we
// won't persist invalidations between restarts, so we may be out of sync when
// we restart. The only way to get back into sync is to have invalidations
// enabled, then complete a sync cycle to make sure we're fully up to date.
bool invalidations_out_of_sync_ = true;
};
} // namespace syncer
#endif // COMPONENTS_SYNC_ENGINE_CYCLE_NUDGE_TRACKER_H_
|