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

Side by Side Diff: content/browser/service_worker/service_worker_version.cc

Issue 1004913003: ServiceWorker: Don't start the timeout timer when DevTools is detached (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "content/browser/service_worker/service_worker_version.h" 5 #include "content/browser/service_worker/service_worker_version.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 const GURL& script_url, 307 const GURL& script_url,
308 int64 version_id, 308 int64 version_id,
309 base::WeakPtr<ServiceWorkerContextCore> context) 309 base::WeakPtr<ServiceWorkerContextCore> context)
310 : version_id_(version_id), 310 : version_id_(version_id),
311 registration_id_(kInvalidServiceWorkerVersionId), 311 registration_id_(kInvalidServiceWorkerVersionId),
312 script_url_(script_url), 312 script_url_(script_url),
313 status_(NEW), 313 status_(NEW),
314 context_(context), 314 context_(context),
315 script_cache_map_(this, context), 315 script_cache_map_(this, context),
316 ping_state_(NOT_PINGING), 316 ping_state_(NOT_PINGING),
317 is_doomed_(false),
318 skip_waiting_(false),
319 weak_factory_(this) { 317 weak_factory_(this) {
320 DCHECK(context_); 318 DCHECK(context_);
321 DCHECK(registration); 319 DCHECK(registration);
322 if (registration) { 320 if (registration) {
323 registration_id_ = registration->id(); 321 registration_id_ = registration->id();
324 scope_ = registration->pattern(); 322 scope_ = registration->pattern();
325 } 323 }
326 context_->AddLiveVersion(this); 324 context_->AddLiveVersion(this);
327 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); 325 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker();
328 embedded_worker_->AddListener(this); 326 embedded_worker_->AddListener(this);
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 if (is_doomed_) 770 if (is_doomed_)
773 return; 771 return;
774 is_doomed_ = true; 772 is_doomed_ = true;
775 if (!HasControllee()) 773 if (!HasControllee())
776 DoomInternal(); 774 DoomInternal();
777 } 775 }
778 776
779 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { 777 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
780 embedded_worker()->set_devtools_attached(attached); 778 embedded_worker()->set_devtools_attached(attached);
781 if (attached) { 779 if (attached) {
782 // Set to null time so we don't record the startup time metric. 780 // Don't record the startup time metric once DevTools is attached.
783 ClearTick(&start_time_); 781 ClearTick(&start_time_);
782 skip_recording_startup_time_ = true;
784 return; 783 return;
785 } 784 }
786 if (!timeout_timer_.IsRunning()) 785 if (running_status() == STARTING || running_status() == STOPPING) {
falken 2015/03/23 00:14:25 This is kind of a non-obvious condition. Would it
nhiroki 2015/03/23 00:43:17 Done.
nhiroki 2015/03/23 00:43:17 Done.
787 StartTimeoutTimer(); 786 // Reactivate the timer for start timeout.
787 DCHECK(timeout_timer_.IsRunning()) << running_status();
788 RestartTick(&start_time_);
789 }
788 } 790 }
789 791
790 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( 792 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
791 const net::HttpResponseInfo& http_info) { 793 const net::HttpResponseInfo& http_info) {
792 main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); 794 main_script_http_info_.reset(new net::HttpResponseInfo(http_info));
793 } 795 }
794 796
795 const net::HttpResponseInfo* 797 const net::HttpResponseInfo*
796 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { 798 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() {
797 return main_script_http_info_.get(); 799 return main_script_http_info_.get();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 streaming_url_request_jobs_.clear(); 871 streaming_url_request_jobs_.clear();
870 872
871 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); 873 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this));
872 874
873 // There should be no more communication from/to a stopped worker. Deleting 875 // There should be no more communication from/to a stopped worker. Deleting
874 // the listener prevents any pending completion callbacks from causing 876 // the listener prevents any pending completion callbacks from causing
875 // messages to be sent to the stopped worker. 877 // messages to be sent to the stopped worker.
876 cache_listener_.reset(); 878 cache_listener_.reset();
877 879
878 // Restart worker if we have any start callbacks and the worker isn't doomed. 880 // Restart worker if we have any start callbacks and the worker isn't doomed.
879 if (should_restart) { 881 if (should_restart)
880 if (embedded_worker_->devtools_attached()) 882 StartWorkerInternal(false /* pause_after_download */);
falken 2015/03/23 00:14:25 Thanks for this helper function.
881 ClearTick(&start_time_);
882 else
883 RestartTick(&start_time_);
nhiroki 2015/03/16 01:58:02 FYI: We may have to call StartTimeoutTimer() here.
884 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
885 embedded_worker_->Start(
886 version_id_, scope_, script_url_, false /* pause_after_download */,
887 base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
888 weak_factory_.GetWeakPtr()));
889 }
890 } 883 }
891 884
892 void ServiceWorkerVersion::OnReportException( 885 void ServiceWorkerVersion::OnReportException(
893 const base::string16& error_message, 886 const base::string16& error_message,
894 int line_number, 887 int line_number,
895 int column_number, 888 int column_number,
896 const GURL& source_url) { 889 const GURL& source_url) {
897 FOR_EACH_OBSERVER( 890 FOR_EACH_OBSERVER(
898 Listener, 891 Listener,
899 listeners_, 892 listeners_,
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 1407
1415 void ServiceWorkerVersion::OnPongFromWorker() { 1408 void ServiceWorkerVersion::OnPongFromWorker() {
1416 ClearTick(&ping_time_); 1409 ClearTick(&ping_time_);
1417 } 1410 }
1418 1411
1419 void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker( 1412 void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
1420 bool pause_after_download, 1413 bool pause_after_download,
1421 const StatusCallback& callback, 1414 const StatusCallback& callback,
1422 ServiceWorkerStatusCode status, 1415 ServiceWorkerStatusCode status,
1423 const scoped_refptr<ServiceWorkerRegistration>& protect) { 1416 const scoped_refptr<ServiceWorkerRegistration>& protect) {
1424 if (status != SERVICE_WORKER_OK || is_doomed()) { 1417 if (status != SERVICE_WORKER_OK || is_doomed()) {
falken 2015/03/23 00:14:25 I feel like non-OK status here is unexpected and w
nhiroki 2015/03/23 00:43:17 Sounds reasonable. Added the function call (is_doo
1425 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); 1418 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
1426 return; 1419 return;
1427 } 1420 }
1428 1421
1429 switch (running_status()) { 1422 switch (running_status()) {
1430 case RUNNING: 1423 case RUNNING:
1431 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); 1424 RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
1432 return; 1425 return;
1433 case STOPPING: 1426 case STOPPING:
1434 case STOPPED: 1427 case STOPPED:
1435 case STARTING: 1428 case STARTING:
1436 if (!timeout_timer_.IsRunning()) 1429 if (start_callbacks_.empty()) {
1437 StartTimeoutTimer(); 1430 start_callbacks_.push_back(
1438 // Start callbacks keep the live registration. 1431 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
1432 weak_factory_.GetWeakPtr()));
1433 }
1434 // Keep the live registration while staring the worker.
falken 2015/03/23 00:14:25 nit: starting
nhiroki 2015/03/23 00:43:17 Done.
1439 start_callbacks_.push_back( 1435 start_callbacks_.push_back(
1440 base::Bind(&RunStartWorkerCallback, callback, protect)); 1436 base::Bind(&RunStartWorkerCallback, callback, protect));
1441 if (running_status() == STOPPED) { 1437 StartWorkerInternal(pause_after_download);
1442 DCHECK(!cache_listener_.get());
1443 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
1444 embedded_worker_->Start(
1445 version_id_, scope_, script_url_, pause_after_download,
1446 base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
1447 weak_factory_.GetWeakPtr()));
1448 }
1449 return; 1438 return;
1450 } 1439 }
1451 } 1440 }
1452 1441
1442 void ServiceWorkerVersion::StartWorkerInternal(bool pause_after_download) {
1443 if (!timeout_timer_.IsRunning())
1444 StartTimeoutTimer();
1445 if (running_status() == STOPPED) {
1446 DCHECK(!cache_listener_.get());
1447 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
1448 embedded_worker_->Start(
1449 version_id_, scope_, script_url_, pause_after_download,
1450 base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
1451 weak_factory_.GetWeakPtr()));
1452 }
1453 }
1454
1453 void ServiceWorkerVersion::DidClaimClients( 1455 void ServiceWorkerVersion::DidClaimClients(
1454 int request_id, ServiceWorkerStatusCode status) { 1456 int request_id, ServiceWorkerStatusCode status) {
1455 if (status == SERVICE_WORKER_ERROR_STATE) { 1457 if (status == SERVICE_WORKER_ERROR_STATE) {
1456 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( 1458 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
1457 request_id, blink::WebServiceWorkerError::ErrorTypeState, 1459 request_id, blink::WebServiceWorkerError::ErrorTypeState,
1458 base::ASCIIToUTF16(kClaimClientsStateErrorMesage))); 1460 base::ASCIIToUTF16(kClaimClientsStateErrorMesage)));
1459 return; 1461 return;
1460 } 1462 }
1461 if (status == SERVICE_WORKER_ERROR_ABORT) { 1463 if (status == SERVICE_WORKER_ERROR_ABORT) {
1462 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( 1464 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
(...skipping 12 matching lines...) Expand all
1475 if (running_status() != RUNNING) 1477 if (running_status() != RUNNING)
1476 return; 1478 return;
1477 1479
1478 embedded_worker_->SendMessage( 1480 embedded_worker_->SendMessage(
1479 ServiceWorkerMsg_DidGetClients(request_id, clients)); 1481 ServiceWorkerMsg_DidGetClients(request_id, clients));
1480 } 1482 }
1481 1483
1482 void ServiceWorkerVersion::StartTimeoutTimer() { 1484 void ServiceWorkerVersion::StartTimeoutTimer() {
1483 DCHECK(!timeout_timer_.IsRunning()); 1485 DCHECK(!timeout_timer_.IsRunning());
1484 1486
1485 if (embedded_worker_->devtools_attached()) 1487 if (embedded_worker_->devtools_attached()) {
1488 // Don't record the startup time metric once DevTools is attached.
1486 ClearTick(&start_time_); 1489 ClearTick(&start_time_);
1487 else 1490 skip_recording_startup_time_ = true;
1491 } else {
1488 RestartTick(&start_time_); 1492 RestartTick(&start_time_);
1489 start_callbacks_.push_back( 1493 skip_recording_startup_time_ = false;
1490 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, 1494 }
1491 weak_factory_.GetWeakPtr()));
1492 1495
1493 ClearTick(&idle_time_); 1496 ClearTick(&idle_time_);
1494 ClearTick(&ping_time_); 1497 ClearTick(&ping_time_);
1495 ping_state_ = NOT_PINGING; 1498 ping_state_ = NOT_PINGING;
1496 1499
1497 timeout_timer_.Start(FROM_HERE, 1500 timeout_timer_.Start(FROM_HERE,
1498 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), 1501 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds),
1499 this, &ServiceWorkerVersion::OnTimeoutTimer); 1502 this, &ServiceWorkerVersion::OnTimeoutTimer);
1500 } 1503 }
1501 1504
1502 void ServiceWorkerVersion::StopTimeoutTimer() { 1505 void ServiceWorkerVersion::StopTimeoutTimer() {
1503 timeout_timer_.Stop(); 1506 timeout_timer_.Stop();
1504 } 1507 }
1505 1508
1506 void ServiceWorkerVersion::OnTimeoutTimer() { 1509 void ServiceWorkerVersion::OnTimeoutTimer() {
1507 DCHECK(running_status() == STARTING || running_status() == RUNNING || 1510 DCHECK(running_status() == STARTING || running_status() == RUNNING ||
1508 running_status() == STOPPING) 1511 running_status() == STOPPING)
1509 << running_status(); 1512 << running_status();
1510 1513
1511 // Starting a worker hasn't finished within a certain period. 1514 // Starting a worker hasn't finished within a certain period.
1512 if (GetTickDuration(start_time_) > 1515 if (GetTickDuration(start_time_) >
1513 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { 1516 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) {
1514 DCHECK_NE(RUNNING, running_status()); 1517 DCHECK(running_status() == STARTING || running_status() == STOPPING)
1518 << running_status();
1515 scoped_refptr<ServiceWorkerVersion> protect(this); 1519 scoped_refptr<ServiceWorkerVersion> protect(this);
1516 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); 1520 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT);
1517 if (running_status() == STARTING) 1521 if (running_status() == STARTING)
1518 embedded_worker_->Stop(); 1522 embedded_worker_->Stop();
1519 return; 1523 return;
1520 } 1524 }
1521 1525
1522 // This check occurs after the start_time_ timeout check, since in that case 1526 // This check occurs after the start_time_ timeout check, since in that case
1523 // the start callbacks should fail with ERROR_TIMEOUT. In the other timeout 1527 // the start callbacks should fail with ERROR_TIMEOUT. In the other timeout
1524 // checks, there's nothing more to do as the worker is already stopping. 1528 // checks, there's nothing more to do as the worker is already stopping.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 base::TimeTicks start_time = start_time_; 1602 base::TimeTicks start_time = start_time_;
1599 ClearTick(&start_time_); 1603 ClearTick(&start_time_);
1600 1604
1601 // Failing to start a doomed worker isn't interesting and very common when 1605 // Failing to start a doomed worker isn't interesting and very common when
1602 // update dooms because the script is byte-to-byte identical. 1606 // update dooms because the script is byte-to-byte identical.
1603 if (is_doomed_) 1607 if (is_doomed_)
1604 return; 1608 return;
1605 1609
1606 UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status, 1610 UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status,
1607 SERVICE_WORKER_ERROR_MAX_VALUE); 1611 SERVICE_WORKER_ERROR_MAX_VALUE);
1608 if (status == SERVICE_WORKER_OK && !start_time.is_null()) { 1612 if (status == SERVICE_WORKER_OK && !start_time.is_null() &&
1613 !skip_recording_startup_time_) {
1609 UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartWorker.Time", 1614 UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartWorker.Time",
1610 GetTickDuration(start_time)); 1615 GetTickDuration(start_time));
1611 } 1616 }
1612 1617
1613 if (status != SERVICE_WORKER_ERROR_TIMEOUT) 1618 if (status != SERVICE_WORKER_ERROR_TIMEOUT)
1614 return; 1619 return;
1615 EmbeddedWorkerInstance::StartingPhase phase = 1620 EmbeddedWorkerInstance::StartingPhase phase =
1616 EmbeddedWorkerInstance::NOT_STARTING; 1621 EmbeddedWorkerInstance::NOT_STARTING;
1617 EmbeddedWorkerInstance::Status running_status = embedded_worker_->status(); 1622 EmbeddedWorkerInstance::Status running_status = embedded_worker_->status();
1618 // Build an artifical JavaScript exception to show in the ServiceWorker 1623 // Build an artifical JavaScript exception to show in the ServiceWorker
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 int request_id) { 1657 int request_id) {
1653 callbacks->Remove(request_id); 1658 callbacks->Remove(request_id);
1654 if (is_doomed_) { 1659 if (is_doomed_) {
1655 // The stop should be already scheduled, but try to stop immediately, in 1660 // The stop should be already scheduled, but try to stop immediately, in
1656 // order to release worker resources soon. 1661 // order to release worker resources soon.
1657 StopWorkerIfIdle(); 1662 StopWorkerIfIdle();
1658 } 1663 }
1659 } 1664 }
1660 1665
1661 } // namespace content 1666 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698