OLD | NEW |
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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
9 #include "base/metrics/histogram.h" | |
10 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
11 #include "base/synchronization/cancellation_flag.h" | 10 #include "base/synchronization/cancellation_flag.h" |
12 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
13 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
14 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
15 #include "base/values.h" | 14 #include "base/values.h" |
16 #include "net/base/address_list.h" | 15 #include "net/base/address_list.h" |
17 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
18 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" |
19 #include "net/dns/host_resolver.h" | 18 #include "net/dns/host_resolver.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // Returns event parameters for a PAC error message (line number + message). | 56 // Returns event parameters for a PAC error message (line number + message). |
58 base::Value* NetLogErrorCallback(int line_number, | 57 base::Value* NetLogErrorCallback(int line_number, |
59 const base::string16* message, | 58 const base::string16* message, |
60 NetLog::LogLevel /* log_level */) { | 59 NetLog::LogLevel /* log_level */) { |
61 base::DictionaryValue* dict = new base::DictionaryValue(); | 60 base::DictionaryValue* dict = new base::DictionaryValue(); |
62 dict->SetInteger("line_number", line_number); | 61 dict->SetInteger("line_number", line_number); |
63 dict->SetString("message", *message); | 62 dict->SetString("message", *message); |
64 return dict; | 63 return dict; |
65 } | 64 } |
66 | 65 |
67 void IncrementWithoutOverflow(uint8* x) { | |
68 if (*x != 0xFF) | |
69 *x += 1; | |
70 } | |
71 | |
72 } // namespace | 66 } // namespace |
73 | 67 |
74 // The Job class is responsible for executing GetProxyForURL() and | 68 // The Job class is responsible for executing GetProxyForURL() and |
75 // SetPacScript(), since both of these operations share similar code. | 69 // SetPacScript(), since both of these operations share similar code. |
76 // | 70 // |
77 // The DNS for these operations can operate in either blocking or | 71 // The DNS for these operations can operate in either blocking or |
78 // non-blocking mode. Blocking mode is used as a fallback when the PAC script | 72 // non-blocking mode. Blocking mode is used as a fallback when the PAC script |
79 // seems to be misbehaving under the tracing optimization. | 73 // seems to be misbehaving under the tracing optimization. |
80 // | 74 // |
81 // Note that this class runs on both the origin thread and a worker | 75 // Note that this class runs on both the origin thread and a worker |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 ProxyResolverV8* v8_resolver(); | 130 ProxyResolverV8* v8_resolver(); |
137 base::MessageLoop* worker_loop(); | 131 base::MessageLoop* worker_loop(); |
138 HostResolver* host_resolver(); | 132 HostResolver* host_resolver(); |
139 ProxyResolverErrorObserver* error_observer(); | 133 ProxyResolverErrorObserver* error_observer(); |
140 NetLog* net_log(); | 134 NetLog* net_log(); |
141 | 135 |
142 // Invokes the user's callback. | 136 // Invokes the user's callback. |
143 void NotifyCaller(int result); | 137 void NotifyCaller(int result); |
144 void NotifyCallerOnOriginLoop(int result); | 138 void NotifyCallerOnOriginLoop(int result); |
145 | 139 |
146 void RecordMetrics() const; | |
147 | |
148 void Start(Operation op, bool blocking_dns, | 140 void Start(Operation op, bool blocking_dns, |
149 const CompletionCallback& callback); | 141 const CompletionCallback& callback); |
150 | 142 |
151 void ExecuteBlocking(); | 143 void ExecuteBlocking(); |
152 void ExecuteNonBlocking(); | 144 void ExecuteNonBlocking(); |
153 int ExecuteProxyResolver(); | 145 int ExecuteProxyResolver(); |
154 | 146 |
155 // Implementation of ProxyResolverv8::JSBindings | 147 // Implementation of ProxyResolverv8::JSBindings |
156 virtual bool ResolveDns(const std::string& host, | 148 virtual bool ResolveDns(const std::string& host, |
157 ResolveDnsOperation op, | 149 ResolveDnsOperation op, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 bool pending_dns_completed_synchronously_; | 283 bool pending_dns_completed_synchronously_; |
292 | 284 |
293 // These are the inputs to DoDnsOperation(). Written on the worker thread, | 285 // These are the inputs to DoDnsOperation(). Written on the worker thread, |
294 // read by the origin thread. | 286 // read by the origin thread. |
295 std::string pending_dns_host_; | 287 std::string pending_dns_host_; |
296 ResolveDnsOperation pending_dns_op_; | 288 ResolveDnsOperation pending_dns_op_; |
297 | 289 |
298 // This contains the resolved address list that DoDnsOperation() fills in. | 290 // This contains the resolved address list that DoDnsOperation() fills in. |
299 // Used exclusively on the origin thread. | 291 // Used exclusively on the origin thread. |
300 AddressList pending_dns_addresses_; | 292 AddressList pending_dns_addresses_; |
301 | |
302 // --------------------------------------------------------------------------- | |
303 // Metrics for histograms | |
304 // --------------------------------------------------------------------------- | |
305 // These values are used solely for logging histograms. They do not affect | |
306 // the execution flow of requests. | |
307 | |
308 // The time when the proxy resolve request started. Used exclusively on the | |
309 // origin thread. | |
310 base::TimeTicks metrics_start_time_; | |
311 | |
312 // The time when the proxy resolve request completes on the worker thread. | |
313 // Written on the worker thread, read on the origin thread. | |
314 base::TimeTicks metrics_end_time_; | |
315 | |
316 // The time when PostDnsOperationAndWait() was called. Written on the worker | |
317 // thread, read by the origin thread. | |
318 base::TimeTicks metrics_pending_dns_start_; | |
319 | |
320 // The total amount of time that has been spent by the script waiting for | |
321 // DNS dependencies. This includes the time spent posting the task to | |
322 // the origin thread, up until the DNS result is found on the origin | |
323 // thread. It does not include any time spent waiting in the message loop | |
324 // for the worker thread, nor any time restarting or executing the | |
325 // script. Used exclusively on the origin thread. | |
326 base::TimeDelta metrics_dns_total_time_; | |
327 | |
328 // The following variables are initialized on the origin thread, | |
329 // incremented on the worker thread, and then read upon completion on the | |
330 // origin thread. The values are not expected to exceed the range of a uint8. | |
331 // If they do, then they will be clamped to 0xFF. | |
332 uint8 metrics_num_executions_; | |
333 uint8 metrics_num_unique_dns_; | |
334 uint8 metrics_num_alerts_; | |
335 uint8 metrics_num_errors_; | |
336 | |
337 // The time that the latest execution took (time spent inside of | |
338 // ExecuteProxyResolver(), which includes time spent in bindings too). | |
339 // Written on the worker thread, read on the origin thread. | |
340 base::TimeDelta metrics_execution_time_; | |
341 | |
342 // The cumulative time spent in ExecuteProxyResolver() that was ultimately | |
343 // discarded work. | |
344 // Written on the worker thread, read on the origin thread. | |
345 base::TimeDelta metrics_abandoned_execution_total_time_; | |
346 | |
347 // The duration that the worker thread was blocked waiting on DNS results from | |
348 // the origin thread, when operating in nonblocking mode. | |
349 // Written on the worker thread, read on the origin thread. | |
350 base::TimeDelta metrics_nonblocking_dns_wait_total_time_; | |
351 }; | 293 }; |
352 | 294 |
353 ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) | 295 ProxyResolverV8Tracing::Job::Job(ProxyResolverV8Tracing* parent) |
354 : origin_loop_(base::MessageLoopProxy::current()), | 296 : origin_loop_(base::MessageLoopProxy::current()), |
355 parent_(parent), | 297 parent_(parent), |
356 event_(true, false), | 298 event_(true, false), |
357 last_num_dns_(0), | 299 last_num_dns_(0), |
358 pending_dns_(NULL), | 300 pending_dns_(NULL) { |
359 metrics_num_executions_(0), | |
360 metrics_num_unique_dns_(0), | |
361 metrics_num_alerts_(0), | |
362 metrics_num_errors_(0) { | |
363 CheckIsOnOriginThread(); | 301 CheckIsOnOriginThread(); |
364 } | 302 } |
365 | 303 |
366 void ProxyResolverV8Tracing::Job::StartSetPacScript( | 304 void ProxyResolverV8Tracing::Job::StartSetPacScript( |
367 const scoped_refptr<ProxyResolverScriptData>& script_data, | 305 const scoped_refptr<ProxyResolverScriptData>& script_data, |
368 const CompletionCallback& callback) { | 306 const CompletionCallback& callback) { |
369 CheckIsOnOriginThread(); | 307 CheckIsOnOriginThread(); |
370 | 308 |
371 script_data_ = script_data; | 309 script_data_ = script_data; |
372 | 310 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 return parent_->error_observer_.get(); | 421 return parent_->error_observer_.get(); |
484 } | 422 } |
485 | 423 |
486 NetLog* ProxyResolverV8Tracing::Job::net_log() { | 424 NetLog* ProxyResolverV8Tracing::Job::net_log() { |
487 return parent_->net_log_; | 425 return parent_->net_log_; |
488 } | 426 } |
489 | 427 |
490 void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { | 428 void ProxyResolverV8Tracing::Job::NotifyCaller(int result) { |
491 CheckIsOnWorkerThread(); | 429 CheckIsOnWorkerThread(); |
492 | 430 |
493 metrics_end_time_ = base::TimeTicks::Now(); | |
494 | |
495 origin_loop_->PostTask( | 431 origin_loop_->PostTask( |
496 FROM_HERE, | 432 FROM_HERE, |
497 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); | 433 base::Bind(&Job::NotifyCallerOnOriginLoop, this, result)); |
498 } | 434 } |
499 | 435 |
500 void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { | 436 void ProxyResolverV8Tracing::Job::NotifyCallerOnOriginLoop(int result) { |
501 CheckIsOnOriginThread(); | 437 CheckIsOnOriginThread(); |
502 | 438 |
503 if (cancelled_.IsSet()) | 439 if (cancelled_.IsSet()) |
504 return; | 440 return; |
505 | 441 |
506 DCHECK(!callback_.is_null()); | 442 DCHECK(!callback_.is_null()); |
507 DCHECK(!pending_dns_); | 443 DCHECK(!pending_dns_); |
508 | 444 |
509 if (operation_ == GET_PROXY_FOR_URL) { | 445 if (operation_ == GET_PROXY_FOR_URL) { |
510 RecordMetrics(); | |
511 *user_results_ = results_; | 446 *user_results_ = results_; |
512 } | 447 } |
513 | 448 |
514 // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be | 449 // There is only ever 1 outstanding SET_PAC_SCRIPT job. It needs to be |
515 // tracked to support cancellation. | 450 // tracked to support cancellation. |
516 if (operation_ == SET_PAC_SCRIPT) { | 451 if (operation_ == SET_PAC_SCRIPT) { |
517 DCHECK_EQ(parent_->set_pac_script_job_.get(), this); | 452 DCHECK_EQ(parent_->set_pac_script_job_.get(), this); |
518 parent_->set_pac_script_job_ = NULL; | 453 parent_->set_pac_script_job_ = NULL; |
519 } | 454 } |
520 | 455 |
521 CompletionCallback callback = callback_; | 456 CompletionCallback callback = callback_; |
522 ReleaseCallback(); | 457 ReleaseCallback(); |
523 callback.Run(result); | 458 callback.Run(result); |
524 | 459 |
525 owned_self_reference_ = NULL; | 460 owned_self_reference_ = NULL; |
526 } | 461 } |
527 | 462 |
528 void ProxyResolverV8Tracing::Job::RecordMetrics() const { | |
529 CheckIsOnOriginThread(); | |
530 DCHECK_EQ(GET_PROXY_FOR_URL, operation_); | |
531 | |
532 base::TimeTicks now = base::TimeTicks::Now(); | |
533 | |
534 // Metrics are output for each completed request to GetProxyForURL()). | |
535 // | |
536 // Note that a different set of histograms is used to record the metrics for | |
537 // requests that completed in non-blocking mode versus blocking mode. The | |
538 // expectation is for requests to complete in non-blocking mode each time. | |
539 // If they don't then something strange is happening, and the purpose of the | |
540 // seprate statistics is to better understand that trend. | |
541 #define UPDATE_HISTOGRAMS(base_name) \ | |
542 do {\ | |
543 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTime", now - metrics_start_time_);\ | |
544 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTimeWorkerThread",\ | |
545 metrics_end_time_ - metrics_start_time_);\ | |
546 UMA_HISTOGRAM_TIMES(base_name "OriginThreadLatency",\ | |
547 now - metrics_end_time_);\ | |
548 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "TotalTimeDNS",\ | |
549 metrics_dns_total_time_);\ | |
550 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "ExecutionTime",\ | |
551 metrics_execution_time_);\ | |
552 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "AbandonedExecutionTotalTime",\ | |
553 metrics_abandoned_execution_total_time_);\ | |
554 UMA_HISTOGRAM_MEDIUM_TIMES(base_name "DnsWaitTotalTime",\ | |
555 metrics_nonblocking_dns_wait_total_time_);\ | |
556 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
557 base_name "NumRestarts", metrics_num_executions_ - 1,\ | |
558 1, kMaxUniqueResolveDnsPerExec, kMaxUniqueResolveDnsPerExec);\ | |
559 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
560 base_name "UniqueDNS", metrics_num_unique_dns_,\ | |
561 1, kMaxUniqueResolveDnsPerExec, kMaxUniqueResolveDnsPerExec);\ | |
562 UMA_HISTOGRAM_COUNTS_100(base_name "NumAlerts", metrics_num_alerts_);\ | |
563 UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
564 base_name "NumErrors", metrics_num_errors_, 1, 10, 10);\ | |
565 } while (false) | |
566 | |
567 if (!blocking_dns_) | |
568 UPDATE_HISTOGRAMS("Net.ProxyResolver."); | |
569 else | |
570 UPDATE_HISTOGRAMS("Net.ProxyResolver.BlockingDNSMode."); | |
571 | |
572 #undef UPDATE_HISTOGRAMS | |
573 | |
574 // Histograms to better understand http://crbug.com/240536 -- long | |
575 // URLs can cause a significant slowdown in PAC execution. Figure out how | |
576 // severe this is in the wild. | |
577 if (!blocking_dns_) { | |
578 size_t url_size = url_.spec().size(); | |
579 | |
580 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
581 "Net.ProxyResolver.URLSize", url_size, 1, 200000, 50); | |
582 | |
583 if (url_size > 2048) { | |
584 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver2K", | |
585 metrics_execution_time_); | |
586 } | |
587 | |
588 if (url_size > 4096) { | |
589 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver4K", | |
590 metrics_execution_time_); | |
591 } | |
592 | |
593 if (url_size > 8192) { | |
594 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver8K", | |
595 metrics_execution_time_); | |
596 } | |
597 | |
598 if (url_size > 131072) { | |
599 UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyResolver.ExecutionTime_UrlOver128K", | |
600 metrics_execution_time_); | |
601 } | |
602 } | |
603 } | |
604 | |
605 | |
606 void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, | 463 void ProxyResolverV8Tracing::Job::Start(Operation op, bool blocking_dns, |
607 const CompletionCallback& callback) { | 464 const CompletionCallback& callback) { |
608 CheckIsOnOriginThread(); | 465 CheckIsOnOriginThread(); |
609 | 466 |
610 metrics_start_time_ = base::TimeTicks::Now(); | |
611 operation_ = op; | 467 operation_ = op; |
612 blocking_dns_ = blocking_dns; | 468 blocking_dns_ = blocking_dns; |
613 SetCallback(callback); | 469 SetCallback(callback); |
614 | 470 |
615 owned_self_reference_ = this; | 471 owned_self_reference_ = this; |
616 | 472 |
617 worker_loop()->PostTask(FROM_HERE, | 473 worker_loop()->PostTask(FROM_HERE, |
618 blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : | 474 blocking_dns_ ? base::Bind(&Job::ExecuteBlocking, this) : |
619 base::Bind(&Job::ExecuteNonBlocking, this)); | 475 base::Bind(&Job::ExecuteNonBlocking, this)); |
620 } | 476 } |
(...skipping 17 matching lines...) Expand all Loading... |
638 | 494 |
639 // Reset state for the current execution. | 495 // Reset state for the current execution. |
640 abandoned_ = false; | 496 abandoned_ = false; |
641 num_dns_ = 0; | 497 num_dns_ = 0; |
642 alerts_and_errors_.clear(); | 498 alerts_and_errors_.clear(); |
643 alerts_and_errors_byte_cost_ = 0; | 499 alerts_and_errors_byte_cost_ = 0; |
644 should_restart_with_blocking_dns_ = false; | 500 should_restart_with_blocking_dns_ = false; |
645 | 501 |
646 int result = ExecuteProxyResolver(); | 502 int result = ExecuteProxyResolver(); |
647 | 503 |
648 if (abandoned_) | |
649 metrics_abandoned_execution_total_time_ += metrics_execution_time_; | |
650 | |
651 if (should_restart_with_blocking_dns_) { | 504 if (should_restart_with_blocking_dns_) { |
652 DCHECK(!blocking_dns_); | 505 DCHECK(!blocking_dns_); |
653 DCHECK(abandoned_); | 506 DCHECK(abandoned_); |
654 blocking_dns_ = true; | 507 blocking_dns_ = true; |
655 ExecuteBlocking(); | 508 ExecuteBlocking(); |
656 return; | 509 return; |
657 } | 510 } |
658 | 511 |
659 if (abandoned_) | 512 if (abandoned_) |
660 return; | 513 return; |
661 | 514 |
662 DispatchBufferedAlertsAndErrors(); | 515 DispatchBufferedAlertsAndErrors(); |
663 NotifyCaller(result); | 516 NotifyCaller(result); |
664 } | 517 } |
665 | 518 |
666 int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { | 519 int ProxyResolverV8Tracing::Job::ExecuteProxyResolver() { |
667 IncrementWithoutOverflow(&metrics_num_executions_); | |
668 | |
669 base::TimeTicks start = base::TimeTicks::Now(); | |
670 | |
671 JSBindings* prev_bindings = v8_resolver()->js_bindings(); | 520 JSBindings* prev_bindings = v8_resolver()->js_bindings(); |
672 v8_resolver()->set_js_bindings(this); | 521 v8_resolver()->set_js_bindings(this); |
673 | 522 |
674 int result = ERR_UNEXPECTED; // Initialized to silence warnings. | 523 int result = ERR_UNEXPECTED; // Initialized to silence warnings. |
675 | 524 |
676 switch (operation_) { | 525 switch (operation_) { |
677 case SET_PAC_SCRIPT: | 526 case SET_PAC_SCRIPT: |
678 result = v8_resolver()->SetPacScript( | 527 result = v8_resolver()->SetPacScript( |
679 script_data_, CompletionCallback()); | 528 script_data_, CompletionCallback()); |
680 break; | 529 break; |
681 case GET_PROXY_FOR_URL: | 530 case GET_PROXY_FOR_URL: |
682 result = v8_resolver()->GetProxyForURL( | 531 result = v8_resolver()->GetProxyForURL( |
683 url_, | 532 url_, |
684 // Important: Do not write directly into |user_results_|, since if the | 533 // Important: Do not write directly into |user_results_|, since if the |
685 // request were to be cancelled from the origin thread, must guarantee | 534 // request were to be cancelled from the origin thread, must guarantee |
686 // that |user_results_| is not accessed anymore. | 535 // that |user_results_| is not accessed anymore. |
687 &results_, | 536 &results_, |
688 CompletionCallback(), | 537 CompletionCallback(), |
689 NULL, | 538 NULL, |
690 bound_net_log_); | 539 bound_net_log_); |
691 break; | 540 break; |
692 } | 541 } |
693 | 542 |
694 v8_resolver()->set_js_bindings(prev_bindings); | 543 v8_resolver()->set_js_bindings(prev_bindings); |
695 | 544 |
696 metrics_execution_time_ = base::TimeTicks::Now() - start; | |
697 | |
698 return result; | 545 return result; |
699 } | 546 } |
700 | 547 |
701 bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, | 548 bool ProxyResolverV8Tracing::Job::ResolveDns(const std::string& host, |
702 ResolveDnsOperation op, | 549 ResolveDnsOperation op, |
703 std::string* output, | 550 std::string* output, |
704 bool* terminate) { | 551 bool* terminate) { |
705 if (cancelled_.IsSet()) { | 552 if (cancelled_.IsSet()) { |
706 *terminate = true; | 553 *terminate = true; |
707 return false; | 554 return false; |
(...skipping 23 matching lines...) Expand all Loading... |
731 std::string* output) { | 578 std::string* output) { |
732 CheckIsOnWorkerThread(); | 579 CheckIsOnWorkerThread(); |
733 | 580 |
734 // Check if the DNS result for this host has already been cached. | 581 // Check if the DNS result for this host has already been cached. |
735 bool rv; | 582 bool rv; |
736 if (GetDnsFromLocalCache(host, op, output, &rv)) { | 583 if (GetDnsFromLocalCache(host, op, output, &rv)) { |
737 // Yay, cache hit! | 584 // Yay, cache hit! |
738 return rv; | 585 return rv; |
739 } | 586 } |
740 | 587 |
741 // If the host was not in the local cache, this is a new hostname. | |
742 IncrementWithoutOverflow(&metrics_num_unique_dns_); | |
743 | |
744 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { | 588 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { |
745 // Safety net for scripts with unexpectedly many DNS calls. | 589 // Safety net for scripts with unexpectedly many DNS calls. |
746 // We will continue running to completion, but will fail every | 590 // We will continue running to completion, but will fail every |
747 // subsequent DNS request. | 591 // subsequent DNS request. |
748 return false; | 592 return false; |
749 } | 593 } |
750 | 594 |
751 if (!PostDnsOperationAndWait(host, op, NULL)) | 595 if (!PostDnsOperationAndWait(host, op, NULL)) |
752 return false; // Was cancelled. | 596 return false; // Was cancelled. |
753 | 597 |
(...skipping 15 matching lines...) Expand all Loading... |
769 | 613 |
770 num_dns_ += 1; | 614 num_dns_ += 1; |
771 | 615 |
772 // Check if the DNS result for this host has already been cached. | 616 // Check if the DNS result for this host has already been cached. |
773 bool rv; | 617 bool rv; |
774 if (GetDnsFromLocalCache(host, op, output, &rv)) { | 618 if (GetDnsFromLocalCache(host, op, output, &rv)) { |
775 // Yay, cache hit! | 619 // Yay, cache hit! |
776 return rv; | 620 return rv; |
777 } | 621 } |
778 | 622 |
779 // If the host was not in the local cache, then this is a new hostname. | |
780 IncrementWithoutOverflow(&metrics_num_unique_dns_); | |
781 | |
782 if (num_dns_ <= last_num_dns_) { | 623 if (num_dns_ <= last_num_dns_) { |
783 // The sequence of DNS operations is different from last time! | 624 // The sequence of DNS operations is different from last time! |
784 ScheduleRestartWithBlockingDns(); | 625 ScheduleRestartWithBlockingDns(); |
785 *terminate = true; | 626 *terminate = true; |
786 return false; | 627 return false; |
787 } | 628 } |
788 | 629 |
789 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { | 630 if (dns_cache_.size() >= kMaxUniqueResolveDnsPerExec) { |
790 // Safety net for scripts with unexpectedly many DNS calls. | 631 // Safety net for scripts with unexpectedly many DNS calls. |
791 return false; | 632 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
808 abandoned_ = true; | 649 abandoned_ = true; |
809 *terminate = true; | 650 *terminate = true; |
810 last_num_dns_ = num_dns_; | 651 last_num_dns_ = num_dns_; |
811 return false; | 652 return false; |
812 } | 653 } |
813 | 654 |
814 bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( | 655 bool ProxyResolverV8Tracing::Job::PostDnsOperationAndWait( |
815 const std::string& host, ResolveDnsOperation op, | 656 const std::string& host, ResolveDnsOperation op, |
816 bool* completed_synchronously) { | 657 bool* completed_synchronously) { |
817 | 658 |
818 base::TimeTicks start = base::TimeTicks::Now(); | |
819 | |
820 // Post the DNS request to the origin thread. | 659 // Post the DNS request to the origin thread. |
821 DCHECK(!pending_dns_); | 660 DCHECK(!pending_dns_); |
822 metrics_pending_dns_start_ = base::TimeTicks::Now(); | |
823 pending_dns_host_ = host; | 661 pending_dns_host_ = host; |
824 pending_dns_op_ = op; | 662 pending_dns_op_ = op; |
825 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); | 663 origin_loop_->PostTask(FROM_HERE, base::Bind(&Job::DoDnsOperation, this)); |
826 | 664 |
827 event_.Wait(); | 665 event_.Wait(); |
828 event_.Reset(); | 666 event_.Reset(); |
829 | 667 |
830 if (cancelled_.IsSet()) | 668 if (cancelled_.IsSet()) |
831 return false; | 669 return false; |
832 | 670 |
833 if (completed_synchronously) | 671 if (completed_synchronously) |
834 *completed_synchronously = pending_dns_completed_synchronously_; | 672 *completed_synchronously = pending_dns_completed_synchronously_; |
835 | 673 |
836 if (!blocking_dns_) | |
837 metrics_nonblocking_dns_wait_total_time_ += base::TimeTicks::Now() - start; | |
838 | |
839 return true; | 674 return true; |
840 } | 675 } |
841 | 676 |
842 void ProxyResolverV8Tracing::Job::DoDnsOperation() { | 677 void ProxyResolverV8Tracing::Job::DoDnsOperation() { |
843 CheckIsOnOriginThread(); | 678 CheckIsOnOriginThread(); |
844 DCHECK(!pending_dns_); | 679 DCHECK(!pending_dns_); |
845 | 680 |
846 if (cancelled_.IsSet()) | 681 if (cancelled_.IsSet()) |
847 return; | 682 return; |
848 | 683 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { | 719 void ProxyResolverV8Tracing::Job::OnDnsOperationComplete(int result) { |
885 CheckIsOnOriginThread(); | 720 CheckIsOnOriginThread(); |
886 | 721 |
887 DCHECK(!cancelled_.IsSet()); | 722 DCHECK(!cancelled_.IsSet()); |
888 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); | 723 DCHECK(pending_dns_completed_synchronously_ == (pending_dns_ == NULL)); |
889 | 724 |
890 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, | 725 SaveDnsToLocalCache(pending_dns_host_, pending_dns_op_, result, |
891 pending_dns_addresses_); | 726 pending_dns_addresses_); |
892 pending_dns_ = NULL; | 727 pending_dns_ = NULL; |
893 | 728 |
894 metrics_dns_total_time_ += | |
895 base::TimeTicks::Now() - metrics_pending_dns_start_; | |
896 | |
897 if (blocking_dns_) { | 729 if (blocking_dns_) { |
898 event_.Signal(); | 730 event_.Signal(); |
899 return; | 731 return; |
900 } | 732 } |
901 | 733 |
902 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { | 734 if (!blocking_dns_ && !pending_dns_completed_synchronously_) { |
903 // Restart. This time it should make more progress due to having | 735 // Restart. This time it should make more progress due to having |
904 // cached items. | 736 // cached items. |
905 worker_loop()->PostTask(FROM_HERE, | 737 worker_loop()->PostTask(FROM_HERE, |
906 base::Bind(&Job::ExecuteNonBlocking, this)); | 738 base::Bind(&Job::ExecuteNonBlocking, this)); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 // If this happens, then some information will get written to the NetLog | 881 // If this happens, then some information will get written to the NetLog |
1050 // needlessly, however the NetLog will still be alive so it shouldn't cause | 882 // needlessly, however the NetLog will still be alive so it shouldn't cause |
1051 // problems. | 883 // problems. |
1052 if (cancelled_.IsSet()) | 884 if (cancelled_.IsSet()) |
1053 return; | 885 return; |
1054 | 886 |
1055 if (is_alert) { | 887 if (is_alert) { |
1056 // ------------------- | 888 // ------------------- |
1057 // alert | 889 // alert |
1058 // ------------------- | 890 // ------------------- |
1059 IncrementWithoutOverflow(&metrics_num_alerts_); | |
1060 VLOG(1) << "PAC-alert: " << message; | 891 VLOG(1) << "PAC-alert: " << message; |
1061 | 892 |
1062 // Send to the NetLog. | 893 // Send to the NetLog. |
1063 LogEventToCurrentRequestAndGlobally( | 894 LogEventToCurrentRequestAndGlobally( |
1064 NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | 895 NetLog::TYPE_PAC_JAVASCRIPT_ALERT, |
1065 NetLog::StringCallback("message", &message)); | 896 NetLog::StringCallback("message", &message)); |
1066 } else { | 897 } else { |
1067 // ------------------- | 898 // ------------------- |
1068 // error | 899 // error |
1069 // ------------------- | 900 // ------------------- |
1070 IncrementWithoutOverflow(&metrics_num_errors_); | |
1071 if (line_number == -1) | 901 if (line_number == -1) |
1072 VLOG(1) << "PAC-error: " << message; | 902 VLOG(1) << "PAC-error: " << message; |
1073 else | 903 else |
1074 VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message; | 904 VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message; |
1075 | 905 |
1076 // Send the error to the NetLog. | 906 // Send the error to the NetLog. |
1077 LogEventToCurrentRequestAndGlobally( | 907 LogEventToCurrentRequestAndGlobally( |
1078 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, | 908 NetLog::TYPE_PAC_JAVASCRIPT_ERROR, |
1079 base::Bind(&NetLogErrorCallback, line_number, &message)); | 909 base::Bind(&NetLogErrorCallback, line_number, &message)); |
1080 | 910 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 DCHECK(!set_pac_script_job_.get()); | 1001 DCHECK(!set_pac_script_job_.get()); |
1172 CHECK_EQ(0, num_outstanding_callbacks_); | 1002 CHECK_EQ(0, num_outstanding_callbacks_); |
1173 | 1003 |
1174 set_pac_script_job_ = new Job(this); | 1004 set_pac_script_job_ = new Job(this); |
1175 set_pac_script_job_->StartSetPacScript(script_data, callback); | 1005 set_pac_script_job_->StartSetPacScript(script_data, callback); |
1176 | 1006 |
1177 return ERR_IO_PENDING; | 1007 return ERR_IO_PENDING; |
1178 } | 1008 } |
1179 | 1009 |
1180 } // namespace net | 1010 } // namespace net |
OLD | NEW |