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

Side by Side Diff: net/proxy/proxy_resolver_v8_tracing.cc

Issue 1944983002: Revert "Add a histogram (Net.PacResultForStrippedUrl) that estimates how often PAC scripts depend o… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 7 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
« no previous file with comments | « net/proxy/proxy_resolver_v8_tracing.h ('k') | net/proxy/proxy_resolver_v8_tracing_unittest.cc » ('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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "net/proxy/proxy_resolver_v8_tracing.h" 5 #include "net/proxy/proxy_resolver_v8_tracing.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/auto_reset.h"
13 #include "base/bind.h" 12 #include "base/bind.h"
14 #include "base/macros.h" 13 #include "base/macros.h"
15 #include "base/metrics/histogram_macros.h"
16 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
17 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
18 #include "base/synchronization/cancellation_flag.h" 16 #include "base/synchronization/cancellation_flag.h"
19 #include "base/synchronization/waitable_event.h" 17 #include "base/synchronization/waitable_event.h"
20 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
21 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
22 #include "base/threading/thread_restrictions.h" 20 #include "base/threading/thread_restrictions.h"
23 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
24 #include "net/base/address_list.h" 22 #include "net/base/address_list.h"
25 #include "net/base/net_errors.h" 23 #include "net/base/net_errors.h"
26 #include "net/base/network_interfaces.h" 24 #include "net/base/network_interfaces.h"
27 #include "net/dns/host_resolver.h" 25 #include "net/dns/host_resolver.h"
28 #include "net/proxy/proxy_info.h" 26 #include "net/proxy/proxy_info.h"
29 #include "net/proxy/proxy_resolver_error_observer.h" 27 #include "net/proxy/proxy_resolver_error_observer.h"
30 #include "net/proxy/proxy_resolver_v8.h" 28 #include "net/proxy/proxy_resolver_v8.h"
31 #include "url/url_canon.h"
32 29
33 // The intent of this class is explained in the design document: 30 // The intent of this class is explained in the design document:
34 // https://docs.google.com/a/chromium.org/document/d/16Ij5OcVnR3s0MH4Z5XkhI9VTPo MJdaBn9rKreAmGOdE/edit 31 // https://docs.google.com/a/chromium.org/document/d/16Ij5OcVnR3s0MH4Z5XkhI9VTPo MJdaBn9rKreAmGOdE/edit
35 // 32 //
36 // In a nutshell, PAC scripts are Javascript programs and may depend on 33 // In a nutshell, PAC scripts are Javascript programs and may depend on
37 // network I/O, by calling functions like dnsResolve(). 34 // network I/O, by calling functions like dnsResolve().
38 // 35 //
39 // This is problematic since functions such as dnsResolve() will block the 36 // This is problematic since functions such as dnsResolve() will block the
40 // Javascript execution until the DNS result is availble, thereby stalling the 37 // Javascript execution until the DNS result is availble, thereby stalling the
41 // PAC thread, which hurts the ability to process parallel proxy resolves. 38 // PAC thread, which hurts the ability to process parallel proxy resolves.
(...skipping 14 matching lines...) Expand all
56 // number of DNS resolves, as well as scripts which are misbehaving 53 // number of DNS resolves, as well as scripts which are misbehaving
57 // under the tracing optimization. It is not expected to hit this normally. 54 // under the tracing optimization. It is not expected to hit this normally.
58 const size_t kMaxUniqueResolveDnsPerExec = 20; 55 const size_t kMaxUniqueResolveDnsPerExec = 20;
59 56
60 // Approximate number of bytes to use for buffering alerts() and errors. 57 // Approximate number of bytes to use for buffering alerts() and errors.
61 // This is a failsafe in case repeated executions of the script causes 58 // This is a failsafe in case repeated executions of the script causes
62 // too much memory bloat. It is not expected for well behaved scripts to 59 // too much memory bloat. It is not expected for well behaved scripts to
63 // hit this. (In fact normal scripts should not even have alerts() or errors). 60 // hit this. (In fact normal scripts should not even have alerts() or errors).
64 const size_t kMaxAlertsAndErrorsBytes = 2048; 61 const size_t kMaxAlertsAndErrorsBytes = 2048;
65 62
66 // Strips path information from the URL and replaces it with a
67 // recognizable placeholder.
68 // TODO(eroman): Remove when done gathering data for crbug.com/593759
69 GURL StripUrlForBug593759(const GURL& url) {
70 GURL::Replacements replacements;
71 replacements.SetPathStr("PathIsHiddenForCrbug593759");
72 replacements.ClearQuery();
73 replacements.ClearRef();
74 return url.ReplaceComponents(replacements);
75 }
76
77 // TODO(eroman): Remove when done gathering data for crbug.com/593759
78 void LogHistogramForBug593759(PacResultForStrippedUrl value) {
79 UMA_HISTOGRAM_ENUMERATION(
80 kHistogramPacResultForStrippedUrl, static_cast<int>(value),
81 static_cast<int>(PacResultForStrippedUrl::MAX_VALUE));
82 }
83
84 // The Job class is responsible for executing GetProxyForURL() and 63 // The Job class is responsible for executing GetProxyForURL() and
85 // creating ProxyResolverV8 instances, since both of these operations share 64 // creating ProxyResolverV8 instances, since both of these operations share
86 // similar code. 65 // similar code.
87 // 66 //
88 // The DNS for these operations can operate in either blocking or 67 // The DNS for these operations can operate in either blocking or
89 // non-blocking mode. Blocking mode is used as a fallback when the PAC script 68 // non-blocking mode. Blocking mode is used as a fallback when the PAC script
90 // seems to be misbehaving under the tracing optimization. 69 // seems to be misbehaving under the tracing optimization.
91 // 70 //
92 // Note that this class runs on both the origin thread and a worker 71 // Note that this class runs on both the origin thread and a worker
93 // thread. Most methods are expected to be used exclusively on one thread 72 // thread. Most methods are expected to be used exclusively on one thread
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 void NotifyCaller(int result); 143 void NotifyCaller(int result);
165 void NotifyCallerOnOriginLoop(int result); 144 void NotifyCallerOnOriginLoop(int result);
166 145
167 void Start(Operation op, bool blocking_dns, 146 void Start(Operation op, bool blocking_dns,
168 const CompletionCallback& callback); 147 const CompletionCallback& callback);
169 148
170 void ExecuteBlocking(); 149 void ExecuteBlocking();
171 void ExecuteNonBlocking(); 150 void ExecuteNonBlocking();
172 int ExecuteProxyResolver(); 151 int ExecuteProxyResolver();
173 152
174 // TODO(eroman): Remove when done gathering data for crbug.com/593759
175 void LogMetricsForBug593759(int original_error);
176
177 // Implementation of ProxyResolverv8::JSBindings 153 // Implementation of ProxyResolverv8::JSBindings
178 bool ResolveDns(const std::string& host, 154 bool ResolveDns(const std::string& host,
179 ResolveDnsOperation op, 155 ResolveDnsOperation op,
180 std::string* output, 156 std::string* output,
181 bool* terminate) override; 157 bool* terminate) override;
182 void Alert(const base::string16& message) override; 158 void Alert(const base::string16& message) override;
183 void OnError(int line_number, const base::string16& error) override; 159 void OnError(int line_number, const base::string16& error) override;
184 160
185 bool ResolveDnsBlocking(const std::string& host, 161 bool ResolveDnsBlocking(const std::string& host,
186 ResolveDnsOperation op, 162 ResolveDnsOperation op,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // Sequence of calls made to Alert() or OnError() by this execution. 269 // Sequence of calls made to Alert() or OnError() by this execution.
294 std::vector<AlertOrError> alerts_and_errors_; 270 std::vector<AlertOrError> alerts_and_errors_;
295 size_t alerts_and_errors_byte_cost_; // Approximate byte cost of the above. 271 size_t alerts_and_errors_byte_cost_; // Approximate byte cost of the above.
296 272
297 // Number of calls made to ResolveDns() by the PREVIOUS execution. 273 // Number of calls made to ResolveDns() by the PREVIOUS execution.
298 int last_num_dns_; 274 int last_num_dns_;
299 275
300 // Whether the current execution needs to be restarted in blocking mode. 276 // Whether the current execution needs to be restarted in blocking mode.
301 bool should_restart_with_blocking_dns_; 277 bool should_restart_with_blocking_dns_;
302 278
303 // TODO(eroman): Remove when done gathering data for crbug.com/593759
304 bool dont_start_dns_ = false;
305
306 // --------------------------------------------------------------------------- 279 // ---------------------------------------------------------------------------
307 // State for pending DNS request. 280 // State for pending DNS request.
308 // --------------------------------------------------------------------------- 281 // ---------------------------------------------------------------------------
309 282
310 // Handle to the outstanding request in the HostResolver, or NULL. 283 // Handle to the outstanding request in the HostResolver, or NULL.
311 // This is mutated and used on the origin thread, however it may be read by 284 // This is mutated and used on the origin thread, however it may be read by
312 // the worker thread for some DCHECKS(). 285 // the worker thread for some DCHECKS().
313 HostResolver::RequestHandle pending_dns_; 286 HostResolver::RequestHandle pending_dns_;
314 287
315 // Indicates if the outstanding DNS request completed synchronously. Written 288 // Indicates if the outstanding DNS request completed synchronously. Written
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 527
555 // Reset state for the current execution. 528 // Reset state for the current execution.
556 abandoned_ = false; 529 abandoned_ = false;
557 num_dns_ = 0; 530 num_dns_ = 0;
558 alerts_and_errors_.clear(); 531 alerts_and_errors_.clear();
559 alerts_and_errors_byte_cost_ = 0; 532 alerts_and_errors_byte_cost_ = 0;
560 should_restart_with_blocking_dns_ = false; 533 should_restart_with_blocking_dns_ = false;
561 534
562 int result = ExecuteProxyResolver(); 535 int result = ExecuteProxyResolver();
563 536
564 // TODO(eroman): Remove when done gathering data for crbug.com/593759
565 LogMetricsForBug593759(result);
566
567 if (should_restart_with_blocking_dns_) { 537 if (should_restart_with_blocking_dns_) {
568 DCHECK(!blocking_dns_); 538 DCHECK(!blocking_dns_);
569 DCHECK(abandoned_); 539 DCHECK(abandoned_);
570 blocking_dns_ = true; 540 blocking_dns_ = true;
571 ExecuteBlocking(); 541 ExecuteBlocking();
572 return; 542 return;
573 } 543 }
574 544
575 if (abandoned_) 545 if (abandoned_)
576 return; 546 return;
(...skipping 20 matching lines...) Expand all
597 // request were to be cancelled from the origin thread, must guarantee 567 // request were to be cancelled from the origin thread, must guarantee
598 // that |user_results_| is not accessed anymore. 568 // that |user_results_| is not accessed anymore.
599 &results_, this); 569 &results_, this);
600 break; 570 break;
601 } 571 }
602 } 572 }
603 573
604 return result; 574 return result;
605 } 575 }
606 576
607 // Gathers data on how often PAC scripts execute differently depending
608 // on the URL path and parameters.
609 //
610 // TODO(eroman): Remove when done gathering data for crbug.com/593759
611 void Job::LogMetricsForBug593759(int original_error) {
612 CheckIsOnWorkerThread();
613
614 DCHECK(!blocking_dns_);
615
616 if (operation_ != GET_PROXY_FOR_URL || !url_.SchemeIsCryptographic()) {
617 // Only interested in FindProxyForURL() invocations for cryptographic URL
618 // schemes (https:// and wss://).
619 return;
620 }
621
622 if (should_restart_with_blocking_dns_) {
623 // The current instrumentation is limited to non-blocking DNS mode, for
624 // simplicity. Fallback to blocking mode is possible for unusual PAC
625 // scripts (non-deterministic, or relies on global state).
626 LogHistogramForBug593759(
627 PacResultForStrippedUrl::SKIPPED_FALLBACK_BLOCKING_DNS);
628 return;
629 }
630
631 if (abandoned_) {
632 // If the FindProxyForURL() attempt was abandoned, it was either cancelled
633 // or it encountered a missing DNS dependency. In the latter case the job
634 // will be re-started once the DNS has been resolved, so just wait until
635 // then.
636 return;
637 }
638
639 if (original_error != OK) {
640 // Only run the extra diagnostics for successful invocations of
641 // FindProxyForURL(). In other words, the instrumentation will
642 // not check whether the script succeeds when using a stripped
643 // path after having already failed on the original URL. A script error
644 // means the PAC script is already broken, so this would just skew the data.
645 return;
646 }
647
648 // Save some state variables to compare the original run against the new run
649 // using a stripped URL.
650 auto original_num_dns = num_dns_;
651 auto original_alerts_and_errors_byte_cost_ = alerts_and_errors_byte_cost_;
652 auto original_results = results_.ToPacString();
653
654 // Reset state variables used by ExecuteProxyResolver().
655 //
656 // This is a bit messy, but it keeps the diagnostics code local
657 // to LogMetricsForBug593759() without having to refactor the existing
658 // code.
659 //
660 // The intent is that after returning from this function all of the
661 // internal state is re-set to reflect the original completion of
662 // ExecuteProxyResolver(), not the second diagnostic one.
663 //
664 // Any global modifications made to the script state however are
665 // not undone, since creating a new script context just for this
666 // test would be expensive.
667 //
668 // Lastly, DNS resolution is disabled before calling
669 // ExecuteProxyResolver(), so only previously cached results can be
670 // used.
671 base::AutoReset<GURL> reset_url(&url_, StripUrlForBug593759(url_));
672 base::AutoReset<int> reset_num_dns(&num_dns_, 0);
673 base::AutoReset<std::vector<AlertOrError>> reset_alerts_and_errors(
674 &alerts_and_errors_, std::vector<AlertOrError>());
675 base::AutoReset<size_t> reset_alerts_and_errors_byte_cost(
676 &alerts_and_errors_byte_cost_, 0);
677 base::AutoReset<bool> reset_should_restart_with_blocking_dns(
678 &should_restart_with_blocking_dns_, false);
679 base::AutoReset<ProxyInfo> reset_results(&results_, ProxyInfo());
680 base::AutoReset<bool> reset_dont_start_dns(&dont_start_dns_, true);
681 base::AutoReset<bool> reset_abandoned(&abandoned_, false);
682
683 // Re-run FindProxyForURL().
684 auto result = ExecuteProxyResolver();
685
686 // Log the result of having run FindProxyForURL() with the modified
687 // URL to an UMA histogram.
688 if (should_restart_with_blocking_dns_) {
689 LogHistogramForBug593759(
690 PacResultForStrippedUrl::FAIL_FALLBACK_BLOCKING_DNS);
691 } else if (abandoned_) {
692 LogHistogramForBug593759(PacResultForStrippedUrl::FAIL_ABANDONED);
693 } else if (result != OK) {
694 LogHistogramForBug593759(PacResultForStrippedUrl::FAIL_ERROR);
695 } else if (original_results != results_.ToPacString()) {
696 LogHistogramForBug593759(
697 PacResultForStrippedUrl::FAIL_DIFFERENT_PROXY_LIST);
698 } else if (original_alerts_and_errors_byte_cost_ !=
699 alerts_and_errors_byte_cost_) {
700 // Here alerts_and_errors_byte_cost_ is being used as a cheap (albeit
701 // imprecise) fingerprint for the calls that were made to alert().
702 LogHistogramForBug593759(PacResultForStrippedUrl::SUCCESS_DIFFERENT_ALERTS);
703 } else if (original_num_dns != num_dns_) {
704 LogHistogramForBug593759(
705 PacResultForStrippedUrl::SUCCESS_DIFFERENT_NUM_DNS);
706 } else {
707 LogHistogramForBug593759(PacResultForStrippedUrl::SUCCESS);
708 }
709 }
710
711 bool Job::ResolveDns(const std::string& host, 577 bool Job::ResolveDns(const std::string& host,
712 ResolveDnsOperation op, 578 ResolveDnsOperation op,
713 std::string* output, 579 std::string* output,
714 bool* terminate) { 580 bool* terminate) {
715 if (cancelled_.IsSet()) { 581 if (cancelled_.IsSet()) {
716 *terminate = true; 582 *terminate = true;
717 return false; 583 return false;
718 } 584 }
719 585
720 if ((op == DNS_RESOLVE || op == DNS_RESOLVE_EX) && host.empty()) { 586 if ((op == DNS_RESOLVE || op == DNS_RESOLVE_EX) && host.empty()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 641
776 num_dns_ += 1; 642 num_dns_ += 1;
777 643
778 // Check if the DNS result for this host has already been cached. 644 // Check if the DNS result for this host has already been cached.
779 bool rv; 645 bool rv;
780 if (GetDnsFromLocalCache(host, op, output, &rv)) { 646 if (GetDnsFromLocalCache(host, op, output, &rv)) {
781 // Yay, cache hit! 647 // Yay, cache hit!
782 return rv; 648 return rv;
783 } 649 }
784 650
785 // TODO(eroman): Remove when done gathering data for crbug.com/593759
786 if (dont_start_dns_) {
787 abandoned_ = true;
788 return false;
789 }
790
791 if (num_dns_ <= last_num_dns_) { 651 if (num_dns_ <= last_num_dns_) {
792 // The sequence of DNS operations is different from last time! 652 // The sequence of DNS operations is different from last time!
793 ScheduleRestartWithBlockingDns(); 653 ScheduleRestartWithBlockingDns();
794 *terminate = true; 654 *terminate = true;
795 return false; 655 return false;
796 } 656 }
797 657
798 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { 658 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) {
799 // Safety net for scripts with unexpectedly many DNS calls. 659 // Safety net for scripts with unexpectedly many DNS calls.
800 return false; 660 return false;
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 } 1094 }
1235 1095
1236 } // namespace 1096 } // namespace
1237 1097
1238 // static 1098 // static
1239 scoped_ptr<ProxyResolverV8TracingFactory> 1099 scoped_ptr<ProxyResolverV8TracingFactory>
1240 ProxyResolverV8TracingFactory::Create() { 1100 ProxyResolverV8TracingFactory::Create() {
1241 return make_scoped_ptr(new ProxyResolverV8TracingFactoryImpl()); 1101 return make_scoped_ptr(new ProxyResolverV8TracingFactoryImpl());
1242 } 1102 }
1243 1103
1244 const char kHistogramPacResultForStrippedUrl[] = "Net.PacResultForStrippedUrl";
1245
1246 } // namespace net 1104 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/proxy_resolver_v8_tracing.h ('k') | net/proxy/proxy_resolver_v8_tracing_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698