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

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

Issue 293483002: Store the service worker script and its imports on first load... really (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix nix compile Created 6 years, 7 months 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_storage.cc
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index a9a5b774ac0597ced39ad398f1b67815c82a5a26..9a79263d718d49b94d630fe81914daa1fcee4091 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -25,17 +25,6 @@ namespace content {
namespace {
-typedef base::Callback<void(
- ServiceWorkerStorage::InitialData* data,
- ServiceWorkerDatabase::Status status)> InitializeCallback;
-typedef base::Callback<void(
- const ServiceWorkerDatabase::RegistrationData& data,
- const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources,
- ServiceWorkerDatabase::Status status)> ReadRegistrationCallback;
-typedef base::Callback<void(
- bool origin_is_deletable,
- ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
-
void RunSoon(const tracked_objects::Location& from_here,
const base::Closure& closure) {
base::MessageLoop::current()->PostTask(from_here, closure);
@@ -60,8 +49,11 @@ const base::FilePath::CharType kServiceWorkerDirectory[] =
FILE_PATH_LITERAL("Service Worker");
const base::FilePath::CharType kDatabaseName[] =
FILE_PATH_LITERAL("Database");
+const base::FilePath::CharType kDiskCacheName[] =
+ FILE_PATH_LITERAL("Cache");
const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
+const int kMaxDiskCacheSize = 250 * 1024 * 1024;
void EmptyCompletionCallback(int) {}
@@ -77,59 +69,6 @@ ServiceWorkerStatusCode DatabaseStatusToStatusCode(
}
}
-void ReadInitialDataFromDB(
- ServiceWorkerDatabase* database,
- scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- const InitializeCallback& callback) {
- DCHECK(database);
- scoped_ptr<ServiceWorkerStorage::InitialData> data(
- new ServiceWorkerStorage::InitialData());
-
- ServiceWorkerDatabase::Status status =
- database->GetNextAvailableIds(&data->next_registration_id,
- &data->next_version_id,
- &data->next_resource_id);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
- return;
- }
-
- status = database->GetOriginsWithRegistrations(&data->origins);
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
-}
-
-void DeleteRegistrationFromDB(
- ServiceWorkerDatabase* database,
- scoped_refptr<base::SequencedTaskRunner> original_task_runner,
- int64 registration_id,
- const GURL& origin,
- const DeleteRegistrationCallback& callback) {
- DCHECK(database);
- ServiceWorkerDatabase::Status status =
- database->DeleteRegistration(registration_id, origin);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, false, status));
- return;
- }
-
- // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
- // unique origin list.
- std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
- status = database->GetRegistrationsForOrigin(origin, &registrations);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, false, status));
- return;
- }
-
- bool deletable = registrations.empty();
- original_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, deletable, status));
-}
-
} // namespace
ServiceWorkerStorage::InitialData::InitialData()
@@ -155,14 +94,11 @@ ServiceWorkerStorage::ServiceWorkerStorage(
database_task_runner_(database_task_runner),
disk_cache_thread_(disk_cache_thread),
quota_manager_proxy_(quota_manager_proxy),
+ is_purge_pending_(false),
weak_factory_(this) {
- if (!path.empty()) {
+ if (!path.empty())
path_ = path.Append(kServiceWorkerDirectory);
- database_.reset(new ServiceWorkerDatabase(path_.Append(kDatabaseName)));
- } else {
- // Create an in-memory database.
- database_.reset(new ServiceWorkerDatabase(base::FilePath()));
- }
+ database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
}
ServiceWorkerStorage::~ServiceWorkerStorage() {
@@ -170,112 +106,107 @@ ServiceWorkerStorage::~ServiceWorkerStorage() {
database_task_runner_->DeleteSoon(FROM_HERE, database_.release());
}
-void ServiceWorkerStorage::FindRegistrationForPattern(
- const GURL& scope,
+void ServiceWorkerStorage::FindRegistrationForDocument(
+ const GURL& document_url,
const FindRegistrationCallback& callback) {
- scoped_refptr<ServiceWorkerRegistration> null_registration;
if (!LazyInitialize(base::Bind(
- &ServiceWorkerStorage::FindRegistrationForPattern,
- weak_factory_.GetWeakPtr(), scope, callback))) {
+ &ServiceWorkerStorage::FindRegistrationForDocument,
+ weak_factory_.GetWeakPtr(), document_url, callback))) {
if (state_ != INITIALIZING || !context_) {
- CompleteFindSoon(FROM_HERE, null_registration,
- SERVICE_WORKER_ERROR_FAILED, callback);
+ CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
+ SERVICE_WORKER_ERROR_FAILED, callback);
}
return;
}
DCHECK_EQ(INITIALIZED, state_);
// See if there are any stored registrations for the origin.
- if (!ContainsKey(registered_origins_, scope.GetOrigin())) {
+ if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
// Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
- FindInstallingRegistrationForPattern(scope);
- if (installing_registration) {
- CompleteFindSoon(
- FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
- return;
- }
- CompleteFindSoon(
- FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
+ FindInstallingRegistrationForDocument(document_url);
+ CompleteFindNow(
+ installing_registration,
+ installing_registration ?
+ SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
+ callback);
return;
}
- RegistrationList* registrations = new RegistrationList();
- PostTaskAndReplyWithResult(
- database_task_runner_,
+ database_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin,
- base::Unretained(database_.get()),
- scope.GetOrigin(), base::Unretained(registrations)),
- base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForPattern,
- weak_factory_.GetWeakPtr(), scope, callback,
- base::Owned(registrations)));
+ base::Bind(
+ &FindForDocumentInDB,
+ database_.get(),
+ base::MessageLoopProxy::current(),
+ document_url,
+ base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument,
+ weak_factory_.GetWeakPtr(), document_url, callback)));
}
-void ServiceWorkerStorage::FindRegistrationForDocument(
- const GURL& document_url,
+void ServiceWorkerStorage::FindRegistrationForPattern(
+ const GURL& scope,
const FindRegistrationCallback& callback) {
- scoped_refptr<ServiceWorkerRegistration> null_registration;
if (!LazyInitialize(base::Bind(
- &ServiceWorkerStorage::FindRegistrationForDocument,
- weak_factory_.GetWeakPtr(), document_url, callback))) {
- if (state_ != INITIALIZING || !context_)
- CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
+ &ServiceWorkerStorage::FindRegistrationForPattern,
+ weak_factory_.GetWeakPtr(), scope, callback))) {
+ if (state_ != INITIALIZING || !context_) {
+ CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(),
+ SERVICE_WORKER_ERROR_FAILED, callback);
+ }
return;
}
DCHECK_EQ(INITIALIZED, state_);
// See if there are any stored registrations for the origin.
- if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
+ if (!ContainsKey(registered_origins_, scope.GetOrigin())) {
// Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
- FindInstallingRegistrationForDocument(document_url);
- if (installing_registration) {
- CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
- return;
- }
- CompleteFindNow(
- null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
+ FindInstallingRegistrationForPattern(scope);
+ CompleteFindSoon(
+ FROM_HERE, installing_registration,
+ installing_registration ?
+ SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
+ callback);
return;
}
- RegistrationList* registrations = new RegistrationList();
- PostTaskAndReplyWithResult(
- database_task_runner_,
+ database_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin,
- base::Unretained(database_.get()),
- document_url.GetOrigin(), base::Unretained(registrations)),
- base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForDocument,
- weak_factory_.GetWeakPtr(), document_url, callback,
- base::Owned(registrations)));
+ base::Bind(
+ &FindForPatternInDB,
+ database_.get(),
+ base::MessageLoopProxy::current(),
+ scope,
+ base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern,
+ weak_factory_.GetWeakPtr(), scope, callback)));
}
void ServiceWorkerStorage::FindRegistrationForId(
int64 registration_id,
const GURL& origin,
const FindRegistrationCallback& callback) {
- scoped_refptr<ServiceWorkerRegistration> null_registration;
if (!LazyInitialize(base::Bind(
&ServiceWorkerStorage::FindRegistrationForId,
weak_factory_.GetWeakPtr(), registration_id, origin, callback))) {
- if (state_ != INITIALIZING || !context_)
- CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
+ if (state_ != INITIALIZING || !context_) {
+ CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
+ SERVICE_WORKER_ERROR_FAILED, callback);
+ }
return;
}
DCHECK_EQ(INITIALIZED, state_);
// See if there are any stored registrations for the origin.
if (!ContainsKey(registered_origins_, origin)) {
- // Look for somthing currently being installed.
+ // Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForId(registration_id);
- if (installing_registration) {
- CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
- return;
- }
CompleteFindNow(
- null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
+ installing_registration,
+ installing_registration ?
+ SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
+ callback);
return;
}
@@ -286,20 +217,14 @@ void ServiceWorkerStorage::FindRegistrationForId(
return;
}
- ServiceWorkerDatabase::RegistrationData* data =
- new ServiceWorkerDatabase::RegistrationData;
- ResourceList* resources = new ResourceList;
- PostTaskAndReplyWithResult(
- database_task_runner_,
+ database_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&ServiceWorkerDatabase::ReadRegistration,
- base::Unretained(database_.get()),
+ base::Bind(&FindForIdInDB,
+ database_.get(),
+ base::MessageLoopProxy::current(),
registration_id, origin,
- base::Unretained(data),
- base::Unretained(resources)),
- base::Bind(&ServiceWorkerStorage::DidReadRegistrationForId,
- weak_factory_.GetWeakPtr(),
- callback, base::Owned(data), base::Owned(resources)));
+ base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId,
+ weak_factory_.GetWeakPtr(), callback)));
}
void ServiceWorkerStorage::GetAllRegistrations(
@@ -351,15 +276,17 @@ void ServiceWorkerStorage::StoreRegistration(
data.is_active = false; // initially stored in the waiting state
ResourceList resources;
- PostTaskAndReplyWithResult(
- database_task_runner_,
+ version->script_cache_map()->GetResources(&resources);
+
+ database_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&ServiceWorkerDatabase::WriteRegistration,
- base::Unretained(database_.get()), data, resources),
- base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
- weak_factory_.GetWeakPtr(),
- registration->script_url().GetOrigin(),
- callback));
+ base::Bind(&WriteRegistrationInDB,
+ database_.get(),
+ base::MessageLoopProxy::current(),
+ data, resources,
+ base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
+ weak_factory_.GetWeakPtr(),
+ callback)));
}
void ServiceWorkerStorage::UpdateToActiveState(
@@ -453,6 +380,18 @@ void ServiceWorkerStorage::NotifyDoneInstallingRegistration(
installing_registrations_.erase(registration->id());
}
+base::FilePath ServiceWorkerStorage::GetDatabasePath() {
+ if (path_.empty())
+ return base::FilePath();
+ return path_.Append(kDatabaseName);
+}
+
+base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
+ if (path_.empty())
+ return base::FilePath();
+ return path_.Append(kDiskCacheName);
+}
+
bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
if (!context_)
return false;
@@ -507,118 +446,70 @@ void ServiceWorkerStorage::DidReadInitialData(
pending_tasks_.clear();
}
-void ServiceWorkerStorage::DidGetRegistrationsForPattern(
- const GURL& scope,
+void ServiceWorkerStorage::DidFindRegistrationForDocument(
+ const GURL& document_url,
const FindRegistrationCallback& callback,
- RegistrationList* registrations,
+ const ServiceWorkerDatabase::RegistrationData& data,
+ const ResourceList& resources,
ServiceWorkerDatabase::Status status) {
- DCHECK(registrations);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- // TODO(nhiroki): Handle database error (http://crbug.com/371675).
- callback.Run(SERVICE_WORKER_ERROR_FAILED,
- scoped_refptr<ServiceWorkerRegistration>());
+ if (status == ServiceWorkerDatabase::STATUS_OK) {
+ callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources));
return;
}
- // Find one with a matching scope.
- for (RegistrationList::const_iterator it = registrations->begin();
- it != registrations->end(); ++it) {
- if (scope == it->scope) {
- scoped_refptr<ServiceWorkerRegistration> registration =
- context_->GetLiveRegistration(it->registration_id);
- if (!registration)
- registration = CreateRegistration(*it);
- callback.Run(SERVICE_WORKER_OK, registration);
- return;
- }
- }
-
- // Look for something currently being installed.
- scoped_refptr<ServiceWorkerRegistration> installing_registration =
- FindInstallingRegistrationForPattern(scope);
- if (installing_registration) {
- callback.Run(SERVICE_WORKER_OK, installing_registration);
+ if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
+ // Look for something currently being installed.
+ scoped_refptr<ServiceWorkerRegistration> installing_registration =
+ FindInstallingRegistrationForDocument(document_url);
+ callback.Run(installing_registration ?
+ SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
+ installing_registration);
return;
}
- callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
+ // TODO(nhiroki): Handle database error (http://crbug.com/371675).
+ callback.Run(DatabaseStatusToStatusCode(status),
scoped_refptr<ServiceWorkerRegistration>());
}
-void ServiceWorkerStorage::DidGetRegistrationsForDocument(
- const GURL& document_url,
+void ServiceWorkerStorage::DidFindRegistrationForPattern(
+ const GURL& scope,
const FindRegistrationCallback& callback,
- RegistrationList* registrations,
+ const ServiceWorkerDatabase::RegistrationData& data,
+ const ResourceList& resources,
ServiceWorkerDatabase::Status status) {
- DCHECK(registrations);
- if (status != ServiceWorkerDatabase::STATUS_OK) {
- // TODO(nhiroki): Handle database error (http://crbug.com/371675).
- callback.Run(SERVICE_WORKER_ERROR_FAILED,
- scoped_refptr<ServiceWorkerRegistration>());
+ if (status == ServiceWorkerDatabase::STATUS_OK) {
+ callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources));
return;
}
- // Find one with a pattern match.
- for (RegistrationList::const_iterator it = registrations->begin();
- it != registrations->end(); ++it) {
- // TODO(michaeln): if there are multiple matches the one with
- // the longest scope should win.
- if (ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) {
- scoped_refptr<ServiceWorkerRegistration> registration =
- context_->GetLiveRegistration(it->registration_id);
- if (registration) {
- callback.Run(SERVICE_WORKER_OK, registration);
- return;
- }
- callback.Run(SERVICE_WORKER_OK, CreateRegistration(*it));
- return;
- }
- }
-
- // Look for something currently being installed.
- // TODO(michaeln): Should be mixed in with the stored registrations
- // for this test.
- scoped_refptr<ServiceWorkerRegistration> installing_registration =
- FindInstallingRegistrationForDocument(document_url);
- if (installing_registration) {
- callback.Run(SERVICE_WORKER_OK, installing_registration);
+ if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
+ scoped_refptr<ServiceWorkerRegistration> installing_registration =
+ FindInstallingRegistrationForPattern(scope);
+ callback.Run(installing_registration ?
+ SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND,
+ installing_registration);
return;
}
- callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
+ // TODO(nhiroki): Handle database error (http://crbug.com/371675).
+ callback.Run(DatabaseStatusToStatusCode(status),
scoped_refptr<ServiceWorkerRegistration>());
}
-void ServiceWorkerStorage::DidReadRegistrationForId(
+void ServiceWorkerStorage::DidFindRegistrationForId(
const FindRegistrationCallback& callback,
- ServiceWorkerDatabase::RegistrationData* registration,
- ResourceList* resources,
+ const ServiceWorkerDatabase::RegistrationData& data,
+ const ResourceList& resources,
ServiceWorkerDatabase::Status status) {
- DCHECK(registration);
- DCHECK(resources);
-
if (status == ServiceWorkerDatabase::STATUS_OK) {
- callback.Run(SERVICE_WORKER_OK, CreateRegistration(*registration));
+ callback.Run(SERVICE_WORKER_OK,
+ GetOrCreateRegistration(data, resources));
return;
}
-
- if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
- // Look for somthing currently being installed.
- scoped_refptr<ServiceWorkerRegistration> installing_registration =
- FindInstallingRegistrationForId(registration->registration_id);
- if (installing_registration) {
- callback.Run(SERVICE_WORKER_OK, installing_registration);
- return;
- }
- callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
- scoped_refptr<ServiceWorkerRegistration>());
- return;
- }
-
// TODO(nhiroki): Handle database error (http://crbug.com/371675).
callback.Run(DatabaseStatusToStatusCode(status),
scoped_refptr<ServiceWorkerRegistration>());
- return;
}
void ServiceWorkerStorage::DidGetAllRegistrations(
@@ -668,8 +559,9 @@ void ServiceWorkerStorage::DidGetAllRegistrations(
}
void ServiceWorkerStorage::DidStoreRegistration(
- const GURL& origin,
const StatusCallback& callback,
+ const GURL& origin,
+ const std::vector<int64>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status) {
if (status != ServiceWorkerDatabase::STATUS_OK) {
// TODO(nhiroki): Handle database error (http://crbug.com/371675).
@@ -678,6 +570,7 @@ void ServiceWorkerStorage::DidStoreRegistration(
}
registered_origins_.insert(origin);
callback.Run(SERVICE_WORKER_OK);
+ StartPurgingResources(newly_purgeable_resources);
}
void ServiceWorkerStorage::DidUpdateToActiveState(
@@ -691,6 +584,7 @@ void ServiceWorkerStorage::DidDeleteRegistration(
const GURL& origin,
const StatusCallback& callback,
bool origin_is_deletable,
+ const std::vector<int64>& newly_purgeable_resources,
ServiceWorkerDatabase::Status status) {
if (status != ServiceWorkerDatabase::STATUS_OK) {
// TODO(nhiroki): Handle database error (http://crbug.com/371675).
@@ -700,21 +594,27 @@ void ServiceWorkerStorage::DidDeleteRegistration(
if (origin_is_deletable)
registered_origins_.erase(origin);
callback.Run(SERVICE_WORKER_OK);
+ StartPurgingResources(newly_purgeable_resources);
}
scoped_refptr<ServiceWorkerRegistration>
-ServiceWorkerStorage::CreateRegistration(
- const ServiceWorkerDatabase::RegistrationData& data) {
- scoped_refptr<ServiceWorkerRegistration> registration(
- new ServiceWorkerRegistration(
- data.scope, data.script, data.registration_id, context_));
+ServiceWorkerStorage::GetOrCreateRegistration(
+ const ServiceWorkerDatabase::RegistrationData& data,
+ const ResourceList& resources) {
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ context_->GetLiveRegistration(data.registration_id);
+ if (registration)
+ return registration;
+ registration = new ServiceWorkerRegistration(
+ data.scope, data.script, data.registration_id, context_);
scoped_refptr<ServiceWorkerVersion> version =
context_->GetLiveVersion(data.version_id);
if (!version) {
version = new ServiceWorkerVersion(registration, data.version_id, context_);
version->SetStatus(data.is_active ?
ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED);
+ version->script_cache_map()->SetResources(resources);
}
if (version->status() == ServiceWorkerVersion::ACTIVE)
@@ -725,7 +625,6 @@ ServiceWorkerStorage::CreateRegistration(
NOTREACHED();
// TODO(michaeln): Hmmm, what if DeleteReg was invoked after
// the Find result we're returning here? NOTREACHED condition?
-
return registration;
}
@@ -733,8 +632,7 @@ ServiceWorkerRegistration*
ServiceWorkerStorage::FindInstallingRegistrationForDocument(
const GURL& document_url) {
// TODO(michaeln): if there are multiple matches the one with
- // the longest scope should win, and these should on equal footing
- // with the stored registrations in FindRegistrationForDocument().
+ // the longest scope should win.
for (RegistrationRefsById::const_iterator it =
installing_registrations_.begin();
it != installing_registrations_.end(); ++it) {
@@ -772,13 +670,240 @@ ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
if (disk_cache_)
return disk_cache_.get();
- // TODO(michaeln): Store data on disk and do error checking.
disk_cache_.reset(new ServiceWorkerDiskCache);
- int rv = disk_cache_->InitWithMemBackend(
- kMaxMemDiskCacheSize,
- base::Bind(&EmptyCompletionCallback));
- DCHECK_EQ(net::OK, rv);
+
+ base::FilePath path = GetDiskCachePath();
+ if (path.empty()) {
+ int rv = disk_cache_->InitWithMemBackend(
+ kMaxMemDiskCacheSize,
+ base::Bind(&EmptyCompletionCallback));
+ DCHECK_EQ(net::OK, rv);
+ return disk_cache_.get();
+ }
+
+ int rv = disk_cache_->InitWithDiskBackend(
+ path, kMaxDiskCacheSize, false,
+ disk_cache_thread_.get(),
+ base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized,
+ weak_factory_.GetWeakPtr()));
+ if (rv != net::ERR_IO_PENDING)
+ OnDiskCacheInitialized(rv);
+
return disk_cache_.get();
}
+void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
+ if (rv != net::OK) {
+ LOG(ERROR) << "Failed to open the serviceworker diskcache.";
+ // TODO(michaeln): DeleteAndStartOver()
+ disk_cache_->Disable();
+ state_ = DISABLED;
+ }
+}
+
+void ServiceWorkerStorage::StartPurgingResources(
+ const std::vector<int64>& ids) {
+ for (size_t i = 0; i < ids.size(); ++i)
+ purgeable_reource_ids_.push_back(ids[i]);
+
+ if (purgeable_reource_ids_.empty() || is_purge_pending_)
+ return;
+
+ // Do one at a time until we're done, use RunSoon to avoid recursion when
+ // DoomEntry returns immediately.
+ is_purge_pending_ = true;
+ int64 id = purgeable_reource_ids_.front();
+ purgeable_reource_ids_.pop_front();
+ RunSoon(FROM_HERE,
+ base::Bind(&ServiceWorkerStorage::PurgeResource,
+ weak_factory_.GetWeakPtr(), id));
+}
+
+void ServiceWorkerStorage::PurgeResource(int64 id) {
+ DCHECK(is_purge_pending_);
+ int rv = disk_cache()->DoomEntry(
+ id, base::Bind(&ServiceWorkerStorage::OnResourcePurged,
+ weak_factory_.GetWeakPtr(), id));
+ if (rv != net::ERR_IO_PENDING)
+ OnResourcePurged(id, rv);
+}
+
+void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) {
+ DCHECK(is_purge_pending_);
+ is_purge_pending_ = false;
+
+ database_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(
+ &ServiceWorkerDatabase::ClearPurgeableResourceIds),
+ base::Unretained(database_.get()),
+ std::set<int64>(&id, &id + 1)));
+
+ // Continue purging the remaining resources.
+ StartPurgingResources(std::vector<int64>());
+}
+
+void ServiceWorkerStorage::ReadInitialDataFromDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ const InitializeCallback& callback) {
+ DCHECK(database);
+ scoped_ptr<ServiceWorkerStorage::InitialData> data(
+ new ServiceWorkerStorage::InitialData());
+
+ ServiceWorkerDatabase::Status status =
+ database->GetNextAvailableIds(&data->next_registration_id,
+ &data->next_version_id,
+ &data->next_resource_id);
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
+ return;
+ }
+
+ status = database->GetOriginsWithRegistrations(&data->origins);
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
+}
+
+void ServiceWorkerStorage::DeleteRegistrationFromDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ int64 registration_id,
+ const GURL& origin,
+ const DeleteRegistrationCallback& callback) {
+ DCHECK(database);
+
+ std::vector<int64> newly_purgeable_resources;
+ ServiceWorkerDatabase::Status status =
+ database->DeleteRegistration(registration_id, origin,
+ &newly_purgeable_resources);
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status));
+ return;
+ }
+
+ // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
+ // unique origin list.
+ std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
+ status = database->GetRegistrationsForOrigin(origin, &registrations);
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status));
+ return;
+ }
+
+ bool deletable = registrations.empty();
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, deletable,
+ newly_purgeable_resources, status));
+}
+
+void ServiceWorkerStorage::WriteRegistrationInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ const ServiceWorkerDatabase::RegistrationData& data,
+ const ResourceList& resources,
+ const WriteRegistrationCallback& callback) {
+ DCHECK(database);
+ std::vector<int64> newly_purgeable_resources;
+ ServiceWorkerDatabase::Status status =
+ database->WriteRegistration(data, resources, &newly_purgeable_resources);
+ original_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback, data.script.GetOrigin(),
+ newly_purgeable_resources, status));
+}
+
+void ServiceWorkerStorage::FindForDocumentInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ const GURL& document_url,
+ const FindInDBCallback& callback) {
+ GURL origin = document_url.GetOrigin();
+ RegistrationList registrations;
+ ServiceWorkerDatabase::Status status =
+ database->GetRegistrationsForOrigin(origin, &registrations);
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ original_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback,
+ ServiceWorkerDatabase::RegistrationData(),
+ ResourceList(),
+ status));
+ return;
+ }
+
+ // Find one with a pattern match.
+ // TODO(michaeln): if there are multiple matches the one with
+ // the longest scope should win.
+ ServiceWorkerDatabase::RegistrationData data;
+ ResourceList resources;
+ status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
+ for (RegistrationList::const_iterator it = registrations.begin();
+ it != registrations.end(); ++it) {
+ if (!ServiceWorkerUtils::ScopeMatches(it->scope, document_url))
+ continue;
+ status = database->ReadRegistration(it->registration_id, origin,
+ &data, &resources);
+ break; // We're done looping.
+ }
+
+ original_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback, data, resources, status));
+}
+
+void ServiceWorkerStorage::FindForPatternInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ const GURL& scope,
+ const FindInDBCallback& callback) {
+ GURL origin = scope.GetOrigin();
+ std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
+ ServiceWorkerDatabase::Status status =
+ database->GetRegistrationsForOrigin(origin, &registrations);
+ if (status != ServiceWorkerDatabase::STATUS_OK) {
+ original_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback,
+ ServiceWorkerDatabase::RegistrationData(),
+ ResourceList(),
+ status));
+ return;
+ }
+
+ // Find one with an exact matching scope.
+ ServiceWorkerDatabase::RegistrationData data;
+ ResourceList resources;
+ status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
+ for (RegistrationList::const_iterator it = registrations.begin();
+ it != registrations.end(); ++it) {
+ if (scope != it->scope)
+ continue;
+ status = database->ReadRegistration(it->registration_id, origin,
+ &data, &resources);
+ break; // We're done looping.
+ }
+
+ original_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback, data, resources, status));
+}
+
+void ServiceWorkerStorage::FindForIdInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ int64 registration_id,
+ const GURL& origin,
+ const FindInDBCallback& callback) {
+ ServiceWorkerDatabase::RegistrationData data;
+ ResourceList resources;
+ ServiceWorkerDatabase::Status status =
+ database->ReadRegistration(registration_id, origin, &data, &resources);
+ original_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, data, resources, status));
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698