1 // Copyright (c) 2010 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 CHROME_BROWSER_SYNC_NOTIFIER_REGISTRATION_MANAGER_H_ 9 #define CHROME_BROWSER_SYNC_NOTIFIER_REGISTRATION_MANAGER_H_ 10 #pragma once 11 12 #include <map> 13 14 #include "base/basictypes.h" 15 #include "base/time.h" 16 #include "base/timer.h" 17 #include "base/threading/non_thread_safe.h" 18 #include "chrome/browser/sync/syncable/model_type.h" 19 // For invalidation::RegistrationState. 20 #include "google/cacheinvalidation/invalidation-client.h" 21 22 namespace sync_notifier { 23 24 // Manages the details of registering types for invalidation. 25 // Implements exponential backoff for repeated registration attempts 26 // to the invalidation client. 27 // 28 // TODO(akalin): Consolidate exponential backoff code. Other 29 // implementations include the syncer thread (both versions) and XMPP 30 // retries. The most sophisticated one is URLRequestThrottler; making 31 // that generic should work for everyone. 32 class RegistrationManager { 33 public: 34 // Constants for exponential backoff (used by tests). 35 static const int kInitialRegistrationDelaySeconds; 36 static const int kRegistrationDelayExponent; 37 static const double kRegistrationDelayMaxJitter; 38 static const int kMinRegistrationDelaySeconds; 39 static const int kMaxRegistrationDelaySeconds; 40 41 // Types used by testing functions. 42 struct PendingRegistrationInfo { 43 PendingRegistrationInfo(); 44 45 // Last time a registration request was actually sent. 46 base::Time last_registration_request; 47 // Time the registration was attempted. 48 base::Time registration_attempt; 49 // The calculated delay of the pending registration (which may be 50 // negative). 51 base::TimeDelta delay; 52 // The delay of the timer, which should be max(delay, 0). 53 base::TimeDelta actual_delay; 54 }; 55 // Map from types with pending registrations to info about the 56 // pending registration. 57 typedef std::map<syncable::ModelType, PendingRegistrationInfo> 58 PendingRegistrationMap; 59 60 // Does not take ownership of |invalidation_client_|. 61 explicit RegistrationManager( 62 invalidation::InvalidationClient* invalidation_client); 63 64 virtual ~RegistrationManager(); 65 66 // Registers all types included in the given set and sets all other 67 // types to be unregistered. 68 void SetRegisteredTypes(const syncable::ModelTypeSet& types); 69 70 // Marks the registration for the |model_type| lost and re-registers 71 // it. 72 void MarkRegistrationLost(syncable::ModelType model_type); 73 74 // Marks all registrations lost and re-registers them. 75 void MarkAllRegistrationsLost(); 76 77 // The functions below should only be used in tests. 78 79 // Gets all currently-registered types. 80 syncable::ModelTypeSet GetRegisteredTypes() const; 81 82 // Gets all pending registrations and their next min delays. 83 PendingRegistrationMap GetPendingRegistrations() const; 84 85 // Run pending registrations immediately. 86 void FirePendingRegistrationsForTest(); 87 88 // Calculate exponential backoff. |jitter| must be Uniform[-1.0, 89 // 1.0]. 90 static double CalculateBackoff(double retry_interval, 91 double initial_retry_interval, 92 double min_retry_interval, 93 double max_retry_interval, 94 double backoff_exponent, 95 double jitter, 96 double max_jitter); 97 98 protected: 99 // Overrideable for testing purposes. 100 virtual double GetJitter(); 101 102 private: 103 struct RegistrationStatus { 104 RegistrationStatus(); 105 ~RegistrationStatus(); 106 107 // Calls registration_manager->DoRegister(model_type). (needed by 108 // |registration_timer|). 109 void DoRegister(); 110 111 // The model type for which this is the status. 112 syncable::ModelType model_type; 113 // The parent registration manager. 114 RegistrationManager* registration_manager; 115 116 // The current registration state. 117 invalidation::RegistrationState state; 118 // When we last sent a registration request. 119 base::Time last_registration_request; 120 // When we last tried to register. 121 base::Time last_registration_attempt; 122 // The calculated delay of any pending registration (which may be 123 // negative). 124 base::TimeDelta delay; 125 // The minimum time to wait until any next registration attempt. 126 // Increased after each consecutive failure. 127 base::TimeDelta next_delay; 128 // The actual timer for registration. 129 base::OneShotTimer<RegistrationStatus> registration_timer; 130 }; 131 132 // If |is_retry| is not set, registers the given type immediately 133 // and resets all backoff parameters. If |is_retry| is set, 134 // registers the given type at some point in the future and 135 // increases the delay until the next retry. 136 void TryRegisterType(syncable::ModelType model_type, 137 bool is_retry); 138 139 // Registers the given type, which must be valid, immediately. 140 // Updates |last_registration| in the appropriate 141 // RegistrationStatus. Should only be called by 142 // RegistrationStatus::DoRegister(). 143 void DoRegisterType(syncable::ModelType model_type); 144 145 // Unregisters the given type, which must be valid. 146 void UnregisterType(syncable::ModelType model_type); 147 148 // Returns true iff the given type, which must be valid, is registered. 149 bool IsTypeRegistered(syncable::ModelType model_type) const; 150 151 base::NonThreadSafe non_thread_safe_; 152 RegistrationStatus registration_statuses_[syncable::MODEL_TYPE_COUNT]; 153 // Weak pointer. 154 invalidation::InvalidationClient* invalidation_client_; 155 156 DISALLOW_COPY_AND_ASSIGN(RegistrationManager); 157 }; 158 159 } // namespace sync_notifier 160 161 #endif // CHROME_BROWSER_SYNC_NOTIFIER_REGISTRATION_MANAGER_H_ 162