Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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 #ifndef NET_BASE_BACKOFF_ITEM_H_
      6 #define NET_BASE_BACKOFF_ITEM_H_
      7 #pragma once
      8 
      9 #include "base/threading/non_thread_safe.h"
     10 #include "base/time.h"
     11 
     12 namespace net {
     13 
     14 // Provides the core logic needed for randomized exponential back-off
     15 // on requests to a given resource, given a back-off policy.
     16 //
     17 // This utility class knows nothing about network specifics; it is
     18 // intended for reuse in various networking scenarios.
     19 class BackoffEntry : public base::NonThreadSafe {
     20  public:
     21   // The set of parameters that define a back-off policy.
     22   struct Policy {
     23     // Number of initial errors (in sequence) to ignore before applying
     24     // exponential back-off rules.
     25     int num_errors_to_ignore;
     26 
     27     // Initial delay for exponential back-off.
     28     int initial_backoff_ms;
     29 
     30     // Factor by which the waiting time will be multiplied.
     31     double multiply_factor;
     32 
     33     // Fuzzing percentage. ex: 10% will spread requests randomly
     34     // between 90%-100% of the calculated time.
     35     double jitter_factor;
     36 
     37     // Maximum amount of time we are willing to delay our request.
     38     int maximum_backoff_ms;
     39 
     40     // Time to keep an entry from being discarded even when it
     41     // has no significant state, -1 to never discard.
     42     int entry_lifetime_ms;
     43   };
     44 
     45   // Lifetime of policy must enclose lifetime of BackoffEntry. The
     46   // pointer must be valid but is not dereferenced during construction.
     47   explicit BackoffEntry(const Policy* const policy);
     48   virtual ~BackoffEntry();
     49 
     50   // Inform this item that a request for the network resource it is
     51   // tracking was made, and whether it failed or succeeded.
     52   void InformOfRequest(bool succeeded);
     53 
     54   // Returns true if a request for the resource this item tracks should
     55   // be rejected at the present time due to exponential back-off policy.
     56   bool ShouldRejectRequest() const;
     57 
     58   // Returns the absolute time after which this entry (given its present
     59   // state) will no longer reject requests.
     60   base::TimeTicks GetReleaseTime() const;
     61 
     62   // Causes this object reject requests until the specified absolute time.
     63   // This can be used to e.g. implement support for a Retry-After header.
     64   void SetCustomReleaseTime(const base::TimeTicks& release_time);
     65 
     66   // Returns true if this object has no significant state (i.e. you could
     67   // just as well start with a fresh BackoffEntry object), and hasn't
     68   // had for Policy::entry_lifetime_ms_.
     69   bool CanDiscard() const;
     70 
     71  protected:
     72   // Equivalent to TimeTicks::Now(), virtual so unit tests can override.
     73   // TODO(joi): Switch to constructor-time dependency injection?
     74   virtual base::TimeTicks GetTimeNow() const;
     75 
     76  private:
     77   // Calculates when requests should again be allowed through.
     78   base::TimeTicks CalculateReleaseTime() const;
     79 
     80   // Timestamp calculated by the exponential back-off algorithm at which we are
     81   // allowed to start sending requests again.
     82   base::TimeTicks exponential_backoff_release_time_;
     83 
     84   // Counts request errors; reset on success.
     85   int failure_count_;
     86 
     87   const Policy* const policy_;
     88 
     89   DISALLOW_COPY_AND_ASSIGN(BackoffEntry);
     90 };
     91 
     92 }  // namespace net
     93 
     94 #endif  // NET_BASE_BACKOFF_ITEM_H_
     95