Chromium Code Reviews| 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 4f714195ce0ea688daffbebcf25093034b944c16..2f56b93e03a6593ef105e54f938d0196637d978e 100644 |
| --- a/content/browser/service_worker/service_worker_storage.cc |
| +++ b/content/browser/service_worker/service_worker_storage.cc |
| @@ -14,8 +14,8 @@ |
| #include "base/trace_event/trace_event.h" |
| #include "content/browser/service_worker/service_worker_context_core.h" |
| #include "content/browser/service_worker/service_worker_disk_cache.h" |
| +#include "content/browser/service_worker/service_worker_disk_cache_migrator.h" |
| #include "content/browser/service_worker/service_worker_info.h" |
| -#include "content/browser/service_worker/service_worker_metrics.h" |
| #include "content/browser/service_worker/service_worker_registration.h" |
| #include "content/browser/service_worker/service_worker_utils.h" |
| #include "content/browser/service_worker/service_worker_version.h" |
| @@ -60,7 +60,8 @@ void CompleteFindSoon( |
| const base::FilePath::CharType kDatabaseName[] = |
| FILE_PATH_LITERAL("Database"); |
| const base::FilePath::CharType kDiskCacheName[] = |
| - FILE_PATH_LITERAL("Cache"); |
| + FILE_PATH_LITERAL("ScriptCache"); |
| +const base::FilePath::CharType kOldDiskCacheName[] = FILE_PATH_LITERAL("Cache"); |
| const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; |
| const int kMaxDiskCacheSize = 250 * 1024 * 1024; |
| @@ -648,18 +649,21 @@ void ServiceWorkerStorage::DeleteRegistration( |
| scoped_ptr<ServiceWorkerResponseReader> |
| ServiceWorkerStorage::CreateResponseReader(int64 response_id) { |
| + DCHECK_EQ(INITIALIZED, state_); |
| return make_scoped_ptr( |
| new ServiceWorkerResponseReader(response_id, disk_cache())); |
| } |
| scoped_ptr<ServiceWorkerResponseWriter> |
| ServiceWorkerStorage::CreateResponseWriter(int64 response_id) { |
| + DCHECK_EQ(INITIALIZED, state_); |
| return make_scoped_ptr( |
| new ServiceWorkerResponseWriter(response_id, disk_cache())); |
| } |
| scoped_ptr<ServiceWorkerResponseMetadataWriter> |
| ServiceWorkerStorage::CreateResponseMetadataWriter(int64 response_id) { |
| + DCHECK_EQ(INITIALIZED, state_); |
| return make_scoped_ptr( |
| new ServiceWorkerResponseMetadataWriter(response_id, disk_cache())); |
| } |
| @@ -949,6 +953,13 @@ base::FilePath ServiceWorkerStorage::GetDiskCachePath() { |
| .Append(kDiskCacheName); |
| } |
| +base::FilePath ServiceWorkerStorage::GetOldDiskCachePath() { |
| + if (path_.empty()) |
| + return base::FilePath(); |
| + return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) |
| + .Append(kOldDiskCacheName); |
| +} |
| + |
| bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { |
| if (!context_) |
| return false; |
| @@ -967,6 +978,110 @@ bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { |
| } |
| state_ = INITIALIZING; |
| + |
| + if (GetOldDiskCachePath().empty()) { |
| + // In-memory storage does not have to migrate. |
| + ContinueLazyInitialize(); |
| + return false; |
| + } |
| + |
| + // Check if the old DiskCache directory exists. |
| + PostTaskAndReplyWithResult( |
| + disk_cache_thread_.get(), FROM_HERE, |
| + base::Bind(&base::DirectoryExists, GetOldDiskCachePath()), |
| + base::Bind(&ServiceWorkerStorage::DidCheckOldDiskCacheDirectory, |
| + weak_factory_.GetWeakPtr())); |
| + return false; |
| +} |
| + |
| +void ServiceWorkerStorage::DidCheckOldDiskCacheDirectory(bool exists) { |
| + if (!exists) { |
| + // DiskCache has already been migrated. |
| + ServiceWorkerMetrics::RecordDiskCacheMigrationResult( |
| + ServiceWorkerMetrics::MIGRATION_NOT_NECESSARY); |
| + ContinueLazyInitialize(); |
| + return; |
| + } |
| + |
| + // Initialize the old DiskCache. |
| + scoped_ptr<ServiceWorkerDiskCache> old_disk_cache = |
| + ServiceWorkerDiskCache::CreateWithBlockFileBackend(); |
| + ServiceWorkerDiskCache* old_disk_cache_ptr = old_disk_cache.get(); |
| + net::CompletionCallback callback = base::Bind( |
| + &ServiceWorkerStorage::DidInitializeOldDiskCache, |
| + weak_factory_.GetWeakPtr(), base::Passed(old_disk_cache.Pass())); |
| + |
| + int result = old_disk_cache_ptr->InitWithDiskBackend( |
| + GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */, |
| + disk_cache_thread_, callback); |
| + if (result == net::ERR_IO_PENDING) |
| + return; |
| + callback.Run(result); |
| +} |
| + |
| +void ServiceWorkerStorage::DidInitializeOldDiskCache( |
| + scoped_ptr<ServiceWorkerDiskCache> old_disk_cache, |
| + int result) { |
| + if (result != net::OK) { |
| + LOG(ERROR) << "Failed to initialize the diskcache: " << result; |
| + AbortLazyInitialize(ServiceWorkerMetrics::MIGRATION_ERROR_INITIALIZE); |
| + return; |
| + } |
| + |
| + // Start migrating resources stored in the old DiskCache. |
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator( |
| + new ServiceWorkerDiskCacheMigrator(old_disk_cache.get(), disk_cache())); |
| + ServiceWorkerDiskCacheMigrator* migrator_ptr = migrator.get(); |
| + migrator_ptr->Start(base::Bind( |
| + &ServiceWorkerStorage::DidDiskCacheMigrated, weak_factory_.GetWeakPtr(), |
| + base::Passed(migrator.Pass()), base::Passed(old_disk_cache.Pass()))); |
| +} |
| + |
| +void ServiceWorkerStorage::DidDiskCacheMigrated( |
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator, |
| + scoped_ptr<ServiceWorkerDiskCache> old_disk_cache, |
| + ServiceWorkerStatusCode status) { |
| + if (status != SERVICE_WORKER_OK) { |
| + LOG(ERROR) << "Failed to migrate the diskcache: " << status; |
| + AbortLazyInitialize(ServiceWorkerMetrics::MIGRATION_ERROR_FAILED); |
| + return; |
| + } |
| + |
| + // Delete the old DiskCache directory. |
| + migrator.reset(); |
| + old_disk_cache.reset(); |
| + PostTaskAndReplyWithResult( |
| + disk_cache_thread_.get(), FROM_HERE, |
| + base::Bind(&base::DeleteFile, GetOldDiskCachePath(), true), |
| + base::Bind(&ServiceWorkerStorage::DidDeleteOldDiskCache, |
| + weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ServiceWorkerStorage::DidDeleteOldDiskCache(bool deleted) { |
| + if (!deleted) { |
| + LOG(ERROR) << "Failed to delete the old diskcache directory"; |
| + AbortLazyInitialize( |
| + ServiceWorkerMetrics::MIGRATION_ERROR_DELETE_DISK_CACHE); |
| + return; |
| + } |
| + |
| + ContinueLazyInitialize(); |
| +} |
| + |
| +void ServiceWorkerStorage::AbortLazyInitialize( |
| + ServiceWorkerMetrics::DiskCacheMigrationResult result) { |
|
falken
2015/06/01 04:31:49
DCHECK(result != OK)?
nhiroki
2015/06/02 09:18:33
Done.
|
| + ServiceWorkerMetrics::RecordDiskCacheMigrationResult(result); |
| + |
| + // Give up the migration and recreate the whole storage. |
| + ScheduleDeleteAndStartOver(); |
| + |
| + // Pending tasks will be aborted due to the disabled storage. |
| + for (const base::Closure& pending_task : pending_tasks_) |
| + RunSoon(FROM_HERE, pending_task); |
|
falken
2015/06/01 04:31:50
Is this OK? Should the pending tasks be run after
nhiroki
2015/06/02 09:18:33
ScheduleDeleteAndStartOver() disables the storage
|
| + pending_tasks_.clear(); |
| +} |
| + |
| +void ServiceWorkerStorage::ContinueLazyInitialize() { |
| database_task_manager_->GetTaskRunner()->PostTask( |
| FROM_HERE, |
| base::Bind(&ReadInitialDataFromDB, |
| @@ -974,7 +1089,6 @@ bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { |
| base::ThreadTaskRunnerHandle::Get(), |
| base::Bind(&ServiceWorkerStorage::DidReadInitialData, |
| weak_factory_.GetWeakPtr()))); |
| - return false; |
| } |
| void ServiceWorkerStorage::DidReadInitialData( |
| @@ -995,10 +1109,8 @@ void ServiceWorkerStorage::DidReadInitialData( |
| ScheduleDeleteAndStartOver(); |
| } |
| - for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); |
| - it != pending_tasks_.end(); ++it) { |
| - RunSoon(FROM_HERE, *it); |
| - } |
| + for (const base::Closure& pending_task : pending_tasks_) |
| + RunSoon(FROM_HERE, pending_task); |
| pending_tasks_.clear(); |
| } |
| @@ -1371,7 +1483,7 @@ ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { |
| if (disk_cache_) |
| return disk_cache_.get(); |
| - disk_cache_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend(); |
| + disk_cache_ = ServiceWorkerDiskCache::CreateWithSimpleBackend(); |
| base::FilePath path = GetDiskCachePath(); |
| if (path.empty()) { |