1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // A class that manages the registration of types for server-issued
8 #ifndef COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_
9 #define COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_
13 #include "base/basictypes.h"
14 #include "base/threading/non_thread_safe.h"
15 #include "base/time/time.h"
16 #include "base/timer/timer.h"
17 // For invalidation::InvalidationListener::RegistrationState.
18 #include "components/invalidation/invalidation_export.h"
19 #include "components/invalidation/invalidation_util.h"
20 #include "google/cacheinvalidation/include/invalidation-listener.h"
21 #include "google/cacheinvalidation/include/types.h"
25 using ::invalidation::InvalidationListener
;
27 // Manages the details of registering types for invalidation.
28 // Implements exponential backoff for repeated registration attempts
29 // to the invalidation client.
31 // TODO(akalin): Consolidate exponential backoff code. Other
32 // implementations include the syncer thread (both versions) and XMPP
33 // retries. The most sophisticated one is URLRequestThrottler; making
34 // that generic should work for everyone.
35 class INVALIDATION_EXPORT_PRIVATE RegistrationManager
36 : public base::NonThreadSafe
{
38 // Constants for exponential backoff (used by tests).
39 static const int kInitialRegistrationDelaySeconds
;
40 static const int kRegistrationDelayExponent
;
41 static const double kRegistrationDelayMaxJitter
;
42 static const int kMinRegistrationDelaySeconds
;
43 static const int kMaxRegistrationDelaySeconds
;
45 // Types used by testing functions.
46 struct PendingRegistrationInfo
{
47 PendingRegistrationInfo();
49 // Last time a registration request was actually sent.
50 base::Time last_registration_request
;
51 // Time the registration was attempted.
52 base::Time registration_attempt
;
53 // The calculated delay of the pending registration (which may be
55 base::TimeDelta delay
;
56 // The delay of the timer, which should be max(delay, 0).
57 base::TimeDelta actual_delay
;
59 // Map of object IDs with pending registrations to info about the
60 // pending registration.
61 typedef std::map
<invalidation::ObjectId
,
62 PendingRegistrationInfo
,
64 PendingRegistrationMap
;
66 // Does not take ownership of |invalidation_client_|.
67 explicit RegistrationManager(
68 invalidation::InvalidationClient
* invalidation_client
);
70 virtual ~RegistrationManager();
72 // Registers all object IDs included in the given set (that are not
73 // already disabled) and unregisters all other object IDs. The return value is
74 // the set of IDs that was unregistered.
75 ObjectIdSet
UpdateRegisteredIds(const ObjectIdSet
& ids
);
77 // Marks the registration for the |id| lost and re-registers
78 // it (unless it's disabled).
79 void MarkRegistrationLost(const invalidation::ObjectId
& id
);
81 // Marks registrations lost for all enabled object IDs and re-registers them.
82 void MarkAllRegistrationsLost();
84 // Marks the registration for the |id| permanently lost and blocks any future
85 // registration attempts.
86 void DisableId(const invalidation::ObjectId
& id
);
88 // Calculate exponential backoff. |jitter| must be Uniform[-1.0, 1.0].
89 static double CalculateBackoff(double retry_interval
,
90 double initial_retry_interval
,
91 double min_retry_interval
,
92 double max_retry_interval
,
93 double backoff_exponent
,
97 // The functions below should only be used in tests.
99 // Gets all currently registered ids.
100 ObjectIdSet
GetRegisteredIdsForTest() const;
102 // Gets all pending registrations and their next min delays.
103 PendingRegistrationMap
GetPendingRegistrationsForTest() const;
105 // Run pending registrations immediately.
106 void FirePendingRegistrationsForTest();
109 // Overrideable for testing purposes.
110 virtual double GetJitter();
113 struct RegistrationStatus
{
114 RegistrationStatus(const invalidation::ObjectId
& id
,
115 RegistrationManager
* manager
);
116 ~RegistrationStatus();
118 // Calls registration_manager->DoRegister(model_type). (needed by
119 // |registration_timer|). Should only be called if |enabled| is
123 // Sets |enabled| to false and resets other variables.
126 // The object for which this is the status.
127 const invalidation::ObjectId id
;
128 // The parent registration manager.
129 RegistrationManager
* const registration_manager
;
131 // Whether this data type should be registered. Set to false if
132 // we get a non-transient registration failure.
134 // The current registration state.
135 InvalidationListener::RegistrationState state
;
136 // When we last sent a registration request.
137 base::Time last_registration_request
;
138 // When we last tried to register.
139 base::Time last_registration_attempt
;
140 // The calculated delay of any pending registration (which may be
142 base::TimeDelta delay
;
143 // The minimum time to wait until any next registration attempt.
144 // Increased after each consecutive failure.
145 base::TimeDelta next_delay
;
146 // The actual timer for registration.
147 base::OneShotTimer
<RegistrationStatus
> registration_timer
;
149 DISALLOW_COPY_AND_ASSIGN(RegistrationStatus
);
151 typedef std::map
<invalidation::ObjectId
,
154 RegistrationStatusMap
;
156 // Does nothing if the given id is disabled. Otherwise, if
157 // |is_retry| is not set, registers the given type immediately and
158 // resets all backoff parameters. If |is_retry| is set, registers
159 // the given type at some point in the future and increases the
160 // delay until the next retry.
161 void TryRegisterId(const invalidation::ObjectId
& id
,
164 // Registers the given id, which must be valid, immediately.
165 // Updates |last_registration| in the appropriate
166 // RegistrationStatus. Should only be called by
167 // RegistrationStatus::DoRegister().
168 void DoRegisterId(const invalidation::ObjectId
& id
);
170 // Unregisters the given object ID.
171 void UnregisterId(const invalidation::ObjectId
& id
);
173 // Gets all currently registered ids.
174 ObjectIdSet
GetRegisteredIds() const;
176 // Returns true iff the given object ID is registered.
177 bool IsIdRegistered(const invalidation::ObjectId
& id
) const;
179 RegistrationStatusMap registration_statuses_
;
181 invalidation::InvalidationClient
* invalidation_client_
;
183 DISALLOW_COPY_AND_ASSIGN(RegistrationManager
);
186 } // namespace syncer
188 #endif // COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_