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

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: rebase 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 } 201 }
201 202
202 ReadSomeData(); 203 ReadSomeData();
203 } 204 }
204 205
205 } // namespace 206 } // namespace
206 207
207 ServiceWorkerStorage::InitialData::InitialData() 208 ServiceWorkerStorage::InitialData::InitialData()
208 : next_registration_id(kInvalidServiceWorkerRegistrationId), 209 : next_registration_id(kInvalidServiceWorkerRegistrationId),
209 next_version_id(kInvalidServiceWorkerVersionId), 210 next_version_id(kInvalidServiceWorkerVersionId),
210 next_resource_id(kInvalidServiceWorkerResourceId) { 211 next_resource_id(kInvalidServiceWorkerResourceId),
212 disk_cache_migration_needed(false),
213 old_disk_cache_deletion_needed(false) {
211 } 214 }
212 215
213 ServiceWorkerStorage::InitialData::~InitialData() { 216 ServiceWorkerStorage::InitialData::~InitialData() {
214 } 217 }
215 218
216 ServiceWorkerStorage:: 219 ServiceWorkerStorage::
217 DidDeleteRegistrationParams::DidDeleteRegistrationParams() 220 DidDeleteRegistrationParams::DidDeleteRegistrationParams()
218 : registration_id(kInvalidServiceWorkerRegistrationId) { 221 : registration_id(kInvalidServiceWorkerRegistrationId) {
219 } 222 }
220 223
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 : next_registration_id_(kInvalidServiceWorkerRegistrationId), 924 : next_registration_id_(kInvalidServiceWorkerRegistrationId),
922 next_version_id_(kInvalidServiceWorkerVersionId), 925 next_version_id_(kInvalidServiceWorkerVersionId),
923 next_resource_id_(kInvalidServiceWorkerResourceId), 926 next_resource_id_(kInvalidServiceWorkerResourceId),
924 state_(UNINITIALIZED), 927 state_(UNINITIALIZED),
925 path_(path), 928 path_(path),
926 context_(context), 929 context_(context),
927 database_task_manager_(database_task_manager.Pass()), 930 database_task_manager_(database_task_manager.Pass()),
928 disk_cache_thread_(disk_cache_thread), 931 disk_cache_thread_(disk_cache_thread),
929 quota_manager_proxy_(quota_manager_proxy), 932 quota_manager_proxy_(quota_manager_proxy),
930 special_storage_policy_(special_storage_policy), 933 special_storage_policy_(special_storage_policy),
934 disk_cache_migration_needed_(false),
935 old_disk_cache_deletion_needed_(false),
931 is_purge_pending_(false), 936 is_purge_pending_(false),
932 has_checked_for_stale_resources_(false), 937 has_checked_for_stale_resources_(false),
933 weak_factory_(this) { 938 weak_factory_(this) {
934 database_.reset(new ServiceWorkerDatabase(GetDatabasePath())); 939 database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
935 } 940 }
936 941
937 base::FilePath ServiceWorkerStorage::GetDatabasePath() { 942 base::FilePath ServiceWorkerStorage::GetDatabasePath() {
938 if (path_.empty()) 943 if (path_.empty())
939 return base::FilePath(); 944 return base::FilePath();
940 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) 945 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
941 .Append(kDatabaseName); 946 .Append(kDatabaseName);
942 } 947 }
943 948
944 base::FilePath ServiceWorkerStorage::GetDiskCachePath() { 949 base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
945 if (path_.empty()) 950 if (path_.empty())
946 return base::FilePath(); 951 return base::FilePath();
947 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) 952 return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
948 .Append(kDiskCacheName); 953 .Append(kDiskCacheName);
949 } 954 }
950 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
951 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { 963 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
952 if (!context_) 964 if (!context_)
953 return false; 965 return false;
954 966
955 switch (state_) { 967 switch (state_) {
956 case INITIALIZED: 968 case INITIALIZED:
957 return true; 969 return true;
958 case DISABLED: 970 case DISABLED:
959 return false; 971 return false;
960 case INITIALIZING: 972 case INITIALIZING:
(...skipping 19 matching lines...) Expand all
980 InitialData* data, 992 InitialData* data,
981 ServiceWorkerDatabase::Status status) { 993 ServiceWorkerDatabase::Status status) {
982 DCHECK(data); 994 DCHECK(data);
983 DCHECK_EQ(INITIALIZING, state_); 995 DCHECK_EQ(INITIALIZING, state_);
984 996
985 if (status == ServiceWorkerDatabase::STATUS_OK) { 997 if (status == ServiceWorkerDatabase::STATUS_OK) {
986 next_registration_id_ = data->next_registration_id; 998 next_registration_id_ = data->next_registration_id;
987 next_version_id_ = data->next_version_id; 999 next_version_id_ = data->next_version_id;
988 next_resource_id_ = data->next_resource_id; 1000 next_resource_id_ = data->next_resource_id;
989 registered_origins_.swap(data->origins); 1001 registered_origins_.swap(data->origins);
1002 disk_cache_migration_needed_ = data->disk_cache_migration_needed;
1003 old_disk_cache_deletion_needed_ = data->old_disk_cache_deletion_needed;
990 state_ = INITIALIZED; 1004 state_ = INITIALIZED;
991 } else { 1005 } else {
992 DVLOG(2) << "Failed to initialize: " 1006 DVLOG(2) << "Failed to initialize: "
993 << ServiceWorkerDatabase::StatusToString(status); 1007 << ServiceWorkerDatabase::StatusToString(status);
994 ScheduleDeleteAndStartOver(); 1008 ScheduleDeleteAndStartOver();
995 } 1009 }
996 1010
997 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); 1011 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin();
998 it != pending_tasks_.end(); ++it) { 1012 it != pending_tasks_.end(); ++it) {
999 RunSoon(FROM_HERE, *it); 1013 RunSoon(FROM_HERE, *it);
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 ServiceWorkerStorage::FindInstallingRegistrationForId( 1414 ServiceWorkerStorage::FindInstallingRegistrationForId(
1401 int64 registration_id) { 1415 int64 registration_id) {
1402 RegistrationRefsById::const_iterator found = 1416 RegistrationRefsById::const_iterator found =
1403 installing_registrations_.find(registration_id); 1417 installing_registrations_.find(registration_id);
1404 if (found == installing_registrations_.end()) 1418 if (found == installing_registrations_.end())
1405 return NULL; 1419 return NULL;
1406 return found->second.get(); 1420 return found->second.get();
1407 } 1421 }
1408 1422
1409 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { 1423 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
1424 DCHECK_EQ(INITIALIZED, state_);
1410 if (disk_cache_) 1425 if (disk_cache_)
1411 return disk_cache_.get(); 1426 return disk_cache_.get();
1412 1427
1413 disk_cache_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend(); 1428 disk_cache_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
1414 1429
1415 base::FilePath path = GetDiskCachePath(); 1430 base::FilePath path = GetDiskCachePath();
1416 if (path.empty()) { 1431 if (path.empty()) {
1417 int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize, 1432 int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize,
1418 net::CompletionCallback()); 1433 net::CompletionCallback());
1419 DCHECK_EQ(net::OK, rv); 1434 DCHECK_EQ(net::OK, rv);
1420 return disk_cache_.get(); 1435 return disk_cache_.get();
1421 } 1436 }
1422 1437
1438 if (disk_cache_migration_needed_) {
1439 // Defer the start of initialization until a migration is complete.
1440 disk_cache_->set_is_waiting_to_initialize(true);
1441 DCHECK(!disk_cache_migrator_);
1442 disk_cache_migrator_.reset(new ServiceWorkerDiskCacheMigrator(
1443 GetOldDiskCachePath(), GetDiskCachePath(), kMaxDiskCacheSize,
1444 disk_cache_thread_));
1445 disk_cache_migrator_->Start(
1446 base::Bind(&ServiceWorkerStorage::DidMigrateDiskCache,
1447 weak_factory_.GetWeakPtr()));
1448 return disk_cache_.get();
1449 }
1450
1451 if (old_disk_cache_deletion_needed_) {
1452 // Lazily delete the old diskcache.
1453 BrowserThread::PostAfterStartupTask(
1454 FROM_HERE, database_task_manager_->GetTaskRunner(),
1455 base::Bind(&DeleteOldDiskCacheInDB, database_.get(),
1456 GetOldDiskCachePath()));
1457 }
1458
1459 ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
1460 ServiceWorkerMetrics::MIGRATION_NOT_NECESSARY);
1461
1462 InitializeDiskCache();
1463 return disk_cache_.get();
1464 }
1465
1466 void ServiceWorkerStorage::DidMigrateDiskCache(ServiceWorkerStatusCode status) {
1467 disk_cache_migrator_.reset();
1468 if (status != SERVICE_WORKER_OK) {
1469 OnDiskCacheMigrationFailed();
1470 return;
1471 }
1472
1473 PostTaskAndReplyWithResult(
1474 database_task_manager_->GetTaskRunner(), FROM_HERE,
1475 base::Bind(&ServiceWorkerDatabase::SetDiskCacheMigrationNotNeeded,
1476 base::Unretained(database_.get())),
1477 base::Bind(&ServiceWorkerStorage::DidSetDiskCacheMigrationNotNeeded,
1478 weak_factory_.GetWeakPtr()));
1479 }
1480
1481 void ServiceWorkerStorage::DidSetDiskCacheMigrationNotNeeded(
1482 ServiceWorkerDatabase::Status status) {
1483 if (status != ServiceWorkerDatabase::STATUS_OK) {
1484 OnDiskCacheMigrationFailed();
1485 return;
1486 }
1487
1488 // Lazily delete the old diskcache and update the database.
1489 BrowserThread::PostAfterStartupTask(
1490 FROM_HERE, database_task_manager_->GetTaskRunner(),
1491 base::Bind(&DeleteOldDiskCacheInDB, database_.get(),
1492 GetOldDiskCachePath()));
1493
1494 ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
1495 ServiceWorkerMetrics::MIGRATION_OK);
1496 InitializeDiskCache();
1497 }
1498
1499 void ServiceWorkerStorage::OnDiskCacheMigrationFailed() {
1500 ServiceWorkerMetrics::RecordDiskCacheMigrationResult(
1501 ServiceWorkerMetrics::MIGRATION_ERROR_FAILED);
1502
1503 // Give up migration and recreate the whole storage.
1504 ScheduleDeleteAndStartOver();
1505
1506 // Lazily delete the old diskcache. Don't have to update the database
1507 // because it will be deleted by DeleteAndStartOver.
1508 BrowserThread::PostAfterStartupTask(
1509 FROM_HERE, disk_cache_thread_.get(),
1510 base::Bind(base::IgnoreResult(&base::DeleteFile), GetOldDiskCachePath(),
1511 true));
1512 }
1513
1514 void ServiceWorkerStorage::InitializeDiskCache() {
1515 disk_cache_->set_is_waiting_to_initialize(false);
1423 int rv = disk_cache_->InitWithDiskBackend( 1516 int rv = disk_cache_->InitWithDiskBackend(
1424 path, 1517 GetDiskCachePath(), kMaxDiskCacheSize, false, disk_cache_thread_,
1425 kMaxDiskCacheSize,
1426 false,
1427 disk_cache_thread_,
1428 base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized, 1518 base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized,
1429 weak_factory_.GetWeakPtr())); 1519 weak_factory_.GetWeakPtr()));
1430 if (rv != net::ERR_IO_PENDING) 1520 if (rv != net::ERR_IO_PENDING)
1431 OnDiskCacheInitialized(rv); 1521 OnDiskCacheInitialized(rv);
1432
1433 return disk_cache_.get();
1434 } 1522 }
1435 1523
1436 void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) { 1524 void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
1437 if (rv != net::OK) { 1525 if (rv != net::OK) {
1438 LOG(ERROR) << "Failed to open the serviceworker diskcache: " 1526 LOG(ERROR) << "Failed to open the serviceworker diskcache: "
1439 << net::ErrorToString(rv); 1527 << net::ErrorToString(rv);
1440 ScheduleDeleteAndStartOver(); 1528 ScheduleDeleteAndStartOver();
1441 } 1529 }
1442 ServiceWorkerMetrics::CountInitDiskCacheResult(rv == net::OK); 1530 ServiceWorkerMetrics::CountInitDiskCacheResult(rv == net::OK);
1443 } 1531 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 ServiceWorkerDatabase::Status status = 1669 ServiceWorkerDatabase::Status status =
1582 database->GetNextAvailableIds(&data->next_registration_id, 1670 database->GetNextAvailableIds(&data->next_registration_id,
1583 &data->next_version_id, 1671 &data->next_version_id,
1584 &data->next_resource_id); 1672 &data->next_resource_id);
1585 if (status != ServiceWorkerDatabase::STATUS_OK) { 1673 if (status != ServiceWorkerDatabase::STATUS_OK) {
1586 original_task_runner->PostTask( 1674 original_task_runner->PostTask(
1587 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 1675 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1588 return; 1676 return;
1589 } 1677 }
1590 1678
1679 status =
1680 database->IsDiskCacheMigrationNeeded(&data->disk_cache_migration_needed);
1681 if (status != ServiceWorkerDatabase::STATUS_OK) {
1682 original_task_runner->PostTask(
1683 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1684 return;
1685 }
1686
1687 status = database->IsOldDiskCacheDeletionNeeded(
1688 &data->old_disk_cache_deletion_needed);
1689 if (status != ServiceWorkerDatabase::STATUS_OK) {
1690 original_task_runner->PostTask(
1691 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1692 return;
1693 }
1694
1591 status = database->GetOriginsWithRegistrations(&data->origins); 1695 status = database->GetOriginsWithRegistrations(&data->origins);
1592 original_task_runner->PostTask( 1696 original_task_runner->PostTask(
1593 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 1697 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1594 } 1698 }
1595 1699
1700 void ServiceWorkerStorage::DeleteOldDiskCacheInDB(
1701 ServiceWorkerDatabase* database,
1702 const base::FilePath& disk_cache_path) {
1703 // Ignore a failure. A retry will happen on the next initialization.
1704 if (!base::DeleteFile(disk_cache_path, true))
1705 return;
1706 database->SetOldDiskCacheDeletionNotNeeded();
1707 }
1708
1596 void ServiceWorkerStorage::DeleteRegistrationFromDB( 1709 void ServiceWorkerStorage::DeleteRegistrationFromDB(
1597 ServiceWorkerDatabase* database, 1710 ServiceWorkerDatabase* database,
1598 scoped_refptr<base::SequencedTaskRunner> original_task_runner, 1711 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1599 int64 registration_id, 1712 int64 registration_id,
1600 const GURL& origin, 1713 const GURL& origin,
1601 const DeleteRegistrationCallback& callback) { 1714 const DeleteRegistrationCallback& callback) {
1602 DCHECK(database); 1715 DCHECK(database);
1603 1716
1604 ServiceWorkerDatabase::RegistrationData deleted_version; 1717 ServiceWorkerDatabase::RegistrationData deleted_version;
1605 std::vector<int64> newly_purgeable_resources; 1718 std::vector<int64> newly_purgeable_resources;
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 callback.Run(SERVICE_WORKER_ERROR_FAILED); 1963 callback.Run(SERVICE_WORKER_ERROR_FAILED);
1851 return; 1964 return;
1852 } 1965 }
1853 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; 1966 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
1854 ServiceWorkerMetrics::RecordDeleteAndStartOverResult( 1967 ServiceWorkerMetrics::RecordDeleteAndStartOverResult(
1855 ServiceWorkerMetrics::DELETE_OK); 1968 ServiceWorkerMetrics::DELETE_OK);
1856 callback.Run(SERVICE_WORKER_OK); 1969 callback.Run(SERVICE_WORKER_OK);
1857 } 1970 }
1858 1971
1859 } // namespace content 1972 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698