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

Side by Side Diff: content/browser/service_worker/service_worker_storage.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: update histograms.xml 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_storage.h" 5 #include "content/browser/service_worker/service_worker_storage.h"
6 6
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/sequenced_task_runner.h" 10 #include "base/sequenced_task_runner.h"
11 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/task_runner_util.h" 12 #include "base/task_runner_util.h"
13 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "content/browser/service_worker/service_worker_context_core.h" 15 #include "content/browser/service_worker/service_worker_context_core.h"
16 #include "content/browser/service_worker/service_worker_disk_cache.h" 16 #include "content/browser/service_worker/service_worker_disk_cache.h"
17 #include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
17 #include "content/browser/service_worker/service_worker_info.h" 18 #include "content/browser/service_worker/service_worker_info.h"
18 #include "content/browser/service_worker/service_worker_metrics.h"
19 #include "content/browser/service_worker/service_worker_registration.h" 19 #include "content/browser/service_worker/service_worker_registration.h"
20 #include "content/browser/service_worker/service_worker_utils.h" 20 #include "content/browser/service_worker/service_worker_utils.h"
21 #include "content/browser/service_worker/service_worker_version.h" 21 #include "content/browser/service_worker/service_worker_version.h"
22 #include "content/common/service_worker/service_worker_types.h" 22 #include "content/common/service_worker/service_worker_types.h"
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "net/base/completion_callback.h" 24 #include "net/base/completion_callback.h"
25 #include "net/base/io_buffer.h" 25 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
27 #include "storage/browser/quota/quota_manager_proxy.h" 27 #include "storage/browser/quota/quota_manager_proxy.h"
28 #include "storage/browser/quota/special_storage_policy.h" 28 #include "storage/browser/quota/special_storage_policy.h"
(...skipping 24 matching lines...) Expand all
53 const scoped_refptr<ServiceWorkerRegistration>& registration, 53 const scoped_refptr<ServiceWorkerRegistration>& registration,
54 ServiceWorkerStatusCode status, 54 ServiceWorkerStatusCode status,
55 const ServiceWorkerStorage::FindRegistrationCallback& callback) { 55 const ServiceWorkerStorage::FindRegistrationCallback& callback) {
56 RunSoon(from_here, 56 RunSoon(from_here,
57 base::Bind(&CompleteFindNow, registration, status, callback)); 57 base::Bind(&CompleteFindNow, registration, status, callback));
58 } 58 }
59 59
60 const base::FilePath::CharType kDatabaseName[] = 60 const base::FilePath::CharType kDatabaseName[] =
61 FILE_PATH_LITERAL("Database"); 61 FILE_PATH_LITERAL("Database");
62 const base::FilePath::CharType kDiskCacheName[] = 62 const base::FilePath::CharType kDiskCacheName[] =
63 FILE_PATH_LITERAL("Cache"); 63 FILE_PATH_LITERAL("ScriptCache");
64 const base::FilePath::CharType kOldDiskCacheName[] = FILE_PATH_LITERAL("Cache");
64 65
65 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; 66 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
66 const int kMaxDiskCacheSize = 250 * 1024 * 1024; 67 const int kMaxDiskCacheSize = 250 * 1024 * 1024;
67 68
68 ServiceWorkerStatusCode DatabaseStatusToStatusCode( 69 ServiceWorkerStatusCode DatabaseStatusToStatusCode(
69 ServiceWorkerDatabase::Status status) { 70 ServiceWorkerDatabase::Status status) {
70 switch (status) { 71 switch (status) {
71 case ServiceWorkerDatabase::STATUS_OK: 72 case ServiceWorkerDatabase::STATUS_OK:
72 return SERVICE_WORKER_OK; 73 return SERVICE_WORKER_OK;
73 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: 74 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND:
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 // The registration should no longer be findable. 642 // The registration should no longer be findable.
642 pending_deletions_.insert(registration_id); 643 pending_deletions_.insert(registration_id);
643 ServiceWorkerRegistration* registration = 644 ServiceWorkerRegistration* registration =
644 context_->GetLiveRegistration(registration_id); 645 context_->GetLiveRegistration(registration_id);
645 if (registration) 646 if (registration)
646 registration->set_is_deleted(true); 647 registration->set_is_deleted(true);
647 } 648 }
648 649
649 scoped_ptr<ServiceWorkerResponseReader> 650 scoped_ptr<ServiceWorkerResponseReader>
650 ServiceWorkerStorage::CreateResponseReader(int64 response_id) { 651 ServiceWorkerStorage::CreateResponseReader(int64 response_id) {
652 DCHECK_EQ(INITIALIZED, state_);
651 return make_scoped_ptr( 653 return make_scoped_ptr(
652 new ServiceWorkerResponseReader(response_id, disk_cache())); 654 new ServiceWorkerResponseReader(response_id, disk_cache()));
653 } 655 }
654 656
655 scoped_ptr<ServiceWorkerResponseWriter> 657 scoped_ptr<ServiceWorkerResponseWriter>
656 ServiceWorkerStorage::CreateResponseWriter(int64 response_id) { 658 ServiceWorkerStorage::CreateResponseWriter(int64 response_id) {
659 DCHECK_EQ(INITIALIZED, state_);
657 return make_scoped_ptr( 660 return make_scoped_ptr(
658 new ServiceWorkerResponseWriter(response_id, disk_cache())); 661 new ServiceWorkerResponseWriter(response_id, disk_cache()));
659 } 662 }
660 663
661 scoped_ptr<ServiceWorkerResponseMetadataWriter> 664 scoped_ptr<ServiceWorkerResponseMetadataWriter>
662 ServiceWorkerStorage::CreateResponseMetadataWriter(int64 response_id) { 665 ServiceWorkerStorage::CreateResponseMetadataWriter(int64 response_id) {
666 DCHECK_EQ(INITIALIZED, state_);
663 return make_scoped_ptr( 667 return make_scoped_ptr(
664 new ServiceWorkerResponseMetadataWriter(response_id, disk_cache())); 668 new ServiceWorkerResponseMetadataWriter(response_id, disk_cache()));
665 } 669 }
666 670
667 void ServiceWorkerStorage::StoreUncommittedResponseId(int64 id) { 671 void ServiceWorkerStorage::StoreUncommittedResponseId(int64 id) {
668 DCHECK_NE(kInvalidServiceWorkerResponseId, id); 672 DCHECK_NE(kInvalidServiceWorkerResponseId, id);
669 DCHECK_EQ(INITIALIZED, state_); 673 DCHECK_EQ(INITIALIZED, state_);
670 674
671 if (!has_checked_for_stale_resources_) 675 if (!has_checked_for_stale_resources_)
672 DeleteStaleResources(); 676 DeleteStaleResources();
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 .Append(kDatabaseName); 946 .Append(kDatabaseName);
943 } 947 }
944 948
945 base::FilePath ServiceWorkerStorage::GetDiskCachePath() { 949 base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
946 if (path_.empty()) 950 if (path_.empty())
947 return base::FilePath(); 951 return base::FilePath();
948 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) 952 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
949 .Append(kDiskCacheName); 953 .Append(kDiskCacheName);
950 } 954 }
951 955
956 base::FilePath ServiceWorkerStorage::GetOldDiskCachePath() {
957 if (path_.empty())
958 return base::FilePath();
959 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
960 .Append(kOldDiskCacheName);
961 }
962
952 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { 963 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
953 if (!context_) 964 if (!context_)
954 return false; 965 return false;
955 966
956 switch (state_) { 967 switch (state_) {
957 case INITIALIZED: 968 case INITIALIZED:
958 return true; 969 return true;
959 case DISABLED: 970 case DISABLED:
960 return false; 971 return false;
961 case INITIALIZING: 972 case INITIALIZING:
962 pending_tasks_.push_back(callback); 973 pending_tasks_.push_back(callback);
963 return false; 974 return false;
964 case UNINITIALIZED: 975 case UNINITIALIZED:
965 pending_tasks_.push_back(callback); 976 pending_tasks_.push_back(callback);
966 // Fall-through. 977 // Fall-through.
967 } 978 }
968 979
969 state_ = INITIALIZING; 980 state_ = INITIALIZING;
981
982 if (GetOldDiskCachePath().empty()) {
983 // In-memory storage does not have to migrate.
984 ContinueLazyInitialize();
985 return false;
986 }
987
988 // Check if the old DiskCache directory exists.
989 PostTaskAndReplyWithResult(
990 disk_cache_thread_.get(), FROM_HERE,
991 base::Bind(&base::DirectoryExists, GetOldDiskCachePath()),
992 base::Bind(&ServiceWorkerStorage::DidCheckOldDiskCacheDirectory,
993 weak_factory_.GetWeakPtr()));
994 return false;
995 }
996
997 void ServiceWorkerStorage::DidCheckOldDiskCacheDirectory(bool exists) {
998 if (!exists) {
999 // DiskCache has already been migrated.
1000 ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
1001 ServiceWorkerMetrics::MIGRATION_NOT_NECESSARY);
1002 ContinueLazyInitialize();
1003 return;
1004 }
1005
1006 // Initialize the old DiskCache.
1007 scoped_ptr<ServiceWorkerDiskCache> old_disk_cache =
1008 ServiceWorkerDiskCache::CreateWithBlockFileBackend();
1009 ServiceWorkerDiskCache* old_disk_cache_ptr = old_disk_cache.get();
1010 net::CompletionCallback callback = base::Bind(
1011 &ServiceWorkerStorage::DidInitializeOldDiskCache,
1012 weak_factory_.GetWeakPtr(), base::Passed(old_disk_cache.Pass()));
1013
1014 int result = old_disk_cache_ptr->InitWithDiskBackend(
1015 GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
1016 disk_cache_thread_, callback);
1017 if (result == net::ERR_IO_PENDING)
1018 return;
1019 callback.Run(result);
1020 }
1021
1022 void ServiceWorkerStorage::DidInitializeOldDiskCache(
1023 scoped_ptr<ServiceWorkerDiskCache> old_disk_cache,
1024 int result) {
1025 if (result != net::OK) {
1026 LOG(ERROR) << "Failed to initialize the diskcache: " << result;
1027 AbortLazyInitialize(ServiceWorkerMetrics::MIGRATION_ERROR_INITIALIZE);
1028 return;
1029 }
1030
1031 // Start migrating resources stored in the old DiskCache.
1032 scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(
1033 new ServiceWorkerDiskCacheMigrator(old_disk_cache.get(), disk_cache()));
1034 ServiceWorkerDiskCacheMigrator* migrator_ptr = migrator.get();
1035 migrator_ptr->Start(base::Bind(
1036 &ServiceWorkerStorage::DidDiskCacheMigrated, weak_factory_.GetWeakPtr(),
1037 base::Passed(migrator.Pass()), base::Passed(old_disk_cache.Pass())));
1038 }
1039
1040 void ServiceWorkerStorage::DidDiskCacheMigrated(
1041 scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator,
1042 scoped_ptr<ServiceWorkerDiskCache> old_disk_cache,
1043 ServiceWorkerStatusCode status) {
1044 if (status != SERVICE_WORKER_OK) {
1045 LOG(ERROR) << "Failed to migrate the diskcache: " << status;
1046 AbortLazyInitialize(ServiceWorkerMetrics::MIGRATION_ERROR_FAILED);
1047 return;
1048 }
1049
1050 // Delete the old DiskCache directory.
1051 migrator.reset();
1052 old_disk_cache.reset();
1053 PostTaskAndReplyWithResult(
1054 disk_cache_thread_.get(), FROM_HERE,
1055 base::Bind(&base::DeleteFile, GetOldDiskCachePath(), true),
1056 base::Bind(&ServiceWorkerStorage::DidDeleteOldDiskCache,
1057 weak_factory_.GetWeakPtr()));
1058 }
1059
1060 void ServiceWorkerStorage::DidDeleteOldDiskCache(bool deleted) {
1061 if (!deleted) {
1062 LOG(ERROR) << "Failed to delete the old diskcache directory";
1063 AbortLazyInitialize(
1064 ServiceWorkerMetrics::MIGRATION_ERROR_DELETE_DISK_CACHE);
1065 return;
1066 }
1067
1068 ContinueLazyInitialize();
1069 }
1070
1071 void ServiceWorkerStorage::AbortLazyInitialize(
1072 ServiceWorkerMetrics::DiskCacheMigrationResult result) {
falken 2015/06/01 04:31:49 DCHECK(result != OK)?
nhiroki 2015/06/02 09:18:33 Done.
1073 ServiceWorkerMetrics::RecordDiskCacheMigrationResult(result);
1074
1075 // Give up the migration and recreate the whole storage.
1076 ScheduleDeleteAndStartOver();
1077
1078 // Pending tasks will be aborted due to the disabled storage.
1079 for (const base::Closure& pending_task : pending_tasks_)
1080 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
1081 pending_tasks_.clear();
1082 }
1083
1084 void ServiceWorkerStorage::ContinueLazyInitialize() {
970 database_task_manager_->GetTaskRunner()->PostTask( 1085 database_task_manager_->GetTaskRunner()->PostTask(
971 FROM_HERE, 1086 FROM_HERE,
972 base::Bind(&ReadInitialDataFromDB, 1087 base::Bind(&ReadInitialDataFromDB,
973 database_.get(), 1088 database_.get(),
974 base::ThreadTaskRunnerHandle::Get(), 1089 base::ThreadTaskRunnerHandle::Get(),
975 base::Bind(&ServiceWorkerStorage::DidReadInitialData, 1090 base::Bind(&ServiceWorkerStorage::DidReadInitialData,
976 weak_factory_.GetWeakPtr()))); 1091 weak_factory_.GetWeakPtr())));
977 return false;
978 } 1092 }
979 1093
980 void ServiceWorkerStorage::DidReadInitialData( 1094 void ServiceWorkerStorage::DidReadInitialData(
981 InitialData* data, 1095 InitialData* data,
982 ServiceWorkerDatabase::Status status) { 1096 ServiceWorkerDatabase::Status status) {
983 DCHECK(data); 1097 DCHECK(data);
984 DCHECK_EQ(INITIALIZING, state_); 1098 DCHECK_EQ(INITIALIZING, state_);
985 1099
986 if (status == ServiceWorkerDatabase::STATUS_OK) { 1100 if (status == ServiceWorkerDatabase::STATUS_OK) {
987 next_registration_id_ = data->next_registration_id; 1101 next_registration_id_ = data->next_registration_id;
988 next_version_id_ = data->next_version_id; 1102 next_version_id_ = data->next_version_id;
989 next_resource_id_ = data->next_resource_id; 1103 next_resource_id_ = data->next_resource_id;
990 registered_origins_.swap(data->origins); 1104 registered_origins_.swap(data->origins);
991 state_ = INITIALIZED; 1105 state_ = INITIALIZED;
992 } else { 1106 } else {
993 DVLOG(2) << "Failed to initialize: " 1107 DVLOG(2) << "Failed to initialize: "
994 << ServiceWorkerDatabase::StatusToString(status); 1108 << ServiceWorkerDatabase::StatusToString(status);
995 ScheduleDeleteAndStartOver(); 1109 ScheduleDeleteAndStartOver();
996 } 1110 }
997 1111
998 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); 1112 for (const base::Closure& pending_task : pending_tasks_)
999 it != pending_tasks_.end(); ++it) { 1113 RunSoon(FROM_HERE, pending_task);
1000 RunSoon(FROM_HERE, *it);
1001 }
1002 pending_tasks_.clear(); 1114 pending_tasks_.clear();
1003 } 1115 }
1004 1116
1005 void ServiceWorkerStorage::DidFindRegistrationForDocument( 1117 void ServiceWorkerStorage::DidFindRegistrationForDocument(
1006 const GURL& document_url, 1118 const GURL& document_url,
1007 const FindRegistrationCallback& callback, 1119 const FindRegistrationCallback& callback,
1008 int64 callback_id, 1120 int64 callback_id,
1009 const ServiceWorkerDatabase::RegistrationData& data, 1121 const ServiceWorkerDatabase::RegistrationData& data,
1010 const ResourceList& resources, 1122 const ResourceList& resources,
1011 ServiceWorkerDatabase::Status status) { 1123 ServiceWorkerDatabase::Status status) {
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 installing_registrations_.find(registration_id); 1476 installing_registrations_.find(registration_id);
1365 if (found == installing_registrations_.end()) 1477 if (found == installing_registrations_.end())
1366 return NULL; 1478 return NULL;
1367 return found->second.get(); 1479 return found->second.get();
1368 } 1480 }
1369 1481
1370 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { 1482 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
1371 if (disk_cache_) 1483 if (disk_cache_)
1372 return disk_cache_.get(); 1484 return disk_cache_.get();
1373 1485
1374 disk_cache_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend(); 1486 disk_cache_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
1375 1487
1376 base::FilePath path = GetDiskCachePath(); 1488 base::FilePath path = GetDiskCachePath();
1377 if (path.empty()) { 1489 if (path.empty()) {
1378 int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize, 1490 int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize,
1379 net::CompletionCallback()); 1491 net::CompletionCallback());
1380 DCHECK_EQ(net::OK, rv); 1492 DCHECK_EQ(net::OK, rv);
1381 return disk_cache_.get(); 1493 return disk_cache_.get();
1382 } 1494 }
1383 1495
1384 int rv = disk_cache_->InitWithDiskBackend( 1496 int rv = disk_cache_->InitWithDiskBackend(
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1811 callback.Run(SERVICE_WORKER_ERROR_FAILED); 1923 callback.Run(SERVICE_WORKER_ERROR_FAILED);
1812 return; 1924 return;
1813 } 1925 }
1814 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; 1926 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
1815 ServiceWorkerMetrics::RecordDeleteAndStartOverResult( 1927 ServiceWorkerMetrics::RecordDeleteAndStartOverResult(
1816 ServiceWorkerMetrics::DELETE_OK); 1928 ServiceWorkerMetrics::DELETE_OK);
1817 callback.Run(SERVICE_WORKER_OK); 1929 callback.Run(SERVICE_WORKER_OK);
1818 } 1930 }
1819 1931
1820 } // namespace content 1932 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698