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