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

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

Issue 2951643003: Add UMA that periodically logs number of outstanding requests (Closed)
Patch Set: Created 3 years, 6 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
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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <stddef.h> 9 #include <stddef.h>
10 10
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 namespace content { 162 namespace content {
163 163
164 namespace { 164 namespace {
165 165
166 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; 166 static ResourceDispatcherHostImpl* g_resource_dispatcher_host;
167 167
168 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates 168 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates
169 const int kUpdateLoadStatesIntervalMsec = 250; 169 const int kUpdateLoadStatesIntervalMsec = 250;
170 170
171 // The interval for calls to RecordOutstandingRequestsStats.
172 const int kRecordOutstandingRequestsStatsIntervalMsec = 60000;
173
171 // Maximum byte "cost" of all the outstanding requests for a renderer. 174 // Maximum byte "cost" of all the outstanding requests for a renderer.
172 // See declaration of |max_outstanding_requests_cost_per_process_| for details. 175 // See declaration of |max_outstanding_requests_cost_per_process_| for details.
173 // This bound is 25MB, which allows for around 6000 outstanding requests. 176 // This bound is 25MB, which allows for around 6000 outstanding requests.
174 const int kMaxOutstandingRequestsCostPerProcess = 26214400; 177 const int kMaxOutstandingRequestsCostPerProcess = 26214400;
175 178
176 // The number of milliseconds after noting a user gesture that we will 179 // The number of milliseconds after noting a user gesture that we will
177 // tag newly-created URLRequest objects with the 180 // tag newly-created URLRequest objects with the
178 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary 181 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary
179 // guess at how long to expect direct impact from a user gesture, but 182 // guess at how long to expect direct impact from a user gesture, but
180 // this should be OK as the load flag is a best-effort thing only, 183 // this should be OK as the load flag is a best-effort thing only,
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 : request_id_(-1), 335 : request_id_(-1),
333 is_shutdown_(false), 336 is_shutdown_(false),
334 num_in_flight_requests_(0), 337 num_in_flight_requests_(0),
335 max_num_in_flight_requests_(base::SharedMemory::GetHandleLimit()), 338 max_num_in_flight_requests_(base::SharedMemory::GetHandleLimit()),
336 max_num_in_flight_requests_per_process_(static_cast<int>( 339 max_num_in_flight_requests_per_process_(static_cast<int>(
337 max_num_in_flight_requests_ * kMaxRequestsPerProcessRatio)), 340 max_num_in_flight_requests_ * kMaxRequestsPerProcessRatio)),
338 max_outstanding_requests_cost_per_process_( 341 max_outstanding_requests_cost_per_process_(
339 kMaxOutstandingRequestsCostPerProcess), 342 kMaxOutstandingRequestsCostPerProcess),
340 largest_outstanding_request_count_seen_(0), 343 largest_outstanding_request_count_seen_(0),
341 largest_outstanding_request_per_process_count_seen_(0), 344 largest_outstanding_request_per_process_count_seen_(0),
345 peak_outstanding_request_count_(0),
346 peak_outstanding_request_count_multitab_(0),
342 delegate_(nullptr), 347 delegate_(nullptr),
343 loader_delegate_(nullptr), 348 loader_delegate_(nullptr),
344 allow_cross_origin_auth_prompt_(false), 349 allow_cross_origin_auth_prompt_(false),
345 create_download_handler_intercept_(download_handler_intercept), 350 create_download_handler_intercept_(download_handler_intercept),
346 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), 351 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
347 io_thread_task_runner_(io_thread_runner), 352 io_thread_task_runner_(io_thread_runner),
348 experimental_web_features_enabled_( 353 experimental_web_features_enabled_(
349 base::CommandLine::ForCurrentProcess()->HasSwitch( 354 base::CommandLine::ForCurrentProcess()->HasSwitch(
350 switches::kEnableExperimentalWebPlatformFeatures)) { 355 switches::kEnableExperimentalWebPlatformFeatures)) {
351 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 356 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
352 DCHECK(!g_resource_dispatcher_host); 357 DCHECK(!g_resource_dispatcher_host);
353 g_resource_dispatcher_host = this; 358 g_resource_dispatcher_host = this;
354 359
355 ANNOTATE_BENIGN_RACE( 360 ANNOTATE_BENIGN_RACE(
356 &last_user_gesture_time_, 361 &last_user_gesture_time_,
357 "We don't care about the precise value, see http://crbug.com/92889"); 362 "We don't care about the precise value, see http://crbug.com/92889");
358 363
359 io_thread_task_runner_->PostTask( 364 io_thread_task_runner_->PostTask(
360 FROM_HERE, 365 FROM_HERE,
361 base::Bind(&ResourceDispatcherHostImpl::OnInit, base::Unretained(this))); 366 base::Bind(&ResourceDispatcherHostImpl::OnInit, base::Unretained(this)));
362 367
363 update_load_states_timer_.reset(new base::RepeatingTimer()); 368 update_load_states_timer_.reset(new base::RepeatingTimer());
369 record_outstanding_requests_stats_timer_.reset(new base::RepeatingTimer());
364 } 370 }
365 371
366 // The default ctor is only used by unittests. It is reasonable to assume that 372 // The default ctor is only used by unittests. It is reasonable to assume that
367 // the main thread and the IO thread are the same for unittests. 373 // the main thread and the IO thread are the same for unittests.
368 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() 374 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
369 : ResourceDispatcherHostImpl(CreateDownloadHandlerIntercept(), 375 : ResourceDispatcherHostImpl(CreateDownloadHandlerIntercept(),
370 base::ThreadTaskRunnerHandle::Get()) {} 376 base::ThreadTaskRunnerHandle::Get()) {}
371 377
372 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { 378 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
373 DCHECK(outstanding_requests_stats_map_.empty()); 379 DCHECK(outstanding_requests_stats_map_.empty());
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 588
583 const net::URLRequestJobFactory* job_factory = 589 const net::URLRequestJobFactory* job_factory =
584 info->GetContext()->GetRequestContext()->job_factory(); 590 info->GetContext()->GetRequestContext()->job_factory();
585 if (!url.is_valid() || job_factory->IsHandledProtocol(url.scheme())) 591 if (!url.is_valid() || job_factory->IsHandledProtocol(url.scheme()))
586 return false; 592 return false;
587 593
588 return delegate_->HandleExternalProtocol(url, info); 594 return delegate_->HandleExternalProtocol(url, info);
589 } 595 }
590 596
591 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { 597 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) {
592 // Make sure we have the load state monitor running. 598 // Make sure we have the load state monitors running.
593 if (!update_load_states_timer_->IsRunning() && 599 if (!update_load_states_timer_->IsRunning() &&
594 scheduler_->HasLoadingClients()) { 600 scheduler_->HasLoadingClients()) {
595 update_load_states_timer_->Start( 601 update_load_states_timer_->Start(
596 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), 602 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec),
597 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); 603 this, &ResourceDispatcherHostImpl::UpdateLoadInfo);
598 } 604 }
605 if (!record_outstanding_requests_stats_timer_->IsRunning()) {
606 record_outstanding_requests_stats_timer_->Start(
607 FROM_HERE,
608 TimeDelta::FromMilliseconds(
609 kRecordOutstandingRequestsStatsIntervalMsec),
610 this, &ResourceDispatcherHostImpl::RecordOutstandingRequestsStats);
611 }
599 } 612 }
600 613
601 void ResourceDispatcherHostImpl::DidReceiveRedirect( 614 void ResourceDispatcherHostImpl::DidReceiveRedirect(
602 ResourceLoader* loader, 615 ResourceLoader* loader,
603 const GURL& new_url, 616 const GURL& new_url,
604 ResourceResponse* response) { 617 ResourceResponse* response) {
605 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 618 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
606 if (delegate_) { 619 if (delegate_) {
607 delegate_->OnRequestRedirected( 620 delegate_->OnRequestRedirected(
608 new_url, loader->request(), info->GetContext(), response); 621 new_url, loader->request(), info->GetContext(), response);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 void ResourceDispatcherHostImpl::OnInit() { 790 void ResourceDispatcherHostImpl::OnInit() {
778 scheduler_.reset(new ResourceScheduler); 791 scheduler_.reset(new ResourceScheduler);
779 } 792 }
780 793
781 void ResourceDispatcherHostImpl::OnShutdown() { 794 void ResourceDispatcherHostImpl::OnShutdown() {
782 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); 795 DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
783 796
784 is_shutdown_ = true; 797 is_shutdown_ = true;
785 pending_loaders_.clear(); 798 pending_loaders_.clear();
786 799
787 // Make sure we shutdown the timer now, otherwise by the time our destructor 800 // Make sure we shutdown the timers now, otherwise by the time our destructor
788 // runs if the timer is still running the Task is deleted twice (once by 801 // runs if the timer is still running the Task is deleted twice (once by
789 // the MessageLoop and the second time by RepeatingTimer). 802 // the MessageLoop and the second time by RepeatingTimer).
790 update_load_states_timer_.reset(); 803 update_load_states_timer_.reset();
804 record_outstanding_requests_stats_timer_.reset();
791 805
792 // Clear blocked requests if any left. 806 // Clear blocked requests if any left.
793 // Note that we have to do this in 2 passes as we cannot call 807 // Note that we have to do this in 2 passes as we cannot call
794 // CancelBlockedRequestsForRoute while iterating over 808 // CancelBlockedRequestsForRoute while iterating over
795 // blocked_loaders_map_, as it modifies it. 809 // blocked_loaders_map_, as it modifies it.
796 std::set<GlobalFrameRoutingId> ids; 810 std::set<GlobalFrameRoutingId> ids;
797 for (const auto& blocked_loaders : blocked_loaders_map_) { 811 for (const auto& blocked_loaders : blocked_loaders_map_) {
798 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result = 812 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result =
799 ids.insert(blocked_loaders.first); 813 ids.insert(blocked_loaders.first);
800 // We should not have duplicates. 814 // We should not have duplicates.
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 } 1976 }
1963 1977
1964 if (stats.num_requests > 1978 if (stats.num_requests >
1965 largest_outstanding_request_per_process_count_seen_) { 1979 largest_outstanding_request_per_process_count_seen_) {
1966 largest_outstanding_request_per_process_count_seen_ = stats.num_requests; 1980 largest_outstanding_request_per_process_count_seen_ = stats.num_requests;
1967 UMA_HISTOGRAM_COUNTS_1M( 1981 UMA_HISTOGRAM_COUNTS_1M(
1968 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess", 1982 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess",
1969 largest_outstanding_request_per_process_count_seen_); 1983 largest_outstanding_request_per_process_count_seen_);
1970 } 1984 }
1971 1985
1986 if (num_in_flight_requests_ > peak_outstanding_request_count_) {
1987 peak_outstanding_request_count_ = num_in_flight_requests_;
1988 }
1989
1990 if (outstanding_requests_stats_map_.size() >= 2 &&
Takashi Toyoshima 2017/06/20 07:39:21 This will report if there is one background tab th
Kunihiko Sakamoto 2017/06/20 08:39:28 Done.
1991 num_in_flight_requests_ > peak_outstanding_request_count_multitab_) {
1992 peak_outstanding_request_count_multitab_ = num_in_flight_requests_;
1993 }
1994
1972 return stats; 1995 return stats;
1973 } 1996 }
1974 1997
1975 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest( 1998 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest(
1976 net::URLRequest* request) { 1999 net::URLRequest* request) {
1977 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 2000 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
1978 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info); 2001 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info);
1979 2002
1980 if (stats.num_requests > max_num_in_flight_requests_per_process_) 2003 if (stats.num_requests > max_num_in_flight_requests_per_process_)
1981 return false; 2004 return false;
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 // We need to be able to compare all requests to find the most important one 2513 // We need to be able to compare all requests to find the most important one
2491 // per tab. Since some requests may be navigation requests and we don't have 2514 // per tab. Since some requests may be navigation requests and we don't have
2492 // their render frame routing IDs yet (which is what we have for subresource 2515 // their render frame routing IDs yet (which is what we have for subresource
2493 // requests), we must go to the UI thread and compare the requests using their 2516 // requests), we must go to the UI thread and compare the requests using their
2494 // WebContents. 2517 // WebContents.
2495 main_thread_task_runner_->PostTask( 2518 main_thread_task_runner_->PostTask(
2496 FROM_HERE, 2519 FROM_HERE,
2497 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); 2520 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos)));
2498 } 2521 }
2499 2522
2523 void ResourceDispatcherHostImpl::RecordOutstandingRequestsStats() {
2524 if (peak_outstanding_request_count_ != 0) {
2525 UMA_HISTOGRAM_COUNTS_1M(
2526 "Net.ResourceDispatcherHost.PeakOutstandingRequests",
2527 peak_outstanding_request_count_);
2528 peak_outstanding_request_count_ = 0;
Takashi Toyoshima 2017/06/20 07:39:21 this will not report at the next time if there are
Kunihiko Sakamoto 2017/06/20 08:39:28 Good catch, thanks! Done.
2529 }
2530
2531 if (peak_outstanding_request_count_multitab_ != 0) {
2532 UMA_HISTOGRAM_COUNTS_1M(
2533 "Net.ResourceDispatcherHost.PeakOutstandingRequests.MultiTabLoading",
2534 peak_outstanding_request_count_multitab_);
2535 peak_outstanding_request_count_multitab_ = 0;
2536 }
2537 }
2538
2500 void ResourceDispatcherHostImpl::BlockRequestsForRoute( 2539 void ResourceDispatcherHostImpl::BlockRequestsForRoute(
2501 const GlobalFrameRoutingId& global_routing_id) { 2540 const GlobalFrameRoutingId& global_routing_id) {
2502 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); 2541 DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
2503 DCHECK(blocked_loaders_map_.find(global_routing_id) == 2542 DCHECK(blocked_loaders_map_.find(global_routing_id) ==
2504 blocked_loaders_map_.end()) 2543 blocked_loaders_map_.end())
2505 << "BlockRequestsForRoute called multiple time for the same RFH"; 2544 << "BlockRequestsForRoute called multiple time for the same RFH";
2506 blocked_loaders_map_[global_routing_id] = 2545 blocked_loaders_map_[global_routing_id] =
2507 base::MakeUnique<BlockedLoadersList>(); 2546 base::MakeUnique<BlockedLoadersList>();
2508 } 2547 }
2509 2548
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 &throttles); 2739 &throttles);
2701 if (!throttles.empty()) { 2740 if (!throttles.empty()) {
2702 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, 2741 handler.reset(new ThrottlingResourceHandler(std::move(handler), request,
2703 std::move(throttles))); 2742 std::move(throttles)));
2704 } 2743 }
2705 } 2744 }
2706 return handler; 2745 return handler;
2707 } 2746 }
2708 2747
2709 } // namespace content 2748 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698