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()) { |