OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_FETCH_THROTTLER_H_ | |
6 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_FETCH_THROTTLER_H_ | |
7 | |
8 #include "base/gtest_prod_util.h" | |
9 #include "base/macros.h" | |
10 #include "base/memory/ref_counted.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "net/base/backoff_entry.h" | |
14 #include "net/base/network_change_notifier.h" | |
15 | |
16 namespace base { | |
17 class TickClock; | |
18 class SingleThreadTaskRunner; | |
19 } // namespace base | |
20 | |
21 namespace password_manager { | |
22 | |
23 class AffiliationFetchThrottlerDelegate; | |
24 | |
25 // Implements the throttling logic that the AffiliationBackend will use when it | |
26 // needs to issue requests over the network to fetch affiliation information. | |
27 // | |
28 // This class manages only the scheduling of the requests. It is up to the | |
29 // consumer (the AffiliationBackend) to actually assemble and send the requests, | |
30 // to report back about their success or failure, and to retry them if desired. | |
31 // The process goes like this: | |
32 // 1.) The consumer calls SignalNetworkRequestNeeded(). | |
33 // 2.) Once appropriate, OnCanSendNetworkRequest() is called on the delegate. | |
34 // 3.) The consumer sends the request, and waits until it completes. | |
35 // 4.) The consumer calls InformOfNetworkRequestComplete(). | |
36 // Note that only a single request at a time is supported. | |
37 // | |
38 // If the request fails in Step 3, the consumer should not automatically retry | |
39 // it. Instead it should always proceed to Step 4, and then -- if retrying the | |
40 // request is desired -- proceed immediately to Step 1. That is, it should act | |
41 // as if another request was needed right away. | |
42 // | |
43 // Essentially, this class implements exponential backoff in case of network and | |
44 // server errors with the additional constraint that no requests will be issued | |
45 // in the first place while there is known to be no network connectivity. This | |
46 // prevents the exponential backoff delay from growing huge during long offline | |
47 // periods, so that requests will not be held back for too long after | |
48 // connectivity is restored. | |
49 class AffiliationFetchThrottler | |
50 : public net::NetworkChangeNotifier::ConnectionTypeObserver { | |
51 public: | |
52 // Creates an instance that will use |tick_clock| as its tick source, and will | |
53 // post to |task_runner| to call the |delegate|'s OnSendNetworkRequest(). | |
mmenke
2015/01/30 19:50:41
Should mention the delegate must outlive the throt
engedy
2015/01/30 20:23:13
Done.
| |
54 AffiliationFetchThrottler( | |
55 AffiliationFetchThrottlerDelegate* delegate, | |
56 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
57 scoped_ptr<base::TickClock> tick_clock); | |
58 ~AffiliationFetchThrottler() override; | |
59 | |
60 // Signals to the throttling logic that a network request is needed, and that | |
61 // OnCanSendNetworkRequest() should be called as soon as the request can be | |
62 // sent. | |
mmenke
2015/01/30 19:50:41
Think it's worth noting that OnCanSendNetworkReque
engedy
2015/01/30 20:23:13
Done.
| |
63 // | |
64 // Calls to this method will be ignored when a request is already known to be | |
65 // needed or while a request is in flight. To signal that another request will | |
66 // be needed right away after the current one, call this method after calling | |
67 // InformOfNetworkRequestComplete(). | |
68 void SignalNetworkRequestNeeded(); | |
69 | |
70 // Informs the back-off logic that the in-flight network request has been | |
71 // completed, either with |success| or not. | |
72 void InformOfNetworkRequestComplete(bool success); | |
73 | |
74 private: | |
75 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, FailedRequests); | |
76 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
77 GracePeriodAfterConnectivityIsRestored); | |
78 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
79 GracePeriodAfterConnectivityIsRestored2); | |
80 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
81 GracePeriodAfterConnectivityIsRestored3); | |
82 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
83 ConnectivityLostDuringBackoff); | |
84 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
85 ConnectivityLostAndRestoredDuringBackoff); | |
86 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, FlakyConnectivity); | |
87 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
88 ConnectivityLostDuringRequest); | |
89 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
90 ConnectivityLostAndRestoredDuringRequest); | |
91 FRIEND_TEST_ALL_PREFIXES(AffiliationFetchThrottlerTest, | |
92 ConnectivityLostAndRestoredDuringRequest2); | |
93 | |
94 enum State { IDLE, FETCH_NEEDED, FETCH_IN_FLIGHT }; | |
95 | |
96 // Exponential backoff parameters in case of network and server errors | |
97 static const net::BackoffEntry::Policy kBackoffPolicy; | |
98 | |
99 // Minimum delay before sending the first request once network connectivity is | |
100 // restored. The fuzzing factor in |kBackoffParameters.jitter_factor| applies. | |
101 static const int64_t kGracePeriodAfterReconnectMs; | |
102 | |
103 // Ensures that OnBackoffDelayExpiredCallback() is scheduled to be called back | |
104 // once the |exponential_backoff_| delay expires. | |
105 void EnsureCallbackIsScheduled(); | |
106 | |
107 // Called back when the |exponential_backoff_| delay expires. | |
108 void OnBackoffDelayExpiredCallback(); | |
109 | |
110 // net::NetworkChangeNotifier::ConnectionTypeObserver: | |
111 void OnConnectionTypeChanged( | |
112 net::NetworkChangeNotifier::ConnectionType type) override; | |
113 | |
114 AffiliationFetchThrottlerDelegate* delegate_; | |
115 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
116 State state_; | |
117 bool has_network_connectivity_; | |
118 bool is_fetch_scheduled_; | |
119 scoped_ptr<base::TickClock> tick_clock_; | |
120 scoped_ptr<net::BackoffEntry> exponential_backoff_; | |
121 base::WeakPtrFactory<AffiliationFetchThrottler> weak_ptr_factory_; | |
mmenke
2015/01/30 19:50:41
Suggest a blank line before the factory, as it sho
engedy
2015/01/30 20:23:13
Done.
| |
122 | |
123 DISALLOW_COPY_AND_ASSIGN(AffiliationFetchThrottler); | |
124 }; | |
125 | |
126 } // namespace password_manager | |
127 | |
128 #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_FETCH_THROTTLER_ H_ | |
OLD | NEW |