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

Side by Side Diff: content/browser/loader/resource_scheduler.cc

Issue 692723002: Add histograms to gather ResourceScheduler information. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Second round of comments. Created 6 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <set> 5 #include <set>
6 6
7 #include "content/browser/loader/resource_scheduler.h" 7 #include "content/browser/loader/resource_scheduler.h"
8 8
9 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
10 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/time/time.h"
11 #include "content/common/resource_messages.h" 13 #include "content/common/resource_messages.h"
12 #include "content/browser/loader/resource_message_delegate.h" 14 #include "content/browser/loader/resource_message_delegate.h"
13 #include "content/public/browser/resource_controller.h" 15 #include "content/public/browser/resource_controller.h"
14 #include "content/public/browser/resource_request_info.h" 16 #include "content/public/browser/resource_request_info.h"
15 #include "content/public/browser/resource_throttle.h" 17 #include "content/public/browser/resource_throttle.h"
16 #include "ipc/ipc_message_macros.h" 18 #include "ipc/ipc_message_macros.h"
17 #include "net/base/host_port_pair.h" 19 #include "net/base/host_port_pair.h"
18 #include "net/base/load_flags.h" 20 #include "net/base/load_flags.h"
19 #include "net/base/request_priority.h" 21 #include "net/base/request_priority.h"
20 #include "net/http/http_server_properties.h" 22 #include "net/http/http_server_properties.h"
21 #include "net/url_request/url_request.h" 23 #include "net/url_request/url_request.h"
22 #include "net/url_request/url_request_context.h" 24 #include "net/url_request/url_request_context.h"
23 25
24 namespace content { 26 namespace content {
25 27
28 namespace {
29
30 void PostHistogram(const char* base_name,
31 const char* suffix,
32 base::TimeDelta time) {
33 std::string histogram_name =
34 base::StringPrintf("ResourceScheduler.%s_%s", base_name, suffix);
35 base::HistogramBase* histogram_counter = base::Histogram::FactoryTimeGet(
36 histogram_name,
37 base::TimeDelta::FromMilliseconds(1),
38 base::TimeDelta::FromMinutes(5),
39 50,
40 base::Histogram::kUmaTargetedHistogramFlag);
41 histogram_counter->AddTime(time);
42 }
43 } // namespace
mmenke 2014/11/03 19:01:19 nit: Blank line before end of namespace.
aiolos (Not reviewing) 2014/11/03 20:16:01 Done.
44
26 static const size_t kCoalescedTimerPeriod = 5000; 45 static const size_t kCoalescedTimerPeriod = 5000;
27 static const size_t kMaxNumDelayableRequestsPerClient = 10; 46 static const size_t kMaxNumDelayableRequestsPerClient = 10;
28 static const size_t kMaxNumDelayableRequestsPerHost = 6; 47 static const size_t kMaxNumDelayableRequestsPerHost = 6;
29 static const size_t kMaxNumThrottledRequestsPerClient = 1; 48 static const size_t kMaxNumThrottledRequestsPerClient = 1;
mmenke 2014/11/03 19:01:20 Optional nit: When there's an anonymous namespace
30 49
31 struct ResourceScheduler::RequestPriorityParams { 50 struct ResourceScheduler::RequestPriorityParams {
32 RequestPriorityParams() 51 RequestPriorityParams()
33 : priority(net::DEFAULT_PRIORITY), 52 : priority(net::DEFAULT_PRIORITY),
34 intra_priority(0) { 53 intra_priority(0) {
35 } 54 }
36 55
37 RequestPriorityParams(net::RequestPriority priority, int intra_priority) 56 RequestPriorityParams(net::RequestPriority priority, int intra_priority)
38 : priority(priority), 57 : priority(priority),
39 intra_priority(intra_priority) { 58 intra_priority(intra_priority) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 client_id_(client_id), 144 client_id_(client_id),
126 request_(request), 145 request_(request),
127 ready_(false), 146 ready_(false),
128 deferred_(false), 147 deferred_(false),
129 classification_(NORMAL_REQUEST), 148 classification_(NORMAL_REQUEST),
130 scheduler_(scheduler), 149 scheduler_(scheduler),
131 priority_(priority), 150 priority_(priority),
132 fifo_ordering_(0) { 151 fifo_ordering_(0) {
133 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_, 152 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_,
134 "url", request->url().spec()); 153 "url", request->url().spec());
154 client_state_on_creation_ = scheduler_->GetClientState(client_id_);
mmenke 2014/11/03 19:01:19 optional nit: I think it's preferred to have "cli
aiolos (Not reviewing) 2014/11/03 20:16:02 Done.
135 } 155 }
136 156
137 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); } 157 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); }
138 158
139 void Start() { 159 void Start() {
140 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued"); 160 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued");
141 ready_ = true; 161 ready_ = true;
142 if (deferred_ && request_->status().is_success()) { 162 if (!request_->status().is_success())
163 return;
164 base::TimeTicks time = base::TimeTicks::Now();
165 ClientState current_state = scheduler_->GetClientState(client_id_);
166 const char* client_state = "Other";
167 if (current_state == client_state_on_creation_ && current_state == ACTIVE)
168 client_state = "Active";
169 else if (current_state == client_state_on_creation_ &&
170 current_state == BACKGROUND)
171 client_state = "Background";
mmenke 2014/11/03 19:01:20 nit: Use braces on all blocks of an if statements
aiolos (Not reviewing) 2014/11/03 20:16:01 Done.
172
173 if (deferred_) {
143 deferred_ = false; 174 deferred_ = false;
144 controller()->Resume(); 175 controller()->Resume();
145 } 176 PostHistogram("RequestTimeDeferred", client_state, time - time_deferred_);
177 } else
178 PostHistogram("RequestTimeDeferred",
179 client_state,
180 base::TimeDelta::FromMicroseconds(0));
mmenke 2014/11/03 19:01:19 nit: Per above comment, should use braces here.
aiolos (Not reviewing) 2014/11/03 20:16:01 Done.
181 PostHistogram(
182 "RequestTimeThrottled", client_state, time - request_->creation_time());
183 // TODO(aiolos): Remove one of the above sets of histograms after gaining an
184 // understanding of the difference between them and which one is more
185 // interesting.
146 } 186 }
147 187
148 void set_request_priority_params(const RequestPriorityParams& priority) { 188 void set_request_priority_params(const RequestPriorityParams& priority) {
149 priority_ = priority; 189 priority_ = priority;
150 } 190 }
151 const RequestPriorityParams& get_request_priority_params() const { 191 const RequestPriorityParams& get_request_priority_params() const {
152 return priority_; 192 return priority_;
153 } 193 }
154 const ClientId& client_id() const { return client_id_; } 194 const ClientId& client_id() const { return client_id_; }
155 net::URLRequest* url_request() { return request_; } 195 net::URLRequest* url_request() { return request_; }
(...skipping 14 matching lines...) Expand all
170 bool OnMessageReceived(const IPC::Message& message) override { 210 bool OnMessageReceived(const IPC::Message& message) override {
171 bool handled = true; 211 bool handled = true;
172 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) 212 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message)
173 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) 213 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority)
174 IPC_MESSAGE_UNHANDLED(handled = false) 214 IPC_MESSAGE_UNHANDLED(handled = false)
175 IPC_END_MESSAGE_MAP() 215 IPC_END_MESSAGE_MAP()
176 return handled; 216 return handled;
177 } 217 }
178 218
179 // ResourceThrottle interface: 219 // ResourceThrottle interface:
180 void WillStartRequest(bool* defer) override { deferred_ = *defer = !ready_; } 220 void WillStartRequest(bool* defer) override {
221 deferred_ = *defer = !ready_;
222 time_deferred_ = base::TimeTicks::Now();
223 }
181 224
182 const char* GetNameForLogging() const override { return "ResourceScheduler"; } 225 const char* GetNameForLogging() const override { return "ResourceScheduler"; }
183 226
184 void DidChangePriority(int request_id, net::RequestPriority new_priority, 227 void DidChangePriority(int request_id, net::RequestPriority new_priority,
185 int intra_priority_value) { 228 int intra_priority_value) {
186 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); 229 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value);
187 } 230 }
188 231
189 ClientId client_id_; 232 ClientId client_id_;
233 ResourceScheduler::ClientState client_state_on_creation_;
190 net::URLRequest* request_; 234 net::URLRequest* request_;
mmenke 2014/11/03 19:01:19 While you're here, can client_id_ and request_ be
aiolos (Not reviewing) 2014/11/03 20:16:01 request_ can't be const because of the usage of ur
191 bool ready_; 235 bool ready_;
192 bool deferred_; 236 bool deferred_;
193 RequestClassification classification_; 237 RequestClassification classification_;
194 ResourceScheduler* scheduler_; 238 ResourceScheduler* scheduler_;
195 RequestPriorityParams priority_; 239 RequestPriorityParams priority_;
196 uint32 fifo_ordering_; 240 uint32 fifo_ordering_;
241 base::TimeTicks time_deferred_;
197 242
198 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); 243 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
199 }; 244 };
200 245
201 bool ResourceScheduler::ScheduledResourceSorter::operator()( 246 bool ResourceScheduler::ScheduledResourceSorter::operator()(
202 const ScheduledResourceRequest* a, 247 const ScheduledResourceRequest* a,
203 const ScheduledResourceRequest* b) const { 248 const ScheduledResourceRequest* b) const {
204 // Want the set to be ordered first by decreasing priority, then by 249 // Want the set to be ordered first by decreasing priority, then by
205 // decreasing intra_priority. 250 // decreasing intra_priority.
206 // ie. with (priority, intra_priority) 251 // ie. with (priority, intra_priority)
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 DCHECK(client); 792 DCHECK(client);
748 return client->throttle_state(); 793 return client->throttle_state();
749 } 794 }
750 795
751 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( 796 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
752 int child_id, 797 int child_id,
753 int route_id, 798 int route_id,
754 net::URLRequest* url_request) { 799 net::URLRequest* url_request) {
755 DCHECK(CalledOnValidThread()); 800 DCHECK(CalledOnValidThread());
756 ClientId client_id = MakeClientId(child_id, route_id); 801 ClientId client_id = MakeClientId(child_id, route_id);
757 scoped_ptr<ScheduledResourceRequest> request( 802 scoped_ptr<ScheduledResourceRequest> request(new ScheduledResourceRequest(
758 new ScheduledResourceRequest(client_id, url_request, this, 803 client_id,
759 RequestPriorityParams(url_request->priority(), 0))); 804 url_request,
805 this,
806 RequestPriorityParams(url_request->priority(), 0)));
760 807
761 ClientMap::iterator it = client_map_.find(client_id); 808 ClientMap::iterator it = client_map_.find(client_id);
762 if (it == client_map_.end()) { 809 if (it == client_map_.end()) {
763 // There are several ways this could happen: 810 // There are several ways this could happen:
764 // 1. <a ping> requests don't have a route_id. 811 // 1. <a ping> requests don't have a route_id.
765 // 2. Most unittests don't send the IPCs needed to register Clients. 812 // 2. Most unittests don't send the IPCs needed to register Clients.
766 // 3. The tab is closed while a RequestResource IPC is in flight. 813 // 3. The tab is closed while a RequestResource IPC is in flight.
767 unowned_requests_.insert(request.get()); 814 unowned_requests_.insert(request.get());
768 request->Start(); 815 request->Start();
769 return request.Pass(); 816 return request.Pass();
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 void ResourceScheduler::LoadCoalescedRequests() { 1038 void ResourceScheduler::LoadCoalescedRequests() {
992 DCHECK(should_coalesce_); 1039 DCHECK(should_coalesce_);
993 ClientMap::iterator client_it = client_map_.begin(); 1040 ClientMap::iterator client_it = client_map_.begin();
994 while (client_it != client_map_.end()) { 1041 while (client_it != client_map_.end()) {
995 Client* client = client_it->second; 1042 Client* client = client_it->second;
996 client->LoadCoalescedRequests(); 1043 client->LoadCoalescedRequests();
997 ++client_it; 1044 ++client_it;
998 } 1045 }
999 } 1046 }
1000 1047
1048 ResourceScheduler::ClientState ResourceScheduler::GetClientState(
1049 ClientId client_id) const {
1050 ClientMap::const_iterator client_it = client_map_.find(client_id);
1051 if (client_it == client_map_.end())
1052 return UNKNOWN;
1053 return client_it->second->is_active() ? ACTIVE : BACKGROUND;
1054 }
1055
1001 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request, 1056 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request,
1002 net::RequestPriority new_priority, 1057 net::RequestPriority new_priority,
1003 int new_intra_priority_value) { 1058 int new_intra_priority_value) {
1004 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) { 1059 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) {
1005 // We should not be re-prioritizing requests with the 1060 // We should not be re-prioritizing requests with the
1006 // IGNORE_LIMITS flag. 1061 // IGNORE_LIMITS flag.
1007 NOTREACHED(); 1062 NOTREACHED();
1008 return; 1063 return;
1009 } 1064 }
1010 RequestPriorityParams new_priority_params(new_priority, 1065 RequestPriorityParams new_priority_params(new_priority,
(...skipping 16 matching lines...) Expand all
1027 1082
1028 Client *client = client_it->second; 1083 Client *client = client_it->second;
1029 client->ReprioritizeRequest( 1084 client->ReprioritizeRequest(
1030 request, old_priority_params, new_priority_params); 1085 request, old_priority_params, new_priority_params);
1031 } 1086 }
1032 1087
1033 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1088 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
1034 int child_id, int route_id) { 1089 int child_id, int route_id) {
1035 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1090 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
1036 } 1091 }
1037
1038 } // namespace content 1092 } // namespace content
mmenke 2014/11/03 19:01:19 nit: Blank line before end of namespace.
aiolos (Not reviewing) 2014/11/03 20:16:01 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698