Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: net/base/network_throttle_manager_impl.h

Issue 2130493002: Implement THROTTLED priority semantics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@NetworkStreamThrottler
Patch Set: Sync'd to p420478 Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/network_throttle_manager.cc ('k') | net/base/network_throttle_manager_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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_NETWORK_THROTTLE_MANAGER_IMPL_H_
6 #define NET_BASE_NETWORK_THROTTLE_MANAGER_IMPL_H_
7
8 #include <list>
9 #include <memory>
10 #include <set>
11
12 #include "base/memory/weak_ptr.h"
13 #include "base/time/tick_clock.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 #include "net/base/network_throttle_manager.h"
17 #include "net/base/percentile_estimator.h"
18
19 namespace net {
20
21 // The NetworkThrottleManagerImpl implements the following semantics:
22 // * All throttles of priority above THROTTLED are created unblocked.
23 // * Throttles of priority THROTTLED are created unblocked, unless
24 // there are |kActiveRequestThrottlingLimit| or more throttles active,
25 // in which case they are created blocked.
26 // When that condition is no longer true, throttles of priority
27 // THROTTLED are unblocked, in priority order.
28 // * Throttles that have been alive for more than |kMedianLifetimeMultiple|
29 // times the current estimate of the throttle median lifetime do
30 // not count against the |kActiveRequestThrottlingLimit| limit.
31 class NET_EXPORT NetworkThrottleManagerImpl : public NetworkThrottleManager {
32 public:
33 // Maximum number of active requests before new THROTTLED throttles
34 // are created blocked. Throttles are unblocked as the active requests
35 // fall below this limit.
36 static const size_t kActiveRequestThrottlingLimit;
37
38 // Note that the following constants are implementation details exposed in the
39 // header file only for testing, and should not be relied on by consumers.
40
41 // Constants used for the running estimate of the median lifetime
42 // for throttles created by this class. That estimate is used to detect
43 // throttles that are "unusually old" and hence may represent hanging GETs
44 // or long-running streams. Such throttles should not be considered
45 // "active" for the purposes of determining whether THROTTLED throttles
46 // should be created in a blocked state.
47 // Note that the precise details of this algorithm aren't very important;
48 // specifically, if it takes a while for the median estimate to reach the
49 // "actual" median of a request stream, the consequence is either a bit more
50 // of a delay in unblocking THROTTLED requests or more THROTTLED requests
51 // being unblocked than would be ideal (i.e. performance tweaks at
52 // the margins).
53
54 // Multiple of the current median lifetime beyond which a throttle is
55 // considered "unusually old" and not considered in counting active
56 // requests. This is used instead of a percentile estimate because the goal
57 // is eliminating requests that are qualitatively different
58 // (e.g. hanging gets, streams), and the percentage of all requests
59 // that are in that category can vary greatly.
60 static const int kMedianLifetimeMultiple;
61
62 // The median lifetime estimate starts at class creation at
63 // |kInitialMedianInMs|.
64 static const int kInitialMedianInMs;
65
66 NetworkThrottleManagerImpl();
67 ~NetworkThrottleManagerImpl() override;
68
69 // NetworkThrottleManager:
70 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
71 RequestPriority priority,
72 bool ignore_limits) override;
73
74 void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
75
76 // If the |NowTicks()| value of |tick_clock_| is greater than the
77 // time the outstanding_recomputation_timer_ has set to go off, Stop()
78 // the timer and manually run the associated user task. This is to allow
79 // "fast-forwarding" of the clock for testing by working around
80 // base::Timer's direct use of base::TimeTicks rather than a base::TickClock.
81 //
82 // Note specifically that base::Timer::Start takes a time delta into the
83 // future and adds it to base::TimeTicks::Now() to get
84 // base::Timer::desired_run_time(), which is what this method compares
85 // |tick_clock_->NowTicks()| against. So tests should be written so that
86 // the timer Start() routine whose callback should be run is called
87 // with |tick_clock_| in accord with wallclock time. This routine can then
88 // be called with |tick_clock_| set into the future.
89 void ConditionallyTriggerTimerForTesting();
90
91 private:
92 class ThrottleImpl;
93 using ThrottleList = std::list<ThrottleImpl*>;
Charlie Harrison 2016/09/23 15:11:12 Can you use a deque? I think it will have better c
Randy Smith (Not in Mondays) 2016/09/23 22:16:49 So I considered using a deque, but didn't because
Charlie Harrison 2016/09/26 22:27:27 There are a few times when I could (maybe) see cac
Randy Smith (Not in Mondays) 2016/10/03 01:06:48 Yeah, unless we have batch IPCs for those and plum
Charlie Harrison 2016/10/03 20:53:48 That's what I am hoping we end up doing (i.e. batc
94
95 // Comparison function used to define the ordering relationship
96 // for |CreationTimeOrderedSet| below.
97 static bool CreationTimeSetCompare(ThrottleImpl* throttle1,
98 ThrottleImpl* throttle2);
99
100 using CreationTimeOrderedSet =
101 std::set<ThrottleImpl*, bool (*)(ThrottleImpl*, ThrottleImpl*)>;
102
103 void OnThrottlePriorityChanged(ThrottleImpl* throttle,
104 RequestPriority old_priority,
105 RequestPriority new_priority);
106 void OnThrottleDestroyed(ThrottleImpl* throttle);
107
108 // Recompute how many requests "count" as outstanding (i.e.
109 // are not older than kMedianLifetimeMultiple * MedianThrottleLifetime()).
110 void RecomputeOutstanding();
111
112 // Unblock the specified throttle. May result in re-entrant calls
113 // into NetworkThrottleManagerImpl.
114 void UnblockThrottle(ThrottleImpl* throttle);
115
116 // Recomputes how many requests count as outstanding, checks to see
117 // if any currently blocked throttles should be unblocked,
118 // and unblock them if so. Note that unblocking may result in
119 // re-entrant calls to this class, so no assumptions about state persistence
120 // should be made across this call.
121 void MaybeUnblockThrottles();
122
123 PercentileEstimator lifetime_median_estimate_;
124
125 // base::Timer controlling outstanding request recomputation.
126 base::Timer outstanding_recomputation_timer_;
127
128 // Contains only OUTSTANDING throttles.
129 CreationTimeOrderedSet outstanding_throttles_;
130
131 // FIFO list of BLOCKED throttles. This is a list so that the
132 // throttles can store iterators to themselves.
133 ThrottleList blocked_throttles_;
134
135 // For testing.
136 std::unique_ptr<base::TickClock> tick_clock_;
137
138 base::WeakPtrFactory<NetworkThrottleManagerImpl> weak_ptr_factory_;
139
140 DISALLOW_COPY_AND_ASSIGN(NetworkThrottleManagerImpl);
141 };
142
143 } // namespace net
144
145 #endif // NET_BASE_NETWORK_THROTTLE_MANAGER_IMPL_H_
OLDNEW
« no previous file with comments | « net/base/network_throttle_manager.cc ('k') | net/base/network_throttle_manager_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698