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

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: fix DCHECK Created 5 years, 5 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 private: 408 private:
409 size_t fired_events = 0; 409 size_t fired_events = 0;
410 size_t handled_events = 0; 410 size_t handled_events = 0;
411 DISALLOW_COPY_AND_ASSIGN(Metrics); 411 DISALLOW_COPY_AND_ASSIGN(Metrics);
412 }; 412 };
413 413
414 // A controller for periodically sending a ping to the worker to see 414 // A controller for periodically sending a ping to the worker to see
415 // if the worker is not stalling. 415 // if the worker is not stalling.
416 class ServiceWorkerVersion::PingController { 416 class ServiceWorkerVersion::PingController {
417 public: 417 public:
418 PingController(ServiceWorkerVersion* version) : version_(version) {} 418 explicit PingController(ServiceWorkerVersion* version) : version_(version) {}
419 ~PingController() {} 419 ~PingController() {}
420 420
421 void Activate() { ping_state_ = PINGING; } 421 void Activate() { ping_state_ = PINGING; }
422 422
423 void Deactivate() { 423 void Deactivate() {
424 ClearTick(&ping_time_); 424 ClearTick(&ping_time_);
425 ping_state_ = NOT_PINGING; 425 ping_state_ = NOT_PINGING;
426 } 426 }
427 427
428 void OnPongReceived() { ClearTick(&ping_time_); } 428 void OnPongReceived() { ClearTick(&ping_time_); }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 ServiceWorkerStatusCode status = embedded_worker_->Stop(); 593 ServiceWorkerStatusCode status = embedded_worker_->Stop();
594 if (status != SERVICE_WORKER_OK) { 594 if (status != SERVICE_WORKER_OK) {
595 RunSoon(base::Bind(callback, status)); 595 RunSoon(base::Bind(callback, status));
596 return; 596 return;
597 } 597 }
598 } 598 }
599 stop_callbacks_.push_back(callback); 599 stop_callbacks_.push_back(callback);
600 } 600 }
601 601
602 void ServiceWorkerVersion::ScheduleUpdate() { 602 void ServiceWorkerVersion::ScheduleUpdate() {
603 if (!context_)
604 return;
603 if (update_timer_.IsRunning()) { 605 if (update_timer_.IsRunning()) {
604 update_timer_.Reset(); 606 update_timer_.Reset();
605 return; 607 return;
606 } 608 }
607 update_timer_.Start( 609 if (is_update_scheduled_)
608 FROM_HERE, base::TimeDelta::FromSeconds(kUpdateDelaySeconds), 610 return;
609 base::Bind(&ServiceWorkerVersion::StartUpdate, 611 is_update_scheduled_ = true;
612
613 // Protect |this| until the timer fires, since we may be stopping
614 // and soon no one might hold a reference to us.
615 context_->ProtectVersion(make_scoped_refptr(this));
616 update_timer_.Start(FROM_HERE,
617 base::TimeDelta::FromSeconds(kUpdateDelaySeconds),
618 base::Bind(&ServiceWorkerVersion::StartUpdate,
619 weak_factory_.GetWeakPtr()));
620 }
621
622 void ServiceWorkerVersion::StartUpdate() {
623 if (!context_)
624 return;
625 context_->storage()->FindRegistrationForId(
626 registration_id_, scope_.GetOrigin(),
627 base::Bind(&ServiceWorkerVersion::FoundRegistrationForUpdate,
610 weak_factory_.GetWeakPtr())); 628 weak_factory_.GetWeakPtr()));
611 } 629 }
612 630
613 void ServiceWorkerVersion::DeferScheduledUpdate() { 631 void ServiceWorkerVersion::DeferScheduledUpdate() {
614 if (update_timer_.IsRunning()) 632 if (update_timer_.IsRunning())
615 update_timer_.Reset(); 633 update_timer_.Reset();
616 } 634 }
617 635
618 void ServiceWorkerVersion::StartUpdate() {
619 update_timer_.Stop();
620 if (!context_)
621 return;
622 ServiceWorkerRegistration* registration =
623 context_->GetLiveRegistration(registration_id_);
624 if (!registration || !registration->GetNewestVersion())
625 return;
626 context_->UpdateServiceWorker(registration, false /* force_bypass_cache */);
627 }
628
629 void ServiceWorkerVersion::DispatchMessageEvent( 636 void ServiceWorkerVersion::DispatchMessageEvent(
630 const base::string16& message, 637 const base::string16& message,
631 const std::vector<TransferredMessagePort>& sent_message_ports, 638 const std::vector<TransferredMessagePort>& sent_message_ports,
632 const StatusCallback& callback) { 639 const StatusCallback& callback) {
633 for (const TransferredMessagePort& port : sent_message_ports) { 640 for (const TransferredMessagePort& port : sent_message_ports) {
634 MessagePortService::GetInstance()->HoldMessages(port.id); 641 MessagePortService::GetInstance()->HoldMessages(port.id);
635 } 642 }
636 643
637 DispatchMessageEventInternal(message, sent_message_ports, callback); 644 DispatchMessageEventInternal(message, sent_message_ports, callback);
638 } 645 }
(...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 RecordStartWorkerResult(status); 1725 RecordStartWorkerResult(status);
1719 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); 1726 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
1720 return; 1727 return;
1721 } 1728 }
1722 if (is_redundant()) { 1729 if (is_redundant()) {
1723 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT); 1730 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT);
1724 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); 1731 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT));
1725 return; 1732 return;
1726 } 1733 }
1727 1734
1735 MarkIfStale();
1736
1728 switch (running_status()) { 1737 switch (running_status()) {
1729 case RUNNING: 1738 case RUNNING:
1730 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); 1739 RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
1731 return; 1740 return;
1732 case STOPPING: 1741 case STOPPING:
1733 case STOPPED: 1742 case STOPPED:
1734 case STARTING: 1743 case STARTING:
1735 if (start_callbacks_.empty()) { 1744 if (start_callbacks_.empty()) {
1736 start_callbacks_.push_back( 1745 start_callbacks_.push_back(
1737 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, 1746 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 // Ping will be activated in OnScriptLoaded. 1839 // Ping will be activated in OnScriptLoaded.
1831 ping_controller_->Deactivate(); 1840 ping_controller_->Deactivate();
1832 1841
1833 timeout_timer_.Start(FROM_HERE, 1842 timeout_timer_.Start(FROM_HERE,
1834 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), 1843 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds),
1835 this, &ServiceWorkerVersion::OnTimeoutTimer); 1844 this, &ServiceWorkerVersion::OnTimeoutTimer);
1836 } 1845 }
1837 1846
1838 void ServiceWorkerVersion::StopTimeoutTimer() { 1847 void ServiceWorkerVersion::StopTimeoutTimer() {
1839 timeout_timer_.Stop(); 1848 timeout_timer_.Stop();
1849
1850 // Trigger update if worker is stale.
1851 if (!stale_time_.is_null()) {
1852 ClearTick(&stale_time_);
1853 if (!update_timer_.IsRunning())
1854 ScheduleUpdate();
1855 }
1840 } 1856 }
1841 1857
1842 void ServiceWorkerVersion::OnTimeoutTimer() { 1858 void ServiceWorkerVersion::OnTimeoutTimer() {
1843 DCHECK(running_status() == STARTING || running_status() == RUNNING || 1859 DCHECK(running_status() == STARTING || running_status() == RUNNING ||
1844 running_status() == STOPPING) 1860 running_status() == STOPPING)
1845 << running_status(); 1861 << running_status();
1846 1862
1863 MarkIfStale();
1864
1865 // Trigger update if worker is stale and we waited long enough for it to go
1866 // idle.
1867 if (GetTickDuration(stale_time_) >
1868 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) {
1869 ClearTick(&stale_time_);
1870 if (!update_timer_.IsRunning())
1871 ScheduleUpdate();
1872 }
1873
1847 // Starting a worker hasn't finished within a certain period. 1874 // Starting a worker hasn't finished within a certain period.
1848 if (GetTickDuration(start_time_) > 1875 if (GetTickDuration(start_time_) >
1849 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { 1876 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) {
1850 DCHECK(running_status() == STARTING || running_status() == STOPPING) 1877 DCHECK(running_status() == STARTING || running_status() == STOPPING)
1851 << running_status(); 1878 << running_status();
1852 scoped_refptr<ServiceWorkerVersion> protect(this); 1879 scoped_refptr<ServiceWorkerVersion> protect(this);
1853 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); 1880 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT);
1854 if (running_status() == STARTING) 1881 if (running_status() == STARTING)
1855 embedded_worker_->Stop(); 1882 embedded_worker_->Stop();
1856 return; 1883 return;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 case net::ERR_ABORTED: 2076 case net::ERR_ABORTED:
2050 return SERVICE_WORKER_ERROR_ABORT; 2077 return SERVICE_WORKER_ERROR_ABORT;
2051 default: 2078 default:
2052 return SERVICE_WORKER_ERROR_NETWORK; 2079 return SERVICE_WORKER_ERROR_NETWORK;
2053 } 2080 }
2054 } 2081 }
2055 2082
2056 return default_code; 2083 return default_code;
2057 } 2084 }
2058 2085
2086 void ServiceWorkerVersion::MarkIfStale() {
2087 if (!context_)
2088 return;
2089 if (update_timer_.IsRunning() || !stale_time_.is_null())
2090 return;
2091 ServiceWorkerRegistration* registration =
2092 context_->GetLiveRegistration(registration_id_);
2093 if (!registration || registration->active_version() != this)
2094 return;
2095 base::TimeDelta time_since_last_check =
2096 base::Time::Now() - registration->last_update_check();
2097 if (time_since_last_check >
2098 base::TimeDelta::FromHours(kServiceWorkerScriptMaxCacheAgeInHours))
2099 RestartTick(&stale_time_);
2100 }
2101
2102 void ServiceWorkerVersion::FoundRegistrationForUpdate(
2103 ServiceWorkerStatusCode status,
2104 const scoped_refptr<ServiceWorkerRegistration>& registration) {
2105 if (!context_)
2106 return;
2107
2108 const scoped_refptr<ServiceWorkerVersion> protect = this;
2109 if (is_update_scheduled_) {
2110 context_->UnprotectVersion(version_id_);
2111 is_update_scheduled_ = false;
2112 }
2113
2114 if (status != SERVICE_WORKER_OK || registration->active_version() != this)
2115 return;
2116 context_->UpdateServiceWorker(registration.get(),
2117 false /* force_bypass_cache */);
2118 }
2119
2059 } // namespace content 2120 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698