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

Side by Side Diff: content/browser/service_worker/service_worker_disk_cache_migrator.cc

Issue 1152543002: ServiceWorker: Migrate the script cache backend from BlockFile to Simple (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove needs_disk_cache_migration Created 5 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_disk_cache_migrator.h" 5 #include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
6 6
7 #include "base/barrier_closure.h"
8 #include "base/files/file_util.h"
9 #include "base/location.h"
7 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/metrics/histogram_macros.h"
8 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/task_runner_util.h"
14 #include "base/time/time.h"
9 #include "content/common/service_worker/service_worker_types.h" 15 #include "content/common/service_worker/service_worker_types.h"
10 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
12 #include "net/disk_cache/disk_cache.h" 18 #include "net/disk_cache/disk_cache.h"
13 19
14 namespace content { 20 namespace content {
15 21
16 namespace { 22 namespace {
17 23
18 // Disk cache entry data indices (Copied from appcache_diskcache.cc). 24 // Disk cache entry data indices (Copied from appcache_diskcache.cc).
19 enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex }; 25 enum { kResponseInfoIndex, kResponseContentIndex, kResponseMetadataIndex };
20 26
27 void RecordMigrationResult(ServiceWorkerStatusCode status) {
28 UMA_HISTOGRAM_ENUMERATION("ServiceWorker.DiskCacheMigrator.MigrationResult",
29 status, SERVICE_WORKER_ERROR_MAX_VALUE);
30 }
31
32 void RecordNumberOfMigratedResources(size_t migrated_resources) {
33 UMA_HISTOGRAM_CUSTOM_COUNTS(
34 "ServiceWorker.DiskCacheMigrator.NumberOfMigratedResources",
35 migrated_resources, 1, 1000, 50);
36 }
37
38 void RecordMigrationTime(const base::TimeDelta& time) {
39 UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.DiskCacheMigrator.MigrationTime",
40 time);
41 }
42
21 } // namespace 43 } // namespace
22 44
23 // A task to move a cached resource from the src DiskCache to the dest 45 // A task to move a cached resource from the src DiskCache to the dest
24 // DiskCache. This is owned by ServiceWorkerDiskCacheMigrator. 46 // DiskCache. This is owned by ServiceWorkerDiskCacheMigrator.
25 class ServiceWorkerDiskCacheMigrator::Task { 47 class ServiceWorkerDiskCacheMigrator::Task {
26 public: 48 public:
27 Task(InflightTaskMap::KeyType task_id, 49 Task(InflightTaskMap::KeyType task_id,
28 int64 resource_id, 50 int64 resource_id,
29 int32 data_size, 51 int32 data_size,
30 ServiceWorkerDiskCache* src, 52 ServiceWorkerDiskCache* src,
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 Finish(SERVICE_WORKER_OK); 240 Finish(SERVICE_WORKER_OK);
219 } 241 }
220 242
221 void ServiceWorkerDiskCacheMigrator::Task::Finish( 243 void ServiceWorkerDiskCacheMigrator::Task::Finish(
222 ServiceWorkerStatusCode status) { 244 ServiceWorkerStatusCode status) {
223 DCHECK(owner_); 245 DCHECK(owner_);
224 owner_->OnEntryMigrated(task_id_, status); 246 owner_->OnEntryMigrated(task_id_, status);
225 } 247 }
226 248
227 ServiceWorkerDiskCacheMigrator::ServiceWorkerDiskCacheMigrator( 249 ServiceWorkerDiskCacheMigrator::ServiceWorkerDiskCacheMigrator(
228 ServiceWorkerDiskCache* src, 250 const base::FilePath& src_path,
229 ServiceWorkerDiskCache* dest) 251 const base::FilePath& dest_path,
230 : src_(src), dest_(dest), weak_factory_(this) { 252 int max_disk_cache_size,
231 DCHECK(!src_->is_disabled()); 253 const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread)
232 DCHECK(!dest_->is_disabled()); 254 : src_path_(src_path),
255 dest_path_(dest_path),
256 max_disk_cache_size_(max_disk_cache_size),
257 disk_cache_thread_(disk_cache_thread),
258 weak_factory_(this) {
233 } 259 }
234 260
235 ServiceWorkerDiskCacheMigrator::~ServiceWorkerDiskCacheMigrator() { 261 ServiceWorkerDiskCacheMigrator::~ServiceWorkerDiskCacheMigrator() {
236 } 262 }
237 263
238 void ServiceWorkerDiskCacheMigrator::Start(const StatusCallback& callback) { 264 void ServiceWorkerDiskCacheMigrator::Start(const StatusCallback& callback) {
239 callback_ = callback; 265 callback_ = callback;
266 start_time_ = base::TimeTicks::Now();
267
268 PostTaskAndReplyWithResult(
269 disk_cache_thread_.get(), FROM_HERE,
270 base::Bind(&base::DeleteFile, dest_path_, true),
271 base::Bind(&ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory,
272 weak_factory_.GetWeakPtr()));
273 }
274
275 void ServiceWorkerDiskCacheMigrator::DidDeleteDestDirectory(bool deleted) {
276 // Continue the migration regardless of the deletion result. If the migrator
277 // cannot proceed or the diskcache gets corrupted due to the failure, the
278 // storage detects it and recovers by DeleteAndStartOver.
279
280 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
281 dest_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
282 bool* is_failed = new bool(false);
283
284 // This closure is called when both diskcaches are initialized.
285 base::Closure barrier_closure = base::BarrierClosure(
286 2, base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches,
287 weak_factory_.GetWeakPtr(), base::Owned(is_failed)));
288
289 // Initialize the src DiskCache.
290 net::CompletionCallback src_callback =
291 base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache,
292 weak_factory_.GetWeakPtr(), is_failed, barrier_closure);
293 int result = src_->InitWithDiskBackend(src_path_, max_disk_cache_size_,
294 false /* force */, disk_cache_thread_,
295 src_callback);
296 if (result != net::ERR_IO_PENDING)
297 src_callback.Run(result);
298
299 // Initialize the dest DiskCache.
300 net::CompletionCallback dest_callback =
301 base::Bind(&ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache,
302 weak_factory_.GetWeakPtr(), is_failed, barrier_closure);
303 result = dest_->InitWithDiskBackend(dest_path_, max_disk_cache_size_,
304 false /* force */, disk_cache_thread_,
305 dest_callback);
306 if (result != net::ERR_IO_PENDING)
307 dest_callback.Run(result);
308 }
309
310 void ServiceWorkerDiskCacheMigrator::DidInitializeDiskCache(
311 bool* is_failed,
312 const base::Closure& barrier_closure,
313 int result) {
314 if (result != net::OK)
315 *is_failed = true;
316 barrier_closure.Run();
317 }
318
319 void ServiceWorkerDiskCacheMigrator::DidInitializeAllDiskCaches(
320 bool* is_failed) {
321 if (*is_failed) {
322 LOG(ERROR) << "Failed to initialize the diskcache";
323 Complete(SERVICE_WORKER_ERROR_FAILED);
324 return;
325 }
326
327 // Iterate through existing entries in the src DiskCache.
240 iterator_ = src_->disk_cache()->CreateIterator(); 328 iterator_ = src_->disk_cache()->CreateIterator();
241 OpenNextEntry(); 329 OpenNextEntry();
242 } 330 }
243 331
244 void ServiceWorkerDiskCacheMigrator::OpenNextEntry() { 332 void ServiceWorkerDiskCacheMigrator::OpenNextEntry() {
245 DCHECK(!pending_task_); 333 DCHECK(!pending_task_);
246 DCHECK(!is_iterating_); 334 DCHECK(!is_iterating_);
247 is_iterating_ = true; 335 is_iterating_ = true;
248 336
249 scoped_ptr<WrappedEntry> wrapped_entry(new WrappedEntry); 337 scoped_ptr<WrappedEntry> wrapped_entry(new WrappedEntry);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 371
284 int64 resource_id = kInvalidServiceWorkerResourceId; 372 int64 resource_id = kInvalidServiceWorkerResourceId;
285 if (!base::StringToInt64(scoped_entry->GetKey(), &resource_id)) { 373 if (!base::StringToInt64(scoped_entry->GetKey(), &resource_id)) {
286 LOG(ERROR) << "Failed to read the resource id"; 374 LOG(ERROR) << "Failed to read the resource id";
287 inflight_tasks_.Clear(); 375 inflight_tasks_.Clear();
288 Complete(SERVICE_WORKER_ERROR_FAILED); 376 Complete(SERVICE_WORKER_ERROR_FAILED);
289 return; 377 return;
290 } 378 }
291 379
292 InflightTaskMap::KeyType task_id = next_task_id_++; 380 InflightTaskMap::KeyType task_id = next_task_id_++;
293 pending_task_.reset(new Task(task_id, resource_id, 381 pending_task_.reset(new Task(
294 scoped_entry->GetDataSize(kResponseContentIndex), 382 task_id, resource_id, scoped_entry->GetDataSize(kResponseContentIndex),
295 src_, dest_, weak_factory_.GetWeakPtr())); 383 src_.get(), dest_.get(), weak_factory_.GetWeakPtr()));
296 if (inflight_tasks_.size() < max_number_of_inflight_tasks_) { 384 if (inflight_tasks_.size() < max_number_of_inflight_tasks_) {
297 RunPendingTask(); 385 RunPendingTask();
298 OpenNextEntry(); 386 OpenNextEntry();
299 return; 387 return;
300 } 388 }
301 // |pending_task_| will run when an inflight task is completed. 389 // |pending_task_| will run when an inflight task is completed.
302 } 390 }
303 391
304 void ServiceWorkerDiskCacheMigrator::RunPendingTask() { 392 void ServiceWorkerDiskCacheMigrator::RunPendingTask() {
305 DCHECK(pending_task_); 393 DCHECK(pending_task_);
306 DCHECK_GT(max_number_of_inflight_tasks_, inflight_tasks_.size()); 394 DCHECK_GT(max_number_of_inflight_tasks_, inflight_tasks_.size());
307 InflightTaskMap::KeyType task_id = pending_task_->task_id(); 395 InflightTaskMap::KeyType task_id = pending_task_->task_id();
308 pending_task_->Run(); 396 pending_task_->Run();
309 inflight_tasks_.AddWithID(pending_task_.release(), task_id); 397 inflight_tasks_.AddWithID(pending_task_.release(), task_id);
310 } 398 }
311 399
312 void ServiceWorkerDiskCacheMigrator::OnEntryMigrated( 400 void ServiceWorkerDiskCacheMigrator::OnEntryMigrated(
313 InflightTaskMap::KeyType task_id, 401 InflightTaskMap::KeyType task_id,
314 ServiceWorkerStatusCode status) { 402 ServiceWorkerStatusCode status) {
315 DCHECK(inflight_tasks_.Lookup(task_id)); 403 DCHECK(inflight_tasks_.Lookup(task_id));
316 inflight_tasks_.Remove(task_id); 404 inflight_tasks_.Remove(task_id);
317 405
318 if (status != SERVICE_WORKER_OK) { 406 if (status != SERVICE_WORKER_OK) {
319 inflight_tasks_.Clear(); 407 inflight_tasks_.Clear();
320 Complete(status); 408 Complete(status);
321 return; 409 return;
322 } 410 }
323 411
412 ++number_of_migrated_resources_;
413
324 if (pending_task_) { 414 if (pending_task_) {
325 RunPendingTask(); 415 RunPendingTask();
326 OpenNextEntry(); 416 OpenNextEntry();
327 return; 417 return;
328 } 418 }
329 419
330 if (is_iterating_) 420 if (is_iterating_)
331 return; 421 return;
332 422
333 if (inflight_tasks_.IsEmpty()) 423 if (inflight_tasks_.IsEmpty())
334 Complete(SERVICE_WORKER_OK); 424 Complete(SERVICE_WORKER_OK);
335 } 425 }
336 426
337 void ServiceWorkerDiskCacheMigrator::Complete(ServiceWorkerStatusCode status) { 427 void ServiceWorkerDiskCacheMigrator::Complete(ServiceWorkerStatusCode status) {
338 DCHECK(inflight_tasks_.IsEmpty()); 428 DCHECK(inflight_tasks_.IsEmpty());
339 // TODO(nhiroki): Add UMA for the result of migration. 429 if (status == SERVICE_WORKER_OK) {
430 RecordMigrationTime(base::TimeTicks().Now() - start_time_);
431 RecordNumberOfMigratedResources(number_of_migrated_resources_);
432 }
433 RecordMigrationResult(status);
434
435 src_.reset();
436 dest_.reset();
340 callback_.Run(status); 437 callback_.Run(status);
341 } 438 }
342 439
343 } // namespace content 440 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698