• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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