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