Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |