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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |