Commit 044a4964 authored by xiang.long's avatar xiang.long Committed by Commit bot

ServiceWorker: Make claim() uses living matching registrations instead of fetching from DB.

Registration can leverage ServiceWorkerProviderHost's MatchRegistration()
method to check whether it is the right registration to claim that client.
So the claim() processing in browser process could be implemented without
hitting the DB to achieve better performance.

BUG=454250
TEST=http/tests/serviceworker/claim*

Review URL: https://codereview.chromium.org/1013423002

Cr-Commit-Position: refs/heads/master@{#322123}
parent 98e56384
...@@ -162,14 +162,21 @@ void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { ...@@ -162,14 +162,21 @@ void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
ActivateWaitingVersion(); ActivateWaitingVersion();
} }
void ServiceWorkerRegistration::ClaimClients(const StatusCallback& callback) { void ServiceWorkerRegistration::ClaimClients() {
DCHECK(context_); DCHECK(context_);
DCHECK(active_version()); DCHECK(active_version());
// TODO(xiang): Should better not hit the database http://crbug.com/454250.
context_->storage()->GetRegistrationsForOrigin( for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
pattern_.GetOrigin(), context_->GetProviderHostIterator();
base::Bind(&ServiceWorkerRegistration::DidGetRegistrationsForClaimClients, !it->IsAtEnd(); it->Advance()) {
this, callback, active_version_)); ServiceWorkerProviderHost* host = it->GetProviderHost();
if (host->IsHostToRunningServiceWorker())
continue;
if (host->controlling_version() == active_version())
continue;
if (host->MatchRegistration() == this)
host->ClaimedByRegistration(this);
}
} }
void ServiceWorkerRegistration::ClearWhenReady() { void ServiceWorkerRegistration::ClearWhenReady() {
...@@ -375,50 +382,4 @@ void ServiceWorkerRegistration::OnRestoreFinished( ...@@ -375,50 +382,4 @@ void ServiceWorkerRegistration::OnRestoreFinished(
callback.Run(status); callback.Run(status);
} }
void ServiceWorkerRegistration::DidGetRegistrationsForClaimClients(
const StatusCallback& callback,
scoped_refptr<ServiceWorkerVersion> version,
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
if (!context_) {
callback.Run(SERVICE_WORKER_ERROR_ABORT);
return;
}
if (!active_version() || version != active_version()) {
callback.Run(SERVICE_WORKER_ERROR_STATE);
return;
}
for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
context_->GetProviderHostIterator();
!it->IsAtEnd(); it->Advance()) {
ServiceWorkerProviderHost* host = it->GetProviderHost();
if (ShouldClaim(host, registrations))
host->ClaimedByRegistration(this);
}
callback.Run(SERVICE_WORKER_OK);
}
bool ServiceWorkerRegistration::ShouldClaim(
ServiceWorkerProviderHost* provider_host,
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
if (provider_host->IsHostToRunningServiceWorker())
return false;
if (provider_host->controlling_version() == active_version())
return false;
LongestScopeMatcher matcher(provider_host->document_url());
if (!matcher.MatchLongest(pattern_))
return false;
for (const ServiceWorkerRegistrationInfo& info : registrations) {
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(info.registration_id);
if (registration &&
(registration->is_uninstalling() || registration->is_uninstalled()))
continue;
if (matcher.MatchLongest(info.pattern))
return false;
}
return true;
}
} // namespace content } // namespace content
...@@ -111,7 +111,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration ...@@ -111,7 +111,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
// Takes over control of provider hosts which are currently not controlled or // Takes over control of provider hosts which are currently not controlled or
// controlled by other registrations. // controlled by other registrations.
void ClaimClients(const StatusCallback& callback); void ClaimClients();
// Triggers the [[ClearRegistration]] algorithm when the currently // Triggers the [[ClearRegistration]] algorithm when the currently
// active version has no controllees. Deletes this registration // active version has no controllees. Deletes this registration
...@@ -167,14 +167,6 @@ class CONTENT_EXPORT ServiceWorkerRegistration ...@@ -167,14 +167,6 @@ class CONTENT_EXPORT ServiceWorkerRegistration
scoped_refptr<ServiceWorkerVersion> version, scoped_refptr<ServiceWorkerVersion> version,
ServiceWorkerStatusCode status); ServiceWorkerStatusCode status);
void DidGetRegistrationsForClaimClients(
const StatusCallback& callback,
scoped_refptr<ServiceWorkerVersion> version,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
bool ShouldClaim(
ServiceWorkerProviderHost* provider_host,
const std::vector<ServiceWorkerRegistrationInfo>& registration_infos);
const GURL pattern_; const GURL pattern_;
const int64 registration_id_; const int64 registration_id_;
bool is_deleted_; bool is_deleted_;
......
...@@ -1396,24 +1396,25 @@ void ServiceWorkerVersion::DidSkipWaiting(int request_id) { ...@@ -1396,24 +1396,25 @@ void ServiceWorkerVersion::DidSkipWaiting(int request_id) {
} }
void ServiceWorkerVersion::OnClaimClients(int request_id) { void ServiceWorkerVersion::OnClaimClients(int request_id) {
StatusCallback callback = base::Bind(&ServiceWorkerVersion::DidClaimClients,
weak_factory_.GetWeakPtr(), request_id);
if (status_ != ACTIVATING && status_ != ACTIVATED) { if (status_ != ACTIVATING && status_ != ACTIVATED) {
callback.Run(SERVICE_WORKER_ERROR_STATE); embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
request_id, blink::WebServiceWorkerError::ErrorTypeState,
base::ASCIIToUTF16(kClaimClientsStateErrorMesage)));
return; return;
} }
if (!context_) { if (context_) {
callback.Run(SERVICE_WORKER_ERROR_ABORT); if (ServiceWorkerRegistration* registration =
return; context_->GetLiveRegistration(registration_id_)) {
registration->ClaimClients();
embedded_worker_->SendMessage(
ServiceWorkerMsg_DidClaimClients(request_id));
return;
}
} }
ServiceWorkerRegistration* registration = embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
context_->GetLiveRegistration(registration_id_); request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
if (!registration) { base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage)));
callback.Run(SERVICE_WORKER_ERROR_ABORT);
return;
}
registration->ClaimClients(callback);
} }
void ServiceWorkerVersion::OnPongFromWorker() { void ServiceWorkerVersion::OnPongFromWorker() {
...@@ -1462,24 +1463,6 @@ void ServiceWorkerVersion::StartWorkerInternal(bool pause_after_download) { ...@@ -1462,24 +1463,6 @@ void ServiceWorkerVersion::StartWorkerInternal(bool pause_after_download) {
} }
} }
void ServiceWorkerVersion::DidClaimClients(
int request_id, ServiceWorkerStatusCode status) {
if (status == SERVICE_WORKER_ERROR_STATE) {
embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
request_id, blink::WebServiceWorkerError::ErrorTypeState,
base::ASCIIToUTF16(kClaimClientsStateErrorMesage)));
return;
}
if (status == SERVICE_WORKER_ERROR_ABORT) {
embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage)));
return;
}
DCHECK(status == SERVICE_WORKER_OK);
embedded_worker_->SendMessage(ServiceWorkerMsg_DidClaimClients(request_id));
}
void ServiceWorkerVersion::DidGetClients( void ServiceWorkerVersion::DidGetClients(
int request_id, int request_id,
const std::vector<ServiceWorkerClientInfo>& clients) { const std::vector<ServiceWorkerClientInfo>& clients) {
......
...@@ -398,7 +398,6 @@ class CONTENT_EXPORT ServiceWorkerVersion ...@@ -398,7 +398,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
void StartWorkerInternal(bool pause_after_download); void StartWorkerInternal(bool pause_after_download);
void DidSkipWaiting(int request_id); void DidSkipWaiting(int request_id);
void DidClaimClients(int request_id, ServiceWorkerStatusCode status);
void DidGetClients( void DidGetClients(
int request_id, const std::vector<ServiceWorkerClientInfo>& clients); int request_id, const std::vector<ServiceWorkerClientInfo>& clients);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment