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

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

Issue 2363743005: Remove code for max connection throttling; the experiment's complete. (Closed)
Patch Set: Merge to p420427. Created 4 years, 2 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 #include "content/browser/loader/resource_scheduler.h" 5 #include "content/browser/loader/resource_scheduler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/supports_user_data.h" 17 #include "base/supports_user_data.h"
20 #include "content/common/resource_messages.h" 18 #include "content/common/resource_messages.h"
21 #include "content/public/browser/resource_controller.h" 19 #include "content/public/browser/resource_controller.h"
22 #include "content/public/browser/resource_request_info.h" 20 #include "content/public/browser/resource_request_info.h"
23 #include "content/public/browser/resource_throttle.h" 21 #include "content/public/browser/resource_throttle.h"
24 #include "net/base/host_port_pair.h" 22 #include "net/base/host_port_pair.h"
25 #include "net/base/load_flags.h" 23 #include "net/base/load_flags.h"
26 #include "net/base/request_priority.h" 24 #include "net/base/request_priority.h"
27 #include "net/http/http_server_properties.h" 25 #include "net/http/http_server_properties.h"
28 #include "net/url_request/url_request.h" 26 #include "net/url_request/url_request.h"
29 #include "net/url_request/url_request_context.h" 27 #include "net/url_request/url_request_context.h"
30 #include "url/scheme_host_port.h" 28 #include "url/scheme_host_port.h"
31 29
32 namespace content { 30 namespace content {
33 31
34 namespace { 32 namespace {
35 33
36 enum StartMode { 34 enum StartMode {
37 START_SYNC, 35 START_SYNC,
38 START_ASYNC 36 START_ASYNC
39 }; 37 };
40 38
41 // Field trial constants
42 const char kRequestLimitFieldTrial[] = "OutstandingRequestLimiting";
43 const char kRequestLimitFieldTrialGroupPrefix[] = "Limit";
44
45 // Flags identifying various attributes of the request that are used 39 // Flags identifying various attributes of the request that are used
46 // when making scheduling decisions. 40 // when making scheduling decisions.
47 using RequestAttributes = uint8_t; 41 using RequestAttributes = uint8_t;
48 const RequestAttributes kAttributeNone = 0x00; 42 const RequestAttributes kAttributeNone = 0x00;
49 const RequestAttributes kAttributeInFlight = 0x01; 43 const RequestAttributes kAttributeInFlight = 0x01;
50 const RequestAttributes kAttributeDelayable = 0x02; 44 const RequestAttributes kAttributeDelayable = 0x02;
51 const RequestAttributes kAttributeLayoutBlocking = 0x04; 45 const RequestAttributes kAttributeLayoutBlocking = 0x04;
52 46
53 } // namespace 47 } // namespace
54 48
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 pointers_[request] = queue_.insert(request); 301 pointers_[request] = queue_.insert(request);
308 } 302 }
309 303
310 // Each client represents a tab. 304 // Each client represents a tab.
311 class ResourceScheduler::Client { 305 class ResourceScheduler::Client {
312 public: 306 public:
313 explicit Client(ResourceScheduler* scheduler) 307 explicit Client(ResourceScheduler* scheduler)
314 : is_loaded_(false), 308 : is_loaded_(false),
315 has_html_body_(false), 309 has_html_body_(false),
316 using_spdy_proxy_(false), 310 using_spdy_proxy_(false),
317 scheduler_(scheduler),
318 in_flight_delayable_count_(0), 311 in_flight_delayable_count_(0),
319 total_layout_blocking_count_(0) {} 312 total_layout_blocking_count_(0) {}
320 313
321 ~Client() {} 314 ~Client() {}
322 315
323 void ScheduleRequest(net::URLRequest* url_request, 316 void ScheduleRequest(net::URLRequest* url_request,
324 ScheduledResourceRequest* request) { 317 ScheduledResourceRequest* request) {
325 SetRequestAttributes(request, DetermineRequestAttributes(request)); 318 SetRequestAttributes(request, DetermineRequestAttributes(request));
326 if (ShouldStartRequest(request) == START_REQUEST) { 319 if (ShouldStartRequest(request) == START_REQUEST) {
327 // New requests can be started synchronously without issue. 320 // New requests can be started synchronously without issue.
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 // 563 //
571 // 4. Layout-blocking requests: 564 // 4. Layout-blocking requests:
572 // * High-priority requests (> net::LOW) initiated before the renderer has 565 // * High-priority requests (> net::LOW) initiated before the renderer has
573 // a <body>. 566 // a <body>.
574 // 567 //
575 // 5. Low priority requests 568 // 5. Low priority requests
576 // 569 //
577 // The following rules are followed: 570 // The following rules are followed:
578 // 571 //
579 // All types of requests: 572 // All types of requests:
580 // * If an outstanding request limit is in place, only that number
581 // of requests may be in flight for a single client at the same time.
582 // * Non-delayable, High-priority and request-priority capable requests are 573 // * Non-delayable, High-priority and request-priority capable requests are
583 // issued immediately. 574 // issued immediately.
584 // * Low priority requests are delayable. 575 // * Low priority requests are delayable.
585 // * While kInFlightNonDelayableRequestCountPerClientThreshold 576 // * While kInFlightNonDelayableRequestCountPerClientThreshold
586 // layout-blocking requests are loading or the body tag has not yet been 577 // layout-blocking requests are loading or the body tag has not yet been
587 // parsed, limit the number of delayable requests that may be in flight 578 // parsed, limit the number of delayable requests that may be in flight
588 // (to kMaxNumDelayableWhileLayoutBlockingPerClient by default, or to zero 579 // to kMaxNumDelayableWhileLayoutBlockingPerClient.
589 // if there's an outstanding request limit in place).
590 // * If no high priority or layout-blocking requests are in flight, start 580 // * If no high priority or layout-blocking requests are in flight, start
591 // loading delayable requests. 581 // loading delayable requests.
592 // * Never exceed 10 delayable requests in flight per client. 582 // * Never exceed 10 delayable requests in flight per client.
593 // * Never exceed 6 delayable requests for a given host. 583 // * Never exceed 6 delayable requests for a given host.
594 584
595 ShouldStartReqResult ShouldStartRequest( 585 ShouldStartReqResult ShouldStartRequest(
596 ScheduledResourceRequest* request) const { 586 ScheduledResourceRequest* request) const {
597 const net::URLRequest& url_request = *request->url_request(); 587 const net::URLRequest& url_request = *request->url_request();
598 // Syncronous requests could block the entire render, which could impact 588 // Syncronous requests could block the entire render, which could impact
599 // user-observable Clients. 589 // user-observable Clients.
600 if (!request->is_async()) 590 if (!request->is_async())
601 return START_REQUEST; 591 return START_REQUEST;
602 592
603 // TODO(simonjam): This may end up causing disk contention. We should 593 // TODO(simonjam): This may end up causing disk contention. We should
604 // experiment with throttling if that happens. 594 // experiment with throttling if that happens.
605 if (!url_request.url().SchemeIsHTTPOrHTTPS()) 595 if (!url_request.url().SchemeIsHTTPOrHTTPS())
606 return START_REQUEST; 596 return START_REQUEST;
607 597
608 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) 598 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme))
609 return START_REQUEST; 599 return START_REQUEST;
610 600
611 // Implementation of the kRequestLimitFieldTrial.
612 if (scheduler_->limit_outstanding_requests() &&
613 in_flight_requests_.size() >= scheduler_->outstanding_request_limit()) {
614 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
615 }
616
617 net::HostPortPair host_port_pair = 601 net::HostPortPair host_port_pair =
618 net::HostPortPair::FromURL(url_request.url()); 602 net::HostPortPair::FromURL(url_request.url());
619 url::SchemeHostPort scheme_host_port(url_request.url()); 603 url::SchemeHostPort scheme_host_port(url_request.url());
620 net::HttpServerProperties& http_server_properties = 604 net::HttpServerProperties& http_server_properties =
621 *url_request.context()->http_server_properties(); 605 *url_request.context()->http_server_properties();
622 606
623 // TODO(willchan): We should really improve this algorithm as described in 607 // TODO(willchan): We should really improve this algorithm as described in
624 // crbug.com/164101. Also, theoretically we should not count a 608 // crbug.com/164101. Also, theoretically we should not count a
625 // request-priority capable request against the delayable requests limit. 609 // request-priority capable request against the delayable requests limit.
626 if (http_server_properties.SupportsRequestPriority(scheme_host_port)) 610 if (http_server_properties.SupportsRequestPriority(scheme_host_port))
(...skipping 20 matching lines...) Expand all
647 if (!has_html_body_ || total_layout_blocking_count_ != 0) { 631 if (!has_html_body_ || total_layout_blocking_count_ != 0) {
648 size_t non_delayable_requests_in_flight_count = 632 size_t non_delayable_requests_in_flight_count =
649 in_flight_requests_.size() - in_flight_delayable_count_; 633 in_flight_requests_.size() - in_flight_delayable_count_;
650 if (non_delayable_requests_in_flight_count > 634 if (non_delayable_requests_in_flight_count >
651 kInFlightNonDelayableRequestCountPerClientThreshold) { 635 kInFlightNonDelayableRequestCountPerClientThreshold) {
652 // Too many higher priority in-flight requests to allow lower priority 636 // Too many higher priority in-flight requests to allow lower priority
653 // requests through. 637 // requests through.
654 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 638 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
655 } 639 }
656 if (in_flight_requests_.size() > 0 && 640 if (in_flight_requests_.size() > 0 &&
657 (scheduler_->limit_outstanding_requests() || 641 (in_flight_delayable_count_ >=
658 in_flight_delayable_count_ >=
659 kMaxNumDelayableWhileLayoutBlockingPerClient)) { 642 kMaxNumDelayableWhileLayoutBlockingPerClient)) {
660 // Block the request if at least one request is in flight and the 643 // Block the request if at least one request is in flight and the
661 // number of in-flight delayable requests has hit the configured 644 // number of in-flight delayable requests has hit the configured
662 // limit. 645 // limit.
663 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 646 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
664 } 647 }
665 } 648 }
666 649
667 return START_REQUEST; 650 return START_REQUEST;
668 } 651 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 } 687 }
705 } 688 }
706 689
707 bool is_loaded_; 690 bool is_loaded_;
708 // Tracks if the main HTML parser has reached the body which marks the end of 691 // Tracks if the main HTML parser has reached the body which marks the end of
709 // layout-blocking resources. 692 // layout-blocking resources.
710 bool has_html_body_; 693 bool has_html_body_;
711 bool using_spdy_proxy_; 694 bool using_spdy_proxy_;
712 RequestQueue pending_requests_; 695 RequestQueue pending_requests_;
713 RequestSet in_flight_requests_; 696 RequestSet in_flight_requests_;
714 ResourceScheduler* scheduler_;
715 // The number of delayable in-flight requests. 697 // The number of delayable in-flight requests.
716 size_t in_flight_delayable_count_; 698 size_t in_flight_delayable_count_;
717 // The number of layout-blocking in-flight requests. 699 // The number of layout-blocking in-flight requests.
718 size_t total_layout_blocking_count_; 700 size_t total_layout_blocking_count_;
719 }; 701 };
720 702
721 ResourceScheduler::ResourceScheduler() 703 ResourceScheduler::ResourceScheduler() {}
722 : limit_outstanding_requests_(false),
723 outstanding_request_limit_(0) {
724 std::string outstanding_limit_trial_group =
725 base::FieldTrialList::FindFullName(kRequestLimitFieldTrial);
726 std::vector<std::string> split_group(
727 base::SplitString(outstanding_limit_trial_group, "=",
728 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL));
729 int outstanding_limit = 0;
730 if (split_group.size() == 2 &&
731 split_group[0] == kRequestLimitFieldTrialGroupPrefix &&
732 base::StringToInt(split_group[1], &outstanding_limit) &&
733 outstanding_limit > 0) {
734 limit_outstanding_requests_ = true;
735 outstanding_request_limit_ = outstanding_limit;
736 }
737 }
738 704
739 ResourceScheduler::~ResourceScheduler() { 705 ResourceScheduler::~ResourceScheduler() {
740 DCHECK(unowned_requests_.empty()); 706 DCHECK(unowned_requests_.empty());
741 DCHECK(client_map_.empty()); 707 DCHECK(client_map_.empty());
742 } 708 }
743 709
744 std::unique_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest( 710 std::unique_ptr<ResourceThrottle> ResourceScheduler::ScheduleRequest(
745 int child_id, 711 int child_id,
746 int route_id, 712 int route_id,
747 bool is_async, 713 bool is_async,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 client->ReprioritizeRequest(scheduled_resource_request, old_priority_params, 889 client->ReprioritizeRequest(scheduled_resource_request, old_priority_params,
924 new_priority_params); 890 new_priority_params);
925 } 891 }
926 892
927 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 893 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
928 int child_id, int route_id) { 894 int child_id, int route_id) {
929 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 895 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
930 } 896 }
931 897
932 } // namespace content 898 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_scheduler.h ('k') | content/browser/loader/resource_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698