Index: content/browser/service_worker/service_worker_disk_cache_migrator.cc |
diff --git a/content/browser/service_worker/service_worker_disk_cache_migrator.cc b/content/browser/service_worker/service_worker_disk_cache_migrator.cc |
index df67b78003abfc0ea3be3ee0108e20a0478eb8e5..256f286f20c5c91cec97abd3445f7c5f6bf9fe05 100644 |
--- a/content/browser/service_worker/service_worker_disk_cache_migrator.cc |
+++ b/content/browser/service_worker/service_worker_disk_cache_migrator.cc |
@@ -4,8 +4,14 @@ |
#include "content/browser/service_worker/service_worker_disk_cache_migrator.h" |
+#include "base/barrier_closure.h" |
+#include "base/files/file_util.h" |
+#include "base/location.h" |
#include "base/memory/ref_counted.h" |
+#include "base/metrics/histogram_macros.h" |
#include "base/strings/string_number_conversions.h" |
+#include "base/task_runner_util.h" |
+#include "base/time/time.h" |
#include "content/common/service_worker/service_worker_types.h" |
#include "net/base/io_buffer.h" |
#include "net/base/net_errors.h" |
@@ -18,6 +24,22 @@ namespace { |
// Disk cache entry data indices (Copied from appcache_diskcache.cc). |
enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex }; |
+void RecordMigrationResult(ServiceWorkerStatusCode status) { |
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.DiskCacheMigrator.MigrationResult", |
+ status, SERVICE_WORKER_ERROR_MAX_VALUE); |
+} |
+ |
+void RecordNumberOfMigratedResources(size_t migrated_resources) { |
+ UMA_HISTOGRAM_CUSTOM_COUNTS( |
+ "ServiceWorker.DiskCacheMigrator.NumberOfMigratedResources", |
+ migrated_resources, 1, 1000, 50); |
+} |
+ |
+void RecordMigrationTime(const base::TimeDelta& time) { |
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.DiskCacheMigrator.MigrationTime", |
+ time); |
+} |
+ |
} // namespace |
// A task to move a cached resource from the src DiskCache to the dest |
@@ -225,11 +247,15 @@ void ServiceWorkerDiskCacheMigrator::Task::Finish( |
} |
ServiceWorkerDiskCacheMigrator::ServiceWorkerDiskCacheMigrator( |
- ServiceWorkerDiskCache* src, |
- ServiceWorkerDiskCache* dest) |
- : src_(src), dest_(dest), weak_factory_(this) { |
- DCHECK(!src_->is_disabled()); |
- DCHECK(!dest_->is_disabled()); |
+ const base::FilePath& src_path, |
+ const base::FilePath& dest_path, |
+ int max_disk_cache_size, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread) |
+ : src_path_(src_path), |
+ dest_path_(dest_path), |
+ max_disk_cache_size_(max_disk_cache_size), |
+ disk_cache_thread_(disk_cache_thread), |
+ weak_factory_(this) { |
} |
ServiceWorkerDiskCacheMigrator::~ServiceWorkerDiskCacheMigrator() { |
@@ -237,6 +263,68 @@ ServiceWorkerDiskCacheMigrator::~ServiceWorkerDiskCacheMigrator() { |
void ServiceWorkerDiskCacheMigrator::Start(const StatusCallback& callback) { |
callback_ = callback; |
+ start_time_ = base::TimeTicks::Now(); |
+ |
+ PostTaskAndReplyWithResult( |
+ disk_cache_thread_.get(), FROM_HERE, |
+ base::Bind(&base::DeleteFile, dest_path_, true), |
+ base::Bind(&ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory(bool deleted) { |
+ // Continue the migration regardless of the deletion result. If the migrator |
+ // cannot proceed or the diskcache gets corrupted due to the failure, the |
+ // storage detects it and recovers by DeleteAndStartOver. |
+ |
+ src_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend(); |
michaeln
2015/06/11 00:52:38
android?
nhiroki
2015/06/11 21:04:50
Done in the separate CL:
https://codereview.chromi
|
+ dest_ = ServiceWorkerDiskCache::CreateWithSimpleBackend(); |
+ bool* is_failed = new bool(false); |
+ |
+ // This closure is called when both diskcaches are initialized. |
+ base::Closure barrier_closure = base::BarrierClosure( |
+ 2, base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches, |
+ weak_factory_.GetWeakPtr(), base::Owned(is_failed))); |
+ |
+ // Initialize the src DiskCache. |
+ net::CompletionCallback src_callback = |
+ base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache, |
+ weak_factory_.GetWeakPtr(), is_failed, barrier_closure); |
+ int result = src_->InitWithDiskBackend(src_path_, max_disk_cache_size_, |
+ false /* force */, disk_cache_thread_, |
+ src_callback); |
+ if (result != net::ERR_IO_PENDING) |
+ src_callback.Run(result); |
+ |
+ // Initialize the dest DiskCache. |
+ net::CompletionCallback dest_callback = |
+ base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache, |
+ weak_factory_.GetWeakPtr(), is_failed, barrier_closure); |
+ result = dest_->InitWithDiskBackend(dest_path_, max_disk_cache_size_, |
+ false /* force */, disk_cache_thread_, |
+ dest_callback); |
+ if (result != net::ERR_IO_PENDING) |
+ dest_callback.Run(result); |
+} |
+ |
+void ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache( |
+ bool* is_failed, |
+ const base::Closure& barrier_closure, |
+ int result) { |
+ if (result != net::OK) |
+ *is_failed = true; |
+ barrier_closure.Run(); |
+} |
+ |
+void ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches( |
+ bool* is_failed) { |
+ if (*is_failed) { |
+ LOG(ERROR) << "Failed to initialize the diskcache"; |
+ Complete(SERVICE_WORKER_ERROR_FAILED); |
+ return; |
+ } |
+ |
+ // Iterate through existing entries in the src DiskCache. |
iterator_ = src_->disk_cache()->CreateIterator(); |
OpenNextEntry(); |
} |
@@ -290,9 +378,9 @@ void ServiceWorkerDiskCacheMigrator::OnNextEntryOpened( |
} |
InflightTaskMap::KeyType task_id = next_task_id_++; |
- pending_task_.reset(new Task(task_id, resource_id, |
- scoped_entry->GetDataSize(kResponseContentIndex), |
- src_, dest_, weak_factory_.GetWeakPtr())); |
+ pending_task_.reset(new Task( |
+ task_id, resource_id, scoped_entry->GetDataSize(kResponseContentIndex), |
+ src_.get(), dest_.get(), weak_factory_.GetWeakPtr())); |
if (inflight_tasks_.size() < max_number_of_inflight_tasks_) { |
RunPendingTask(); |
OpenNextEntry(); |
@@ -321,6 +409,8 @@ void ServiceWorkerDiskCacheMigrator::OnEntryMigrated( |
return; |
} |
+ ++number_of_migrated_resources_; |
+ |
if (pending_task_) { |
RunPendingTask(); |
OpenNextEntry(); |
@@ -336,7 +426,14 @@ void ServiceWorkerDiskCacheMigrator::OnEntryMigrated( |
void ServiceWorkerDiskCacheMigrator::Complete(ServiceWorkerStatusCode status) { |
DCHECK(inflight_tasks_.IsEmpty()); |
- // TODO(nhiroki): Add UMA for the result of migration. |
+ if (status == SERVICE_WORKER_OK) { |
+ RecordMigrationTime(base::TimeTicks().Now() - start_time_); |
+ RecordNumberOfMigratedResources(number_of_migrated_resources_); |
+ } |
+ RecordMigrationResult(status); |
+ |
+ src_.reset(); |
+ dest_.reset(); |
callback_.Run(status); |
} |