Home | History | Annotate | Download | only in invalidation
      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