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