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

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: Comments addressed. 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"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 PointerMap pointers_; 113 PointerMap pointers_;
112 }; 114 };
113 115
114 // This is the handle we return to the ResourceDispatcherHostImpl so it can 116 // This is the handle we return to the ResourceDispatcherHostImpl so it can
115 // interact with the request. 117 // interact with the request.
116 class ResourceScheduler::ScheduledResourceRequest 118 class ResourceScheduler::ScheduledResourceRequest
117 : public ResourceMessageDelegate, 119 : public ResourceMessageDelegate,
118 public ResourceThrottle { 120 public ResourceThrottle {
119 public: 121 public:
120 ScheduledResourceRequest(const ClientId& client_id, 122 ScheduledResourceRequest(const ClientId& client_id,
123 ResourceScheduler::ClientState client_state,
mmenke 2014/11/03 16:05:55 Optional nit: Suggest not taking this as an argum
aiolos (Not reviewing) 2014/11/03 17:50:25 Done.
121 net::URLRequest* request, 124 net::URLRequest* request,
122 ResourceScheduler* scheduler, 125 ResourceScheduler* scheduler,
123 const RequestPriorityParams& priority) 126 const RequestPriorityParams& priority)
124 : ResourceMessageDelegate(request), 127 : ResourceMessageDelegate(request),
125 client_id_(client_id), 128 client_id_(client_id),
129 client_state_on_creation_(client_state),
126 request_(request), 130 request_(request),
127 ready_(false), 131 ready_(false),
128 deferred_(false), 132 deferred_(false),
129 classification_(NORMAL_REQUEST), 133 classification_(NORMAL_REQUEST),
130 scheduler_(scheduler), 134 scheduler_(scheduler),
131 priority_(priority), 135 priority_(priority),
132 fifo_ordering_(0) { 136 fifo_ordering_(0) {
133 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_, 137 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_,
134 "url", request->url().spec()); 138 "url", request->url().spec());
135 } 139 }
136 140
137 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); } 141 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); }
138 142
139 void Start() { 143 void Start() {
140 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued"); 144 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued");
141 ready_ = true; 145 ready_ = true;
142 if (deferred_ && request_->status().is_success()) { 146 if (request_->status().is_success()) {
mmenke 2014/11/03 16:05:55 nit: Suggest making this an early return - early
aiolos (Not reviewing) 2014/11/03 17:50:26 Done.
143 deferred_ = false; 147 base::TimeTicks time = base::TimeTicks::Now();
144 controller()->Resume(); 148 ClientState current_state = scheduler_->GetClientState(client_id_);
149 const char* client_state =
150 current_state == UNKNOWN || current_state != client_state_on_creation_
151 ? "Other"
152 : current_state == ACTIVE ? "Active" : "Background";
mmenke 2014/11/03 16:05:54 Suggest a method or function for this, or splittin
aiolos (Not reviewing) 2014/11/03 17:50:25 Done.
153 if (deferred_) {
154 deferred_ = false;
155 controller()->Resume();
156 scheduler_->PostHistogram(
157 "RequestTimeDeferred", client_state, time - time_deferred_);
mmenke 2014/11/03 16:05:55 If !deferred_, we should be recording a 0, I belie
aiolos (Not reviewing) 2014/11/03 17:50:25 Done.
158 }
159 // TODO(aiolos): Remove one of these histograms after gaining an
160 // understanding of the difference between them and which one is more
161 // interesting.
162 scheduler_->PostHistogram("RequestTimeThrottled",
163 client_state,
164 time - request_->creation_time());
145 } 165 }
146 } 166 }
147 167
148 void set_request_priority_params(const RequestPriorityParams& priority) { 168 void set_request_priority_params(const RequestPriorityParams& priority) {
149 priority_ = priority; 169 priority_ = priority;
150 } 170 }
151 const RequestPriorityParams& get_request_priority_params() const { 171 const RequestPriorityParams& get_request_priority_params() const {
152 return priority_; 172 return priority_;
153 } 173 }
154 const ClientId& client_id() const { return client_id_; } 174 const ClientId& client_id() const { return client_id_; }
(...skipping 15 matching lines...) Expand all
170 bool OnMessageReceived(const IPC::Message& message) override { 190 bool OnMessageReceived(const IPC::Message& message) override {
171 bool handled = true; 191 bool handled = true;
172 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) 192 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message)
173 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) 193 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority)
174 IPC_MESSAGE_UNHANDLED(handled = false) 194 IPC_MESSAGE_UNHANDLED(handled = false)
175 IPC_END_MESSAGE_MAP() 195 IPC_END_MESSAGE_MAP()
176 return handled; 196 return handled;
177 } 197 }
178 198
179 // ResourceThrottle interface: 199 // ResourceThrottle interface:
180 void WillStartRequest(bool* defer) override { deferred_ = *defer = !ready_; } 200 void WillStartRequest(bool* defer) override {
201 deferred_ = *defer = !ready_;
202 time_deferred_ = base::TimeTicks::Now();
203 }
181 204
182 const char* GetNameForLogging() const override { return "ResourceScheduler"; } 205 const char* GetNameForLogging() const override { return "ResourceScheduler"; }
183 206
184 void DidChangePriority(int request_id, net::RequestPriority new_priority, 207 void DidChangePriority(int request_id, net::RequestPriority new_priority,
185 int intra_priority_value) { 208 int intra_priority_value) {
186 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); 209 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value);
187 } 210 }
188 211
189 ClientId client_id_; 212 ClientId client_id_;
213 ResourceScheduler::ClientState client_state_on_creation_;
190 net::URLRequest* request_; 214 net::URLRequest* request_;
191 bool ready_; 215 bool ready_;
192 bool deferred_; 216 bool deferred_;
193 RequestClassification classification_; 217 RequestClassification classification_;
194 ResourceScheduler* scheduler_; 218 ResourceScheduler* scheduler_;
195 RequestPriorityParams priority_; 219 RequestPriorityParams priority_;
196 uint32 fifo_ordering_; 220 uint32 fifo_ordering_;
221 base::TimeTicks time_deferred_;
197 222
198 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); 223 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
199 }; 224 };
200 225
201 bool ResourceScheduler::ScheduledResourceSorter::operator()( 226 bool ResourceScheduler::ScheduledResourceSorter::operator()(
202 const ScheduledResourceRequest* a, 227 const ScheduledResourceRequest* a,
203 const ScheduledResourceRequest* b) const { 228 const ScheduledResourceRequest* b) const {
204 // Want the set to be ordered first by decreasing priority, then by 229 // Want the set to be ordered first by decreasing priority, then by
205 // decreasing intra_priority. 230 // decreasing intra_priority.
206 // ie. with (priority, intra_priority) 231 // ie. with (priority, intra_priority)
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 DCHECK(client); 772 DCHECK(client);
748 return client->throttle_state(); 773 return client->throttle_state();
749 } 774 }
750 775
751 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( 776 scoped_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
752 int child_id, 777 int child_id,
753 int route_id, 778 int route_id,
754 net::URLRequest* url_request) { 779 net::URLRequest* url_request) {
755 DCHECK(CalledOnValidThread()); 780 DCHECK(CalledOnValidThread());
756 ClientId client_id = MakeClientId(child_id, route_id); 781 ClientId client_id = MakeClientId(child_id, route_id);
757 scoped_ptr<ScheduledResourceRequest> request( 782 scoped_ptr<ScheduledResourceRequest> request(new ScheduledResourceRequest(
758 new ScheduledResourceRequest(client_id, url_request, this, 783 client_id,
759 RequestPriorityParams(url_request->priority(), 0))); 784 GetClientState(client_id),
785 url_request,
786 this,
787 RequestPriorityParams(url_request->priority(), 0)));
760 788
761 ClientMap::iterator it = client_map_.find(client_id); 789 ClientMap::iterator it = client_map_.find(client_id);
762 if (it == client_map_.end()) { 790 if (it == client_map_.end()) {
763 // There are several ways this could happen: 791 // There are several ways this could happen:
764 // 1. <a ping> requests don't have a route_id. 792 // 1. <a ping> requests don't have a route_id.
765 // 2. Most unittests don't send the IPCs needed to register Clients. 793 // 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. 794 // 3. The tab is closed while a RequestResource IPC is in flight.
767 unowned_requests_.insert(request.get()); 795 unowned_requests_.insert(request.get());
768 request->Start(); 796 request->Start();
769 return request.Pass(); 797 return request.Pass();
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 void ResourceScheduler::LoadCoalescedRequests() { 1019 void ResourceScheduler::LoadCoalescedRequests() {
992 DCHECK(should_coalesce_); 1020 DCHECK(should_coalesce_);
993 ClientMap::iterator client_it = client_map_.begin(); 1021 ClientMap::iterator client_it = client_map_.begin();
994 while (client_it != client_map_.end()) { 1022 while (client_it != client_map_.end()) {
995 Client* client = client_it->second; 1023 Client* client = client_it->second;
996 client->LoadCoalescedRequests(); 1024 client->LoadCoalescedRequests();
997 ++client_it; 1025 ++client_it;
998 } 1026 }
999 } 1027 }
1000 1028
1029 ResourceScheduler::ClientState ResourceScheduler::GetClientState(
1030 ClientId client_id) const {
1031 ClientMap::const_iterator client_it = client_map_.find(client_id);
1032 if (client_it == client_map_.end())
1033 return UNKNOWN;
1034 return client_it->second->is_active() ? ACTIVE : BACKGROUND;
1035 }
1036
1001 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request, 1037 void ResourceScheduler::ReprioritizeRequest(ScheduledResourceRequest* request,
1002 net::RequestPriority new_priority, 1038 net::RequestPriority new_priority,
1003 int new_intra_priority_value) { 1039 int new_intra_priority_value) {
1004 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) { 1040 if (request->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS) {
1005 // We should not be re-prioritizing requests with the 1041 // We should not be re-prioritizing requests with the
1006 // IGNORE_LIMITS flag. 1042 // IGNORE_LIMITS flag.
1007 NOTREACHED(); 1043 NOTREACHED();
1008 return; 1044 return;
1009 } 1045 }
1010 RequestPriorityParams new_priority_params(new_priority, 1046 RequestPriorityParams new_priority_params(new_priority,
(...skipping 17 matching lines...) Expand all
1028 Client *client = client_it->second; 1064 Client *client = client_it->second;
1029 client->ReprioritizeRequest( 1065 client->ReprioritizeRequest(
1030 request, old_priority_params, new_priority_params); 1066 request, old_priority_params, new_priority_params);
1031 } 1067 }
1032 1068
1033 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1069 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
1034 int child_id, int route_id) { 1070 int child_id, int route_id) {
1035 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1071 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
1036 } 1072 }
1037 1073
1074 void ResourceScheduler::PostHistogram(const char* base_name,
mmenke 2014/11/03 16:05:55 This should be in an anonymous namespace up top.
aiolos (Not reviewing) 2014/11/03 17:50:26 Done.
1075 const char* suffix,
1076 base::TimeDelta time) {
1077 std::string histogram_name =
1078 base::StringPrintf("ResourceScheduler.%s_%s", base_name, suffix);
1079 base::HistogramBase* histogram_counter = base::Histogram::FactoryTimeGet(
1080 histogram_name,
1081 base::TimeDelta::FromMilliseconds(1),
1082 base::TimeDelta::FromMinutes(5),
1083 50,
1084 base::Histogram::kUmaTargetedHistogramFlag);
1085 histogram_counter->AddTime(time);
1086 }
1038 } // namespace content 1087 } // 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