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

Unified Diff: content/browser/service_worker/service_worker_version.cc

Issue 1525743002: Allow ServiceWorker events to have custom durations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use std::move instead of .Pass Created 5 years 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_version.cc
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 4fd441b8058715f9586bf91b372e1d6f08006a12..3c7f105dd70b767fe2139bed41f93dc253fdf186 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -329,6 +329,12 @@ void RestartTick(base::TimeTicks* time) {
*time = base::TimeTicks().Now();
}
+bool RequestExpired(const base::TimeTicks& expiration) {
+ if (expiration.is_null())
+ return false;
+ return base::TimeTicks().Now() >= expiration;
+}
+
base::TimeDelta GetTickDuration(const base::TimeTicks& time) {
if (time.is_null())
return base::TimeDelta();
@@ -803,6 +809,7 @@ void ServiceWorkerVersion::DispatchFetchEvent(
void ServiceWorkerVersion::DispatchSyncEvent(
BackgroundSyncRegistrationHandle::HandleId handle_id,
BackgroundSyncEventLastChance last_chance,
+ base::TimeDelta max_duration,
const StatusCallback& callback) {
OnBeginEvent();
DCHECK_EQ(ACTIVATED, status()) << status();
@@ -811,11 +818,13 @@ void ServiceWorkerVersion::DispatchSyncEvent(
StartWorker(base::Bind(
&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), callback,
base::Bind(&self::DispatchSyncEvent, weak_factory_.GetWeakPtr(),
- handle_id, last_chance, callback)));
+ handle_id, last_chance, max_duration, callback)));
return;
}
- int request_id = AddRequest(callback, &sync_requests_, REQUEST_SYNC);
+ int request_id =
+ AddRequestWithExpiration(callback, &sync_requests_, REQUEST_SYNC,
+ base::TimeTicks::Now() + max_duration);
if (!background_sync_dispatcher_) {
embedded_worker_->GetServiceRegistry()->ConnectToRemoteService(
mojo::GetProxy(&background_sync_dispatcher_));
@@ -1079,7 +1088,7 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
skip_recording_startup_time_ = true;
// Cancel request timeouts.
- SetAllRequestTimes(base::TimeTicks());
+ SetAllRequestExpirations(base::TimeTicks());
return;
}
if (!start_callbacks_.empty()) {
@@ -1090,8 +1099,10 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
RestartTick(&start_time_);
}
- // Reactivate request timeouts.
- SetAllRequestTimes(base::TimeTicks::Now());
+ // Reactivate request timeouts, setting them all to the same expiration time.
+ SetAllRequestExpirations(
+ base::TimeTicks::Now() +
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes));
}
void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
@@ -1110,15 +1121,20 @@ ServiceWorkerVersion::GetMainScriptHttpResponseInfo() {
return main_script_http_info_.get();
}
-ServiceWorkerVersion::RequestInfo::RequestInfo(int id,
- RequestType type,
- const base::TimeTicks& now)
- : id(id), type(type), time(now) {
-}
+ServiceWorkerVersion::RequestInfo::RequestInfo(
+ int id,
+ RequestType type,
+ const base::TimeTicks& expiration)
+ : id(id), type(type), expiration(expiration) {}
ServiceWorkerVersion::RequestInfo::~RequestInfo() {
}
+bool ServiceWorkerVersion::RequestInfo::operator>(
+ const RequestInfo& other) const {
+ return expiration > other.expiration;
+}
+
template <typename CallbackType>
ServiceWorkerVersion::PendingRequest<CallbackType>::PendingRequest(
const CallbackType& callback,
@@ -1433,10 +1449,13 @@ void ServiceWorkerVersion::OnSyncEventFinished(
"Request id", request_id);
PendingRequest<StatusCallback>* request = sync_requests_.Lookup(request_id);
if (!request) {
- NOTREACHED() << "Got unexpected message: " << request_id;
+ // Assume the request timed out.
return;
}
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.BackgroundSyncEvent.Time",
+ base::TimeTicks::Now() - request->start_time);
+
scoped_refptr<ServiceWorkerVersion> protect(this);
request->callback.Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status));
RemoveCallbackAndStopIfRedundant(&sync_requests_, request_id);
@@ -2119,21 +2138,20 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
return;
}
- // Requests have not finished within a certain period.
- bool request_timed_out = false;
+ // Requests have not finished before their expiration.
+ bool stop_for_timeout = false;
while (!requests_.empty()) {
- RequestInfo info = requests_.front();
- if (GetTickDuration(info.time) <
- base::TimeDelta::FromMinutes(kRequestTimeoutMinutes))
+ RequestInfo info = requests_.top();
+ if (!RequestExpired(info.expiration))
break;
if (MaybeTimeOutRequest(info)) {
- request_timed_out = true;
+ stop_for_timeout = stop_for_timeout || ShouldStopIfRequestTimesOut(info);
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.RequestTimeouts.Count",
info.type, NUM_REQUEST_TYPES);
}
requests_.pop();
}
- if (request_timed_out && running_status() != STOPPING)
+ if (stop_for_timeout && running_status() != STOPPING)
embedded_worker_->Stop();
// For the timeouts below, there are no callbacks to timeout so there is
@@ -2240,10 +2258,22 @@ int ServiceWorkerVersion::AddRequest(
const CallbackType& callback,
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
RequestType request_type) {
- base::TimeTicks now = base::TimeTicks::Now();
- int request_id =
- callback_map->Add(new PendingRequest<CallbackType>(callback, now));
- requests_.push(RequestInfo(request_id, request_type, now));
+ base::TimeTicks expiration_time =
+ base::TimeTicks::Now() +
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes);
+ return AddRequestWithExpiration(callback, callback_map, request_type,
+ expiration_time);
+}
+
+template <typename CallbackType>
+int ServiceWorkerVersion::AddRequestWithExpiration(
+ const CallbackType& callback,
+ IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map,
+ RequestType request_type,
+ base::TimeTicks expiration) {
+ int request_id = callback_map->Add(
+ new PendingRequest<CallbackType>(callback, base::TimeTicks::Now()));
+ requests_.push(RequestInfo(request_id, request_type, expiration));
return request_id;
}
@@ -2284,11 +2314,35 @@ bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) {
return false;
}
-void ServiceWorkerVersion::SetAllRequestTimes(const base::TimeTicks& ticks) {
- std::queue<RequestInfo> new_requests;
+bool ServiceWorkerVersion::ShouldStopIfRequestTimesOut(
+ const RequestInfo& info) {
+ // Note, returning false for a type means that the On*EventFinished should not
+ // call NOTREACHED if it can't find the matching request, it may have simply
+ // timed out.
+ switch (info.type) {
+ case REQUEST_SYNC:
+ return false;
+ case REQUEST_ACTIVATE:
+ case REQUEST_INSTALL:
+ case REQUEST_FETCH:
+ case REQUEST_NOTIFICATION_CLICK:
+ case REQUEST_PUSH:
+ case REQUEST_GEOFENCING:
+ case REQUEST_SERVICE_PORT_CONNECT:
+ return true;
+ case NUM_REQUEST_TYPES:
+ NOTREACHED() << "Got unexpected request type: " << info.type;
+ }
+ NOTREACHED() << "Got unexpected request type: " << info.type;
+ return false;
+}
+
+void ServiceWorkerVersion::SetAllRequestExpirations(
+ const base::TimeTicks& expiration) {
+ RequestInfoPriorityQueue new_requests;
while (!requests_.empty()) {
- RequestInfo info = requests_.front();
- info.time = ticks;
+ RequestInfo info = requests_.top();
+ info.expiration = expiration;
new_requests.push(info);
requests_.pop();
}

Powered by Google App Engine
This is Rietveld 408576698