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. 4 // 5 // A class that manages the registration of types for server-issued 6 // notifications. 7 8 #ifndef COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_ 9 #define COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_ 10 11 #include <map> 12 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" 22 23 namespace syncer { 24 25 using ::invalidation::InvalidationListener; 26 27 // Manages the details of registering types for invalidation. 28 // Implements exponential backoff for repeated registration attempts 29 // to the invalidation client. 30 // 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 { 37 public: 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; 44 45 // Types used by testing functions. 46 struct PendingRegistrationInfo { 47 PendingRegistrationInfo(); 48 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 54 // negative). 55 base::TimeDelta delay; 56 // The delay of the timer, which should be max(delay, 0). 57 base::TimeDelta actual_delay; 58 }; 59 // Map of object IDs with pending registrations to info about the 60 // pending registration. 61 typedef std::map<invalidation::ObjectId, 62 PendingRegistrationInfo, 63 ObjectIdLessThan> 64 PendingRegistrationMap; 65 66 // Does not take ownership of |invalidation_client_|. 67 explicit RegistrationManager( 68 invalidation::InvalidationClient* invalidation_client); 69 70 virtual ~RegistrationManager(); 71 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); 76 77 // Marks the registration for the |id| lost and re-registers 78 // it (unless it's disabled). 79 void MarkRegistrationLost(const invalidation::ObjectId& id); 80 81 // Marks registrations lost for all enabled object IDs and re-registers them. 82 void MarkAllRegistrationsLost(); 83 84 // Marks the registration for the |id| permanently lost and blocks any future 85 // registration attempts. 86 void DisableId(const invalidation::ObjectId& id); 87 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, 94 double jitter, 95 double max_jitter); 96 97 // The functions below should only be used in tests. 98 99 // Gets all currently registered ids. 100 ObjectIdSet GetRegisteredIdsForTest() const; 101 102 // Gets all pending registrations and their next min delays. 103 PendingRegistrationMap GetPendingRegistrationsForTest() const; 104 105 // Run pending registrations immediately. 106 void FirePendingRegistrationsForTest(); 107 108 protected: 109 // Overrideable for testing purposes. 110 virtual double GetJitter(); 111 112 private: 113 struct RegistrationStatus { 114 RegistrationStatus(const invalidation::ObjectId& id, 115 RegistrationManager* manager); 116 ~RegistrationStatus(); 117 118 // Calls registration_manager->DoRegister(model_type). (needed by 119 // |registration_timer|). Should only be called if |enabled| is 120 // true. 121 void DoRegister(); 122 123 // Sets |enabled| to false and resets other variables. 124 void Disable(); 125 126 // The object for which this is the status. 127 const invalidation::ObjectId id; 128 // The parent registration manager. 129 RegistrationManager* const registration_manager; 130 131 // Whether this data type should be registered. Set to false if 132 // we get a non-transient registration failure. 133 bool enabled; 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 141 // negative). 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; 148 149 DISALLOW_COPY_AND_ASSIGN(RegistrationStatus); 150 }; 151 typedef std::map<invalidation::ObjectId, 152 RegistrationStatus*, 153 ObjectIdLessThan> 154 RegistrationStatusMap; 155 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, 162 bool is_retry); 163 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); 169 170 // Unregisters the given object ID. 171 void UnregisterId(const invalidation::ObjectId& id); 172 173 // Gets all currently registered ids. 174 ObjectIdSet GetRegisteredIds() const; 175 176 // Returns true iff the given object ID is registered. 177 bool IsIdRegistered(const invalidation::ObjectId& id) const; 178 179 RegistrationStatusMap registration_statuses_; 180 // Weak pointer. 181 invalidation::InvalidationClient* invalidation_client_; 182 183 DISALLOW_COPY_AND_ASSIGN(RegistrationManager); 184 }; 185 186 } // namespace syncer 187 188 #endif // COMPONENTS_INVALIDATION_REGISTRATION_MANAGER_H_ 189