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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2013 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.
#ifndef COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_NUDGE_TRACKER_H_
#define COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_NUDGE_TRACKER_H_
#include <stddef.h>
#include <list>
#include <map>
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "components/sync/base/invalidation_interface.h"
#include "components/sync/base/model_type.h"
#include "components/sync/engine_impl/cycle/data_type_tracker.h"
#include "components/sync/protocol/sync.pb.h"
namespace syncer {
// A class to track the outstanding work required to bring the client back into
// sync with the server.
class NudgeTracker {
public:
static size_t kDefaultMaxPayloadsPerType;
NudgeTracker();
~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() const;
// Returns true if there is a good reason for performing a get updates
// request as part of the next sync cycle.
bool IsGetUpdatesRequired() const;
// Return true if should perform a sync cycle for GU retry.
//
// This is sensitive to changes in 'current time'. Its value can be affected
// by SetSyncCycleStartTime(), SetNextRetryTime(), and
// RecordSuccessfulSyncCycle(). Please refer to those functions for more
// information on how this flag is maintained.
bool IsRetryRequired() const;
// Tells this class that all required update fetching or committing has
// completed successfully.
void RecordSuccessfulSyncCycle();
// Takes note of a local change.
// Returns the shortest nudge delay from the tracker of each type in |types|.
base::TimeDelta RecordLocalChange(ModelTypeSet types);
// Takes note of a locally issued request to refresh a data type.
// Returns the current nudge delay for a local refresh.
base::TimeDelta RecordLocalRefreshRequest(ModelTypeSet types);
// Takes note of the receipt of an invalidation notice from the server.
// Returns the current nudge delay for a remote invalidation.
base::TimeDelta RecordRemoteInvalidation(
ModelType type,
std::unique_ptr<InvalidationInterface> invalidation);
// Take note that an initial sync is pending for this type.
void RecordInitialSyncRequired(ModelType type);
// Takes note that the conflict happended for this type, need to sync to
// resolve conflict locally.
void RecordCommitConflict(ModelType 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(ModelTypeSet types,
base::TimeDelta length,
base::TimeTicks now);
// Marks |type| as being backed off from |now| until |now| + |length|.
void SetTypeBackedOff(ModelType type,
base::TimeDelta length,
base::TimeTicks now);
// Removes any throttling and backoff that have expired.
void UpdateTypeThrottlingAndBackoffState();
// 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(ModelType 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(ModelType type) const;
// Returns |type|'s blocking mode.
WaitInterval::BlockingMode GetTypeBlockingMode(ModelType type) const;
// Returns the set of currently throttled or backed off types.
ModelTypeSet GetBlockedTypes() const;
// Returns the set of types with local changes pending.
ModelTypeSet GetNudgedTypes() const;
// Returns the set of types that have pending invalidations.
ModelTypeSet GetNotifiedTypes() const;
// Returns the set of types that have pending refresh requests.
ModelTypeSet GetRefreshRequestedTypes() const;
// Returns the 'source' of the GetUpdate request.
//
// This flag is deprecated, but still used by the server. There can be more
// than one reason to perform a particular sync cycle. The GetUpdatesTrigger
// message will contain more reliable information about the reasons for
// performing a sync.
//
// See the implementation for important information about the coalesce logic.
sync_pb::GetUpdatesCallerInfo::GetUpdatesSource GetLegacySource() 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(ModelType type, sync_pb::GetUpdateTriggers* msg) const;
// Fills a ProgressMarker with single legacy notification hint expected by the
// sync server. Newer servers will rely on the data set by FillProtoMessage()
// instead of this.
void SetLegacyNotificationHint(
ModelType type,
sync_pb::DataTypeProgressMarker* progress) const;
// Flips the flag if we're due for a retry.
void SetSyncCycleStartTime(base::TimeTicks now);
// Adjusts the number of hints that can be stored locally.
void SetHintBufferSize(size_t size);
// Schedules a retry GetUpdate request for some time in the future.
//
// This is a request sent to us as part of a server response requesting
// that the client perform a GetUpdate request at |next_retry_time| to
// fetch any updates it may have missed in the first attempt.
//
// To avoid strange results from IsRetryRequired() during a sync cycle, the
// effects of this change are not guaranteed to take effect until
// SetSyncCycleStartTime() is called at the start of the *next* sync cycle.
void SetNextRetryTime(base::TimeTicks next_retry_time);
// Update the per-datatype local change nudge delays.
void OnReceivedCustomNudgeDelays(
const std::map<ModelType, base::TimeDelta>& delay_map);
// Update the default nudge delay.
void SetDefaultNudgeDelay(base::TimeDelta nudge_delay);
private:
using TypeTrackerMap = std::map<ModelType, std::unique_ptr<DataTypeTracker>>;
friend class SyncSchedulerImplTest;
TypeTrackerMap type_trackers_;
// Tracks whether or not invalidations are currently enabled.
bool invalidations_enabled_;
// 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_;
base::TimeTicks last_successful_sync_time_;
// A pending update to the current_retry_time_.
//
// The GU retry time is specified by a call to SetNextRetryTime, but we don't
// want that change to take effect right away, since it could happen in the
// middle of a sync cycle. We delay the update until the start of the next
// sync cycle, which is indicated by a call to SetSyncCycleStartTime().
base::TimeTicks next_retry_time_;
// The currently active retry GU time. Will be null if there is no retry GU
// pending at this time.
base::TimeTicks current_retry_time_;
// The time when the sync cycle started. This value is maintained by
// SetSyncCycleStartTime(). This may contain a stale value if we're not
// currently in a sync cycle.
base::TimeTicks sync_cycle_start_time_;
// Nudge delays for various events.
base::TimeDelta minimum_local_nudge_delay_;
base::TimeDelta local_refresh_nudge_delay_;
base::TimeDelta remote_invalidation_nudge_delay_;
DISALLOW_COPY_AND_ASSIGN(NudgeTracker);
};
} // namespace syncer
#endif // COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_NUDGE_TRACKER_H_
|