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

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

Issue 1187623006: Service Worker: Update stale workers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: safer reg holding Created 5 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 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/location.h" 8 #include "base/location.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 // Delay between the timeout timer firing. 54 // Delay between the timeout timer firing.
55 const int kTimeoutTimerDelaySeconds = 30; 55 const int kTimeoutTimerDelaySeconds = 30;
56 56
57 // Time to wait until stopping an idle worker. 57 // Time to wait until stopping an idle worker.
58 const int kIdleWorkerTimeoutSeconds = 30; 58 const int kIdleWorkerTimeoutSeconds = 30;
59 59
60 // Default delay for scheduled update. 60 // Default delay for scheduled update.
61 const int kUpdateDelaySeconds = 1; 61 const int kUpdateDelaySeconds = 1;
62 62
63 // Time to wait until updating a stale worker that's still running.
64 const int kUpdateStaleWorkerSeconds = 30;
Peter Beverloo 2015/06/18 14:08:58 It'd be great if we could get some UMA coverage to
falken 2015/06/22 08:05:44 Actually I realized I should be using 5 minutes as
65
63 // Timeout for waiting for a response to a ping. 66 // Timeout for waiting for a response to a ping.
64 const int kPingTimeoutSeconds = 30; 67 const int kPingTimeoutSeconds = 30;
65 68
66 // If the SW was destructed while starting up, how many seconds it 69 // If the SW was destructed while starting up, how many seconds it
67 // had to start up for this to be considered a timeout occurrence. 70 // had to start up for this to be considered a timeout occurrence.
68 const int kDestructedStartingWorkerTimeoutThresholdSeconds = 5; 71 const int kDestructedStartingWorkerTimeoutThresholdSeconds = 5;
69 72
70 const char kClaimClientsStateErrorMesage[] = 73 const char kClaimClientsStateErrorMesage[] =
71 "Only the active worker can claim clients."; 74 "Only the active worker can claim clients.";
72 75
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 private: 411 private:
409 size_t fired_events = 0; 412 size_t fired_events = 0;
410 size_t handled_events = 0; 413 size_t handled_events = 0;
411 DISALLOW_COPY_AND_ASSIGN(Metrics); 414 DISALLOW_COPY_AND_ASSIGN(Metrics);
412 }; 415 };
413 416
414 // A controller for periodically sending a ping to the worker to see 417 // A controller for periodically sending a ping to the worker to see
415 // if the worker is not stalling. 418 // if the worker is not stalling.
416 class ServiceWorkerVersion::PingController { 419 class ServiceWorkerVersion::PingController {
417 public: 420 public:
418 PingController(ServiceWorkerVersion* version) : version_(version) {} 421 explicit PingController(ServiceWorkerVersion* version) : version_(version) {}
419 ~PingController() {} 422 ~PingController() {}
420 423
421 void Activate() { ping_state_ = PINGING; } 424 void Activate() { ping_state_ = PINGING; }
422 425
423 void Deactivate() { 426 void Deactivate() {
424 ClearTick(&ping_time_); 427 ClearTick(&ping_time_);
425 ping_state_ = NOT_PINGING; 428 ping_state_ = NOT_PINGING;
426 } 429 }
427 430
428 void OnPongReceived() { ClearTick(&ping_time_); } 431 void OnPongReceived() { ClearTick(&ping_time_); }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 600 }
598 } 601 }
599 stop_callbacks_.push_back(callback); 602 stop_callbacks_.push_back(callback);
600 } 603 }
601 604
602 void ServiceWorkerVersion::ScheduleUpdate() { 605 void ServiceWorkerVersion::ScheduleUpdate() {
603 if (update_timer_.IsRunning()) { 606 if (update_timer_.IsRunning()) {
604 update_timer_.Reset(); 607 update_timer_.Reset();
605 return; 608 return;
606 } 609 }
607 update_timer_.Start( 610 update_timer_.Start(FROM_HERE,
608 FROM_HERE, base::TimeDelta::FromSeconds(kUpdateDelaySeconds), 611 base::TimeDelta::FromSeconds(kUpdateDelaySeconds),
609 base::Bind(&ServiceWorkerVersion::StartUpdate, 612 base::Bind(&ServiceWorkerVersion::StartUpdate, this));
610 weak_factory_.GetWeakPtr()));
611 } 613 }
612 614
613 void ServiceWorkerVersion::DeferScheduledUpdate() { 615 void ServiceWorkerVersion::DeferScheduledUpdate() {
614 if (update_timer_.IsRunning()) 616 if (update_timer_.IsRunning())
615 update_timer_.Reset(); 617 update_timer_.Reset();
616 } 618 }
617 619
618 void ServiceWorkerVersion::StartUpdate() { 620 void ServiceWorkerVersion::StartUpdate() {
619 update_timer_.Stop(); 621 update_timer_.Stop();
620 if (!context_) 622 if (!context_)
621 return; 623 return;
622 ServiceWorkerRegistration* registration = 624 context_->storage()->FindRegistrationForId(
623 context_->GetLiveRegistration(registration_id_); 625 registration_id_, scope_.GetOrigin(),
624 if (!registration || !registration->GetNewestVersion()) 626 base::Bind(&ServiceWorkerVersion::FoundRegistrationForUpdate, this));
nhiroki 2015/06/22 05:16:55 "this" should be weakptr because this version coul
falken 2015/06/22 08:05:44 I actually wanted to ensure the version stays aliv
nhiroki 2015/06/22 08:39:17 Oh sorry, I thought you are passing a rawptr here.
625 return;
626 context_->UpdateServiceWorker(registration, false /* force_bypass_cache */);
627 } 627 }
628 628
629 void ServiceWorkerVersion::DispatchMessageEvent( 629 void ServiceWorkerVersion::DispatchMessageEvent(
630 const base::string16& message, 630 const base::string16& message,
631 const std::vector<TransferredMessagePort>& sent_message_ports, 631 const std::vector<TransferredMessagePort>& sent_message_ports,
632 const StatusCallback& callback) { 632 const StatusCallback& callback) {
633 for (const TransferredMessagePort& port : sent_message_ports) { 633 for (const TransferredMessagePort& port : sent_message_ports) {
634 MessagePortService::GetInstance()->HoldMessages(port.id); 634 MessagePortService::GetInstance()->HoldMessages(port.id);
635 } 635 }
636 636
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 RecordStartWorkerResult(status); 1718 RecordStartWorkerResult(status);
1719 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); 1719 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
1720 return; 1720 return;
1721 } 1721 }
1722 if (is_redundant()) { 1722 if (is_redundant()) {
1723 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT); 1723 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT);
1724 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); 1724 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT));
1725 return; 1725 return;
1726 } 1726 }
1727 1727
1728 MarkIfStale();
1729
1728 switch (running_status()) { 1730 switch (running_status()) {
1729 case RUNNING: 1731 case RUNNING:
1730 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); 1732 RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
1731 return; 1733 return;
1732 case STOPPING: 1734 case STOPPING:
1733 case STOPPED: 1735 case STOPPED:
1734 case STARTING: 1736 case STARTING:
1735 if (start_callbacks_.empty()) { 1737 if (start_callbacks_.empty()) {
1736 start_callbacks_.push_back( 1738 start_callbacks_.push_back(
1737 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, 1739 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 // Ping will be activated in OnScriptLoaded. 1832 // Ping will be activated in OnScriptLoaded.
1831 ping_controller_->Deactivate(); 1833 ping_controller_->Deactivate();
1832 1834
1833 timeout_timer_.Start(FROM_HERE, 1835 timeout_timer_.Start(FROM_HERE,
1834 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), 1836 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds),
1835 this, &ServiceWorkerVersion::OnTimeoutTimer); 1837 this, &ServiceWorkerVersion::OnTimeoutTimer);
1836 } 1838 }
1837 1839
1838 void ServiceWorkerVersion::StopTimeoutTimer() { 1840 void ServiceWorkerVersion::StopTimeoutTimer() {
1839 timeout_timer_.Stop(); 1841 timeout_timer_.Stop();
1842
1843 // Trigger update if worker is stale.
1844 if (!stale_time_.is_null()) {
1845 ClearTick(&stale_time_);
1846 if (!update_timer_.IsRunning())
1847 ScheduleUpdate();
1848 }
1840 } 1849 }
1841 1850
1842 void ServiceWorkerVersion::OnTimeoutTimer() { 1851 void ServiceWorkerVersion::OnTimeoutTimer() {
1843 DCHECK(running_status() == STARTING || running_status() == RUNNING || 1852 DCHECK(running_status() == STARTING || running_status() == RUNNING ||
1844 running_status() == STOPPING) 1853 running_status() == STOPPING)
1845 << running_status(); 1854 << running_status();
1846 1855
1856 MarkIfStale();
falken 2015/06/18 09:05:57 +nhiroki: I'm hoping while the worker is running I
nhiroki 2015/06/22 05:16:55 Yes, you can assume that because ServiceWorkerGlob
1857
1858 // Trigger update if worker is stale and we waited long enough for it to go
1859 // idle.
1860 if (GetTickDuration(stale_time_) >
1861 base::TimeDelta::FromSeconds(kUpdateStaleWorkerSeconds)) {
1862 ClearTick(&stale_time_);
1863 if (!update_timer_.IsRunning())
1864 ScheduleUpdate();
1865 }
1866
1847 // Starting a worker hasn't finished within a certain period. 1867 // Starting a worker hasn't finished within a certain period.
1848 if (GetTickDuration(start_time_) > 1868 if (GetTickDuration(start_time_) >
1849 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { 1869 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) {
1850 DCHECK(running_status() == STARTING || running_status() == STOPPING) 1870 DCHECK(running_status() == STARTING || running_status() == STOPPING)
1851 << running_status(); 1871 << running_status();
1852 scoped_refptr<ServiceWorkerVersion> protect(this); 1872 scoped_refptr<ServiceWorkerVersion> protect(this);
1853 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); 1873 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT);
1854 if (running_status() == STARTING) 1874 if (running_status() == STARTING)
1855 embedded_worker_->Stop(); 1875 embedded_worker_->Stop();
1856 return; 1876 return;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 case net::ERR_ABORTED: 2069 case net::ERR_ABORTED:
2050 return SERVICE_WORKER_ERROR_ABORT; 2070 return SERVICE_WORKER_ERROR_ABORT;
2051 default: 2071 default:
2052 return SERVICE_WORKER_ERROR_NETWORK; 2072 return SERVICE_WORKER_ERROR_NETWORK;
2053 } 2073 }
2054 } 2074 }
2055 2075
2056 return default_code; 2076 return default_code;
2057 } 2077 }
2058 2078
2079 void ServiceWorkerVersion::MarkIfStale() {
2080 if (!context_)
2081 return;
2082 if (update_timer_.IsRunning() || !stale_time_.is_null())
2083 return;
2084 ServiceWorkerRegistration* registration =
2085 context_->GetLiveRegistration(registration_id_);
2086 if (!registration || registration->active_version() != this)
2087 return;
2088 base::TimeDelta time_since_last_check =
2089 base::Time::Now() - registration->last_update_check();
2090 if (time_since_last_check > base::TimeDelta::FromHours(24))
Peter Beverloo 2015/06/18 14:08:58 nit: Should this be a constant for readability?
falken 2015/06/22 08:05:44 Changed to use existing kRequestTimeoutMinutes.
2091 RestartTick(&stale_time_);
2092 }
2093
2094 void ServiceWorkerVersion::FoundRegistrationForUpdate(
2095 ServiceWorkerStatusCode status,
2096 const scoped_refptr<ServiceWorkerRegistration>& registration) {
2097 if (status != SERVICE_WORKER_OK || registration->active_version() != this)
2098 return;
2099 context_->UpdateServiceWorker(registration.get(),
2100 false /* force_bypass_cache */);
2101 }
2102
2059 } // namespace content 2103 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698