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

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: Ilya nits. 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
« no previous file with comments | « content/browser/loader/resource_scheduler.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
44 } // namespace
45
26 static const size_t kCoalescedTimerPeriod = 5000; 46 static const size_t kCoalescedTimerPeriod = 5000;
27 static const size_t kMaxNumDelayableRequestsPerClient = 10; 47 static const size_t kMaxNumDelayableRequestsPerClient = 10;
28 static const size_t kMaxNumDelayableRequestsPerHost = 6; 48 static const size_t kMaxNumDelayableRequestsPerHost = 6;
29 static const size_t kMaxNumThrottledRequestsPerClient = 1; 49 static const size_t kMaxNumThrottledRequestsPerClient = 1;
30 50
31 struct ResourceScheduler::RequestPriorityParams { 51 struct ResourceScheduler::RequestPriorityParams {
32 RequestPriorityParams() 52 RequestPriorityParams()
33 : priority(net::DEFAULT_PRIORITY), 53 : priority(net::DEFAULT_PRIORITY),
34 intra_priority(0) { 54 intra_priority(0) {
35 } 55 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 class ResourceScheduler::ScheduledResourceRequest 136 class ResourceScheduler::ScheduledResourceRequest
117 : public ResourceMessageDelegate, 137 : public ResourceMessageDelegate,
118 public ResourceThrottle { 138 public ResourceThrottle {
119 public: 139 public:
120 ScheduledResourceRequest(const ClientId& client_id, 140 ScheduledResourceRequest(const ClientId& client_id,
121 net::URLRequest* request, 141 net::URLRequest* request,
122 ResourceScheduler* scheduler, 142 ResourceScheduler* scheduler,
123 const RequestPriorityParams& priority) 143 const RequestPriorityParams& priority)
124 : ResourceMessageDelegate(request), 144 : ResourceMessageDelegate(request),
125 client_id_(client_id), 145 client_id_(client_id),
146 client_state_on_creation_(scheduler->GetClientState(client_id_)),
126 request_(request), 147 request_(request),
127 ready_(false), 148 ready_(false),
128 deferred_(false), 149 deferred_(false),
129 classification_(NORMAL_REQUEST), 150 classification_(NORMAL_REQUEST),
130 scheduler_(scheduler), 151 scheduler_(scheduler),
131 priority_(priority), 152 priority_(priority),
132 fifo_ordering_(0) { 153 fifo_ordering_(0) {
133 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_, 154 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_,
134 "url", request->url().spec()); 155 "url", request->url().spec());
135 } 156 }
136 157
137 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); } 158 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); }
138 159
139 void Start() { 160 void Start() {
140 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued"); 161 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued");
141 ready_ = true; 162 ready_ = true;
142 if (deferred_ && request_->status().is_success()) { 163 if (!request_->status().is_success())
164 return;
165 base::TimeTicks time = base::TimeTicks::Now();
166 ClientState current_state = scheduler_->GetClientState(client_id_);
167 // Note: the client state isn't perfectly accurate since it won't capture
168 // tabs which have switched between active and background multiple times.
169 // Ex: A tab with the following transitions Active -> Background -> Active
170 // will be recorded as Active.
171 const char* client_state = "Other";
172 if (current_state == client_state_on_creation_ && current_state == ACTIVE) {
173 client_state = "Active";
174 } else if (current_state == client_state_on_creation_ &&
175 current_state == BACKGROUND) {
176 client_state = "Background";
177 }
178
179 base::TimeDelta time_was_deferred = base::TimeDelta::FromMicroseconds(0);
180 if (deferred_) {
143 deferred_ = false; 181 deferred_ = false;
144 controller()->Resume(); 182 controller()->Resume();
183 time_was_deferred = time - time_deferred_;
145 } 184 }
185 PostHistogram("RequestTimeDeferred", client_state, time_was_deferred);
186 PostHistogram(
187 "RequestTimeThrottled", client_state, time - request_->creation_time());
188 // TODO(aiolos): Remove one of the above histograms after gaining an
189 // understanding of the difference between them and which one is more
190 // interesting.
146 } 191 }
147 192
148 void set_request_priority_params(const RequestPriorityParams& priority) { 193 void set_request_priority_params(const RequestPriorityParams& priority) {
149 priority_ = priority; 194 priority_ = priority;
150 } 195 }
151 const RequestPriorityParams& get_request_priority_params() const { 196 const RequestPriorityParams& get_request_priority_params() const {
152 return priority_; 197 return priority_;
153 } 198 }
154 const ClientId& client_id() const { return client_id_; } 199 const ClientId& client_id() const { return client_id_; }
155 net::URLRequest* url_request() { return request_; } 200 net::URLRequest* url_request() { return request_; }
(...skipping 14 matching lines...) Expand all
170 bool OnMessageReceived(const IPC::Message& message) override { 215 bool OnMessageReceived(const IPC::Message& message) override {
171 bool handled = true; 216 bool handled = true;
172 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) 217 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message)
173 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) 218 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority)
174 IPC_MESSAGE_UNHANDLED(handled = false) 219 IPC_MESSAGE_UNHANDLED(handled = false)
175 IPC_END_MESSAGE_MAP() 220 IPC_END_MESSAGE_MAP()
176 return handled; 221 return handled;
177 } 222 }
178 223
179 // ResourceThrottle interface: 224 // ResourceThrottle interface:
180 void WillStartRequest(bool* defer) override { deferred_ = *defer = !ready_; } 225 void WillStartRequest(bool* defer) override {
226 deferred_ = *defer = !ready_;
227 time_deferred_ = base::TimeTicks::Now();
228 }
181 229
182 const char* GetNameForLogging() const override { return "ResourceScheduler"; } 230 const char* GetNameForLogging() const override { return "ResourceScheduler"; }
183 231
184 void DidChangePriority(int request_id, net::RequestPriority new_priority, 232 void DidChangePriority(int request_id, net::RequestPriority new_priority,
185 int intra_priority_value) { 233 int intra_priority_value) {
186 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); 234 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value);
187 } 235 }
188 236
189 ClientId client_id_; 237 const ClientId client_id_;
238 const ResourceScheduler::ClientState client_state_on_creation_;
190 net::URLRequest* request_; 239 net::URLRequest* request_;
191 bool ready_; 240 bool ready_;
192 bool deferred_; 241 bool deferred_;
193 RequestClassification classification_; 242 RequestClassification classification_;
194 ResourceScheduler* scheduler_; 243 ResourceScheduler* scheduler_;
195 RequestPriorityParams priority_; 244 RequestPriorityParams priority_;
196 uint32 fifo_ordering_; 245 uint32 fifo_ordering_;
246 base::TimeTicks time_deferred_;
197 247
198 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); 248 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
199 }; 249 };
200 250
201 bool ResourceScheduler::ScheduledResourceSorter::operator()( 251 bool ResourceScheduler::ScheduledResourceSorter::operator()(
202 const ScheduledResourceRequest* a, 252 const ScheduledResourceRequest* a,
203 const ScheduledResourceRequest* b) const { 253 const ScheduledResourceRequest* b) const {
204 // Want the set to be ordered first by decreasing priority, then by 254 // Want the set to be ordered first by decreasing priority, then by
205 // decreasing intra_priority. 255 // decreasing intra_priority.
206 // ie. with (priority, intra_priority) 256 // ie. with (priority, intra_priority)
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 DCHECK(client); 797 DCHECK(client);
748 return client->throttle_state(); 798 return client->throttle_state();
749 } 799 }
750 800
751 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( 801 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
752 int child_id, 802 int child_id,
753 int route_id, 803 int route_id,
754 net::URLRequest* url_request) { 804 net::URLRequest* url_request) {
755 DCHECK(CalledOnValidThread()); 805 DCHECK(CalledOnValidThread());
756 ClientId client_id = MakeClientId(child_id, route_id); 806 ClientId client_id = MakeClientId(child_id, route_id);
757 scoped_ptr<ScheduledResourceRequest> request( 807 scoped_ptr<ScheduledResourceRequest> request(new ScheduledResourceRequest(
758 new ScheduledResourceRequest(client_id, url_request, this, 808 client_id,
759 RequestPriorityParams(url_request->priority(), 0))); 809 url_request,
810 this,
811 RequestPriorityParams(url_request->priority(), 0)));
760 812
761 ClientMap::iterator it = client_map_.find(client_id); 813 ClientMap::iterator it = client_map_.find(client_id);
762 if (it == client_map_.end()) { 814 if (it == client_map_.end()) {
763 // There are several ways this could happen: 815 // There are several ways this could happen:
764 // 1. <a ping> requests don't have a route_id. 816 // 1. <a ping> requests don't have a route_id.
765 // 2. Most unittests don't send the IPCs needed to register Clients. 817 // 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. 818 // 3. The tab is closed while a RequestResource IPC is in flight.
767 unowned_requests_.insert(request.get()); 819 unowned_requests_.insert(request.get());
768 request->Start(); 820 request->Start();
769 return request.Pass(); 821 return request.Pass();
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 void ResourceScheduler::LoadCoalescedRequests() { 1043 void ResourceScheduler::LoadCoalescedRequests() {
992 DCHECK(should_coalesce_); 1044 DCHECK(should_coalesce_);
993 ClientMap::iterator client_it = client_map_.begin(); 1045 ClientMap::iterator client_it = client_map_.begin();
994 while (client_it != client_map_.end()) { 1046 while (client_it != client_map_.end()) {
995 Client* client = client_it->second; 1047 Client* client = client_it->second;
996 client->LoadCoalescedRequests(); 1048 client->LoadCoalescedRequests();
997 ++client_it; 1049 ++client_it;
998 } 1050 }
999 } 1051 }
1000 1052
1053 ResourceScheduler::ClientState ResourceScheduler::GetClientState(
1054 ClientId client_id) const {
1055 ClientMap::const_iterator client_it = client_map_.find(client_id);
1056 if (client_it == client_map_.end())
1057 return UNKNOWN;
1058 return client_it->second->is_active() ? ACTIVE : BACKGROUND;
1059 }
1060
1001 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request, 1061 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request,
1002 net::RequestPriority new_priority, 1062 net::RequestPriority new_priority,
1003 int new_intra_priority_value) { 1063 int new_intra_priority_value) {
1004 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) { 1064 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) {
1005 // We should not be re-prioritizing requests with the 1065 // We should not be re-prioritizing requests with the
1006 // IGNORE_LIMITS flag. 1066 // IGNORE_LIMITS flag.
1007 NOTREACHED(); 1067 NOTREACHED();
1008 return; 1068 return;
1009 } 1069 }
1010 RequestPriorityParams new_priority_params(new_priority, 1070 RequestPriorityParams new_priority_params(new_priority,
(...skipping 18 matching lines...) Expand all
1029 client->ReprioritizeRequest( 1089 client->ReprioritizeRequest(
1030 request, old_priority_params, new_priority_params); 1090 request, old_priority_params, new_priority_params);
1031 } 1091 }
1032 1092
1033 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1093 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
1034 int child_id, int route_id) { 1094 int child_id, int route_id) {
1035 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1095 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
1036 } 1096 }
1037 1097
1038 } // namespace content 1098 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_scheduler.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698