Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 (update_timer_.IsRunning()) { | 603 if (update_timer_.IsRunning()) { |
| 604 update_timer_.Reset(); | 604 update_timer_.Reset(); |
| 605 return; | 605 return; |
| 606 } | 606 } |
| 607 update_timer_.Start( | 607 |
| 608 FROM_HERE, base::TimeDelta::FromSeconds(kUpdateDelaySeconds), | 608 if (is_update_scheduled_) |
| 609 base::Bind(&ServiceWorkerVersion::StartUpdate, | 609 return; |
| 610 is_update_scheduled_ = true; | |
| 611 | |
| 612 // Protect |this| until the timer fires, since we may be stopping | |
| 613 // and soon no one might hold a reference to us. | |
| 614 context_->ProtectVersion(make_scoped_refptr(this)); | |
|
nhiroki
2015/06/24 05:14:41
Can you check |context| before accessing?
falken
2015/06/24 07:58:10
Done.
| |
| 615 update_timer_.Start(FROM_HERE, | |
| 616 base::TimeDelta::FromSeconds(kUpdateDelaySeconds), | |
| 617 base::Bind(&ServiceWorkerVersion::StartUpdate, | |
| 618 weak_factory_.GetWeakPtr())); | |
| 619 } | |
| 620 | |
| 621 void ServiceWorkerVersion::StartUpdate() { | |
| 622 if (!context_) | |
| 623 return; | |
| 624 context_->storage()->FindRegistrationForId( | |
| 625 registration_id_, scope_.GetOrigin(), | |
| 626 base::Bind(&ServiceWorkerVersion::FoundRegistrationForUpdate, | |
| 610 weak_factory_.GetWeakPtr())); | 627 weak_factory_.GetWeakPtr())); |
| 611 } | 628 } |
| 612 | 629 |
| 613 void ServiceWorkerVersion::DeferScheduledUpdate() { | 630 void ServiceWorkerVersion::DeferScheduledUpdate() { |
| 614 if (update_timer_.IsRunning()) | 631 if (update_timer_.IsRunning()) |
| 615 update_timer_.Reset(); | 632 update_timer_.Reset(); |
| 616 } | 633 } |
| 617 | 634 |
| 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( | 635 void ServiceWorkerVersion::DispatchMessageEvent( |
| 630 const base::string16& message, | 636 const base::string16& message, |
| 631 const std::vector<TransferredMessagePort>& sent_message_ports, | 637 const std::vector<TransferredMessagePort>& sent_message_ports, |
| 632 const StatusCallback& callback) { | 638 const StatusCallback& callback) { |
| 633 for (const TransferredMessagePort& port : sent_message_ports) { | 639 for (const TransferredMessagePort& port : sent_message_ports) { |
| 634 MessagePortService::GetInstance()->HoldMessages(port.id); | 640 MessagePortService::GetInstance()->HoldMessages(port.id); |
| 635 } | 641 } |
| 636 | 642 |
| 637 DispatchMessageEventInternal(message, sent_message_ports, callback); | 643 DispatchMessageEventInternal(message, sent_message_ports, callback); |
| 638 } | 644 } |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1718 RecordStartWorkerResult(status); | 1724 RecordStartWorkerResult(status); |
| 1719 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 1725 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |
| 1720 return; | 1726 return; |
| 1721 } | 1727 } |
| 1722 if (is_redundant()) { | 1728 if (is_redundant()) { |
| 1723 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT); | 1729 RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT); |
| 1724 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); | 1730 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); |
| 1725 return; | 1731 return; |
| 1726 } | 1732 } |
| 1727 | 1733 |
| 1734 MarkIfStale(); | |
| 1735 | |
| 1728 switch (running_status()) { | 1736 switch (running_status()) { |
| 1729 case RUNNING: | 1737 case RUNNING: |
| 1730 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 1738 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 1731 return; | 1739 return; |
| 1732 case STOPPING: | 1740 case STOPPING: |
| 1733 case STOPPED: | 1741 case STOPPED: |
| 1734 case STARTING: | 1742 case STARTING: |
| 1735 if (start_callbacks_.empty()) { | 1743 if (start_callbacks_.empty()) { |
| 1736 start_callbacks_.push_back( | 1744 start_callbacks_.push_back( |
| 1737 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, | 1745 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1830 // Ping will be activated in OnScriptLoaded. | 1838 // Ping will be activated in OnScriptLoaded. |
| 1831 ping_controller_->Deactivate(); | 1839 ping_controller_->Deactivate(); |
| 1832 | 1840 |
| 1833 timeout_timer_.Start(FROM_HERE, | 1841 timeout_timer_.Start(FROM_HERE, |
| 1834 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), | 1842 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), |
| 1835 this, &ServiceWorkerVersion::OnTimeoutTimer); | 1843 this, &ServiceWorkerVersion::OnTimeoutTimer); |
| 1836 } | 1844 } |
| 1837 | 1845 |
| 1838 void ServiceWorkerVersion::StopTimeoutTimer() { | 1846 void ServiceWorkerVersion::StopTimeoutTimer() { |
| 1839 timeout_timer_.Stop(); | 1847 timeout_timer_.Stop(); |
| 1848 | |
| 1849 // Trigger update if worker is stale. | |
| 1850 if (!stale_time_.is_null()) { | |
| 1851 ClearTick(&stale_time_); | |
| 1852 if (!update_timer_.IsRunning()) | |
| 1853 ScheduleUpdate(); | |
| 1854 } | |
| 1840 } | 1855 } |
| 1841 | 1856 |
| 1842 void ServiceWorkerVersion::OnTimeoutTimer() { | 1857 void ServiceWorkerVersion::OnTimeoutTimer() { |
| 1843 DCHECK(running_status() == STARTING || running_status() == RUNNING || | 1858 DCHECK(running_status() == STARTING || running_status() == RUNNING || |
| 1844 running_status() == STOPPING) | 1859 running_status() == STOPPING) |
| 1845 << running_status(); | 1860 << running_status(); |
| 1846 | 1861 |
| 1862 MarkIfStale(); | |
| 1863 | |
| 1864 // Trigger update if worker is stale and we waited long enough for it to go | |
| 1865 // idle. | |
| 1866 if (GetTickDuration(stale_time_) > | |
| 1867 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) { | |
| 1868 ClearTick(&stale_time_); | |
| 1869 if (!update_timer_.IsRunning()) | |
| 1870 ScheduleUpdate(); | |
| 1871 } | |
| 1872 | |
| 1847 // Starting a worker hasn't finished within a certain period. | 1873 // Starting a worker hasn't finished within a certain period. |
| 1848 if (GetTickDuration(start_time_) > | 1874 if (GetTickDuration(start_time_) > |
| 1849 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { | 1875 base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes)) { |
| 1850 DCHECK(running_status() == STARTING || running_status() == STOPPING) | 1876 DCHECK(running_status() == STARTING || running_status() == STOPPING) |
| 1851 << running_status(); | 1877 << running_status(); |
| 1852 scoped_refptr<ServiceWorkerVersion> protect(this); | 1878 scoped_refptr<ServiceWorkerVersion> protect(this); |
| 1853 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); | 1879 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); |
| 1854 if (running_status() == STARTING) | 1880 if (running_status() == STARTING) |
| 1855 embedded_worker_->Stop(); | 1881 embedded_worker_->Stop(); |
| 1856 return; | 1882 return; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2049 case net::ERR_ABORTED: | 2075 case net::ERR_ABORTED: |
| 2050 return SERVICE_WORKER_ERROR_ABORT; | 2076 return SERVICE_WORKER_ERROR_ABORT; |
| 2051 default: | 2077 default: |
| 2052 return SERVICE_WORKER_ERROR_NETWORK; | 2078 return SERVICE_WORKER_ERROR_NETWORK; |
| 2053 } | 2079 } |
| 2054 } | 2080 } |
| 2055 | 2081 |
| 2056 return default_code; | 2082 return default_code; |
| 2057 } | 2083 } |
| 2058 | 2084 |
| 2085 void ServiceWorkerVersion::MarkIfStale() { | |
| 2086 if (!context_) | |
| 2087 return; | |
| 2088 if (update_timer_.IsRunning() || !stale_time_.is_null()) | |
| 2089 return; | |
| 2090 ServiceWorkerRegistration* registration = | |
| 2091 context_->GetLiveRegistration(registration_id_); | |
| 2092 if (!registration || registration->active_version() != this) | |
| 2093 return; | |
| 2094 base::TimeDelta time_since_last_check = | |
| 2095 base::Time::Now() - registration->last_update_check(); | |
| 2096 if (time_since_last_check > | |
| 2097 base::TimeDelta::FromHours(kServiceWorkerScriptMaxCacheAgeInHours)) | |
| 2098 RestartTick(&stale_time_); | |
| 2099 } | |
| 2100 | |
| 2101 void ServiceWorkerVersion::FoundRegistrationForUpdate( | |
| 2102 ServiceWorkerStatusCode status, | |
| 2103 const scoped_refptr<ServiceWorkerRegistration>& registration) { | |
| 2104 if (!context_) | |
| 2105 return; | |
| 2106 const scoped_refptr<ServiceWorkerVersion> protect = this; | |
| 2107 context_->UnprotectVersion(make_scoped_refptr(this)); | |
|
nhiroki
2015/06/24 05:14:41
How about passing "version_id" instead of "make_sc
falken
2015/06/24 07:58:10
Sure, done.
| |
| 2108 is_update_scheduled_ = false; | |
| 2109 if (status != SERVICE_WORKER_OK || registration->active_version() != this) | |
| 2110 return; | |
| 2111 context_->UpdateServiceWorker(registration.get(), | |
| 2112 false /* force_bypass_cache */); | |
| 2113 } | |
| 2114 | |
| 2059 } // namespace content | 2115 } // namespace content |
| OLD | NEW |