Commit 8266ff12 authored by Kenichi Ishibashi's avatar Kenichi Ishibashi Committed by Commit Bot

service worker: Move resource purge scheduling to storage control impl

This CL moves service worker script resource purging logic from
ServiceWorkerRegistry to ServiceWorkerStorageControlImpl. See [1] for
the motivation and how the new purging logic would work.

[1] https://docs.google.com/document/d/1VnZN2k9YbpX1Xy-Yvo93DKDnW4-M2W-rwjkGF1swqLo/edit?usp=sharing

Bug: 1055677
Change-Id: I4f8e9a54b47a9ec39538b8126ef8fb3e05f04c3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2348734
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797531}
parent 31fce7e5
...@@ -1164,22 +1164,6 @@ void ServiceWorkerRegistry::DidStoreRegistration( ...@@ -1164,22 +1164,6 @@ void ServiceWorkerRegistry::DidStoreRegistration(
return; return;
} }
// Purge the deleted version's resources now if needed. This is subtle. The
// version might still be used for a long time even after it's deleted. We can
// only purge safely once the version is REDUNDANT, since it will never be
// used again.
//
// If the deleted version's ServiceWorkerVersion doesn't exist, we can assume
// it's effectively REDUNDANT so it's safe to purge now. This is because the
// caller is assumed to promote the new version to active unless the deleted
// version is doing work, and it can't be doing work if it's not live.
//
// If the ServiceWorkerVersion does exist, it triggers purging once it reaches
// REDUNDANT. Otherwise, purging happens on the next browser session (via
// DeleteStaleResources).
if (!context_->GetLiveVersion(deleted_version_id))
storage()->PurgeResources(newly_purgeable_resources);
scoped_refptr<ServiceWorkerRegistration> registration = scoped_refptr<ServiceWorkerRegistration> registration =
context_->GetLiveRegistration(stored_registration_id); context_->GetLiveRegistration(stored_registration_id);
if (registration) { if (registration) {
...@@ -1215,9 +1199,6 @@ void ServiceWorkerRegistry::DidDeleteRegistration( ...@@ -1215,9 +1199,6 @@ void ServiceWorkerRegistry::DidDeleteRegistration(
return; return;
} }
if (!context_->GetLiveVersion(deleted_version_id))
storage()->PurgeResources(newly_purgeable_resources);
scoped_refptr<ServiceWorkerRegistration> registration = scoped_refptr<ServiceWorkerRegistration> registration =
context_->GetLiveRegistration(registration_id); context_->GetLiveRegistration(registration_id);
if (registration) if (registration)
......
...@@ -49,9 +49,18 @@ class ServiceWorkerLiveVersionRefImpl ...@@ -49,9 +49,18 @@ class ServiceWorkerLiveVersionRefImpl
void set_purgeable_resources( void set_purgeable_resources(
const std::vector<int64_t>& purgeable_resources) { const std::vector<int64_t>& purgeable_resources) {
DCHECK(purgeable_resources_.empty()); if (!purgeable_resources_.empty()) {
// This setter method can be called multiple times but the resource ids
// should be the same.
DCHECK(std::set<int64_t>(purgeable_resources_.begin(),
purgeable_resources_.end()) ==
std::set<int64_t>(purgeable_resources.begin(),
purgeable_resources.end()));
return;
}
purgeable_resources_ = purgeable_resources; purgeable_resources_ = purgeable_resources;
} }
const std::vector<int64_t>& purgeable_resources() const { const std::vector<int64_t>& purgeable_resources() const {
return purgeable_resources_; return purgeable_resources_;
} }
...@@ -90,8 +99,7 @@ void ServiceWorkerStorageControlImpl::Bind( ...@@ -90,8 +99,7 @@ void ServiceWorkerStorageControlImpl::Bind(
void ServiceWorkerStorageControlImpl::OnNoLiveVersion(int64_t version_id) { void ServiceWorkerStorageControlImpl::OnNoLiveVersion(int64_t version_id) {
auto it = live_versions_.find(version_id); auto it = live_versions_.find(version_id);
DCHECK(it != live_versions_.end()); DCHECK(it != live_versions_.end());
if (purge_resources_when_no_live_versions_ && if (it->second->purgeable_resources().size() > 0) {
it->second->purgeable_resources().size() > 0) {
storage_->PurgeResources(it->second->purgeable_resources()); storage_->PurgeResources(it->second->purgeable_resources());
} }
live_versions_.erase(it); live_versions_.erase(it);
...@@ -101,11 +109,6 @@ void ServiceWorkerStorageControlImpl::LazyInitializeForTest() { ...@@ -101,11 +109,6 @@ void ServiceWorkerStorageControlImpl::LazyInitializeForTest() {
storage_->LazyInitializeForTest(); storage_->LazyInitializeForTest();
} }
void ServiceWorkerStorageControlImpl::
EnableResourcePurgingOnNoLiveVersionForTest() {
purge_resources_when_no_live_versions_ = true;
}
void ServiceWorkerStorageControlImpl::GetRegisteredOrigins( void ServiceWorkerStorageControlImpl::GetRegisteredOrigins(
GetRegisteredOriginsCallback callback) { GetRegisteredOriginsCallback callback) {
storage_->GetRegisteredOrigins(std::move(callback)); storage_->GetRegisteredOrigins(std::move(callback));
...@@ -469,8 +472,7 @@ ServiceWorkerStorageControlImpl::CreateLiveVersionReferenceRemote( ...@@ -469,8 +472,7 @@ ServiceWorkerStorageControlImpl::CreateLiveVersionReferenceRemote(
void ServiceWorkerStorageControlImpl::MaybePurgeResources( void ServiceWorkerStorageControlImpl::MaybePurgeResources(
int64_t version_id, int64_t version_id,
const std::vector<int64_t>& purgeable_resources) { const std::vector<int64_t>& purgeable_resources) {
if (!purge_resources_when_no_live_versions_ || if (version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
purgeable_resources.size() == 0) { purgeable_resources.size() == 0) {
return; return;
} }
......
...@@ -47,12 +47,6 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl ...@@ -47,12 +47,6 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
void LazyInitializeForTest(); void LazyInitializeForTest();
// When enabled, the instance of this class manages when to purge resources
// (service worker scripts) which are no longer used.
// TODO(crbug.com/1055677): Remove this once resource purging logic is
// completely moved from ServiceWorkerRegistry to this class.
void EnableResourcePurgingOnNoLiveVersionForTest();
private: private:
// storage::mojom::ServiceWorkerStorageControl implementations: // storage::mojom::ServiceWorkerStorageControl implementations:
void GetRegisteredOrigins(GetRegisteredOriginsCallback callback) override; void GetRegisteredOrigins(GetRegisteredOriginsCallback callback) override;
...@@ -199,8 +193,6 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl ...@@ -199,8 +193,6 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
std::unique_ptr<ServiceWorkerLiveVersionRefImpl>> std::unique_ptr<ServiceWorkerLiveVersionRefImpl>>
live_versions_; live_versions_;
bool purge_resources_when_no_live_versions_ = false;
base::WeakPtrFactory<ServiceWorkerStorageControlImpl> weak_ptr_factory_{this}; base::WeakPtrFactory<ServiceWorkerStorageControlImpl> weak_ptr_factory_{this};
}; };
......
...@@ -185,7 +185,6 @@ class ServiceWorkerStorageControlImplTest : public testing::Test { ...@@ -185,7 +185,6 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
/*quota_manager_proxy=*/nullptr); /*quota_manager_proxy=*/nullptr);
storage_impl_ = storage_impl_ =
std::make_unique<ServiceWorkerStorageControlImpl>(std::move(storage)); std::make_unique<ServiceWorkerStorageControlImpl>(std::move(storage));
storage_impl_->EnableResourcePurgingOnNoLiveVersionForTest();
} }
void DestroyStorage() { void DestroyStorage() {
......
...@@ -1481,8 +1481,6 @@ TEST_F(ServiceWorkerResourceStorageTest, ...@@ -1481,8 +1481,6 @@ TEST_F(ServiceWorkerResourceStorageTest,
} }
TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) { TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
registration_->SetWaitingVersion(nullptr);
// Deleting the registration should result in the resources being added to the // Deleting the registration should result in the resources being added to the
// purgeable list and then doomed in the disk cache and removed from that // purgeable list and then doomed in the disk cache and removed from that
// list. // list.
...@@ -1490,9 +1488,15 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) { ...@@ -1490,9 +1488,15 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
storage()->SetPurgingCompleteCallbackForTest(loop.QuitClosure()); storage()->SetPurgingCompleteCallbackForTest(loop.QuitClosure());
EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
DeleteRegistration(registration_, scope_.GetOrigin())); DeleteRegistration(registration_, scope_.GetOrigin()));
// At this point registration_->waiting_version() has a remote reference, so
// the resources should be in the purgeable list.
EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size()); EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size());
registration_->SetWaitingVersion(nullptr);
loop.Run(); loop.Run();
// registration_->waiting_version() is cleared. The resources should be
// purged at this point.
EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty()); EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty());
EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id1_, false)); EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id1_, false));
EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id2_, false)); EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id2_, false));
...@@ -1770,9 +1774,6 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration_NoLiveVersion) { ...@@ -1770,9 +1774,6 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration_NoLiveVersion) {
live_version->set_fetch_handler_existence( live_version->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS); ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
// Destroy the active version.
registration_->UnsetVersion(registration_->active_version());
// Writing the registration should purge the old version's resources, // Writing the registration should purge the old version's resources,
// since it's not live. // since it's not live.
base::RunLoop loop; base::RunLoop loop;
...@@ -1782,6 +1783,9 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration_NoLiveVersion) { ...@@ -1782,6 +1783,9 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration_NoLiveVersion) {
StoreRegistration(registration_.get(), registration_->waiting_version())); StoreRegistration(registration_.get(), registration_->waiting_version()));
EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size()); EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size());
// Destroy the active version.
registration_->UnsetVersion(registration_->active_version());
// The resources should be purged. // The resources should be purged.
loop.Run(); loop.Run();
EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty()); EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty());
......
...@@ -374,11 +374,9 @@ void ServiceWorkerVersion::SetStatus(Status status) { ...@@ -374,11 +374,9 @@ void ServiceWorkerVersion::SetStatus(Status status) {
} else if (status == REDUNDANT) { } else if (status == REDUNDANT) {
embedded_worker_->OnWorkerVersionDoomed(); embedded_worker_->OnWorkerVersionDoomed();
// Tell the storage system that this worker's script resources can now be // Drop the remote reference to tell the storage system that the worker
// deleted. // script resources can now be deleted.
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources; remote_reference_.reset();
script_cache_map_.GetResources(&resources);
context_->storage()->PurgeResources(resources);
} }
} }
......
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