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

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

Issue 374873002: Service Worker: Delay stale resource cleanup (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch for landing Created 6 years, 5 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 | Annotate | Revision Log
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 <string> 7 #include <string>
8 8
9 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 base::Owned(registrations))); 264 base::Owned(registrations)));
265 } 265 }
266 266
267 void ServiceWorkerStorage::StoreRegistration( 267 void ServiceWorkerStorage::StoreRegistration(
268 ServiceWorkerRegistration* registration, 268 ServiceWorkerRegistration* registration,
269 ServiceWorkerVersion* version, 269 ServiceWorkerVersion* version,
270 const StatusCallback& callback) { 270 const StatusCallback& callback) {
271 DCHECK(registration); 271 DCHECK(registration);
272 DCHECK(version); 272 DCHECK(version);
273 273
274 DCHECK(state_ == INITIALIZED || state_ == DISABLED); 274 DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
275 if (state_ != INITIALIZED || !context_) { 275 if (IsDisabled() || !context_) {
276 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 276 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
277 return; 277 return;
278 } 278 }
279 279
280 ServiceWorkerDatabase::RegistrationData data; 280 ServiceWorkerDatabase::RegistrationData data;
281 data.registration_id = registration->id(); 281 data.registration_id = registration->id();
282 data.scope = registration->pattern(); 282 data.scope = registration->pattern();
283 data.script = registration->script_url(); 283 data.script = registration->script_url();
284 data.has_fetch_handler = true; 284 data.has_fetch_handler = true;
285 data.version_id = version->version_id(); 285 data.version_id = version->version_id();
286 data.last_update_check = base::Time::Now(); 286 data.last_update_check = base::Time::Now();
287 data.is_active = false; // initially stored in the waiting state 287 data.is_active = false; // initially stored in the waiting state
288 288
289 ResourceList resources; 289 ResourceList resources;
290 version->script_cache_map()->GetResources(&resources); 290 version->script_cache_map()->GetResources(&resources);
291 291
292 if (!has_checked_for_stale_resources_)
293 DeleteStaleResources();
294
292 database_task_runner_->PostTask( 295 database_task_runner_->PostTask(
293 FROM_HERE, 296 FROM_HERE,
294 base::Bind(&WriteRegistrationInDB, 297 base::Bind(&WriteRegistrationInDB,
295 database_.get(), 298 database_.get(),
296 base::MessageLoopProxy::current(), 299 base::MessageLoopProxy::current(),
297 data, resources, 300 data, resources,
298 base::Bind(&ServiceWorkerStorage::DidStoreRegistration, 301 base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
299 weak_factory_.GetWeakPtr(), 302 weak_factory_.GetWeakPtr(),
300 callback))); 303 callback)));
301 } 304 }
302 305
303 void ServiceWorkerStorage::UpdateToActiveState( 306 void ServiceWorkerStorage::UpdateToActiveState(
304 ServiceWorkerRegistration* registration, 307 ServiceWorkerRegistration* registration,
305 const StatusCallback& callback) { 308 const StatusCallback& callback) {
306 DCHECK(registration); 309 DCHECK(registration);
307 310
308 DCHECK(state_ == INITIALIZED || state_ == DISABLED); 311 DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
309 if (state_ != INITIALIZED || !context_) { 312 if (IsDisabled() || !context_) {
310 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 313 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
311 return; 314 return;
312 } 315 }
313 316
314 PostTaskAndReplyWithResult( 317 PostTaskAndReplyWithResult(
315 database_task_runner_, 318 database_task_runner_,
316 FROM_HERE, 319 FROM_HERE,
317 base::Bind(&ServiceWorkerDatabase::UpdateVersionToActive, 320 base::Bind(&ServiceWorkerDatabase::UpdateVersionToActive,
318 base::Unretained(database_.get()), 321 base::Unretained(database_.get()),
319 registration->id(), 322 registration->id(),
320 registration->script_url().GetOrigin()), 323 registration->script_url().GetOrigin()),
321 base::Bind(&ServiceWorkerStorage::DidUpdateToActiveState, 324 base::Bind(&ServiceWorkerStorage::DidUpdateToActiveState,
322 weak_factory_.GetWeakPtr(), 325 weak_factory_.GetWeakPtr(),
323 callback)); 326 callback));
324 } 327 }
325 328
326 void ServiceWorkerStorage::DeleteRegistration( 329 void ServiceWorkerStorage::DeleteRegistration(
327 int64 registration_id, 330 int64 registration_id,
328 const GURL& origin, 331 const GURL& origin,
329 const StatusCallback& callback) { 332 const StatusCallback& callback) {
330 DCHECK(state_ == INITIALIZED || state_ == DISABLED); 333 DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
331 if (state_ != INITIALIZED || !context_) { 334 if (IsDisabled() || !context_) {
332 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 335 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
333 return; 336 return;
334 } 337 }
335 338
339 if (!has_checked_for_stale_resources_)
340 DeleteStaleResources();
341
336 database_task_runner_->PostTask( 342 database_task_runner_->PostTask(
337 FROM_HERE, 343 FROM_HERE,
338 base::Bind(&DeleteRegistrationFromDB, 344 base::Bind(&DeleteRegistrationFromDB,
339 database_.get(), 345 database_.get(),
340 base::MessageLoopProxy::current(), 346 base::MessageLoopProxy::current(),
341 registration_id, origin, 347 registration_id, origin,
342 base::Bind(&ServiceWorkerStorage::DidDeleteRegistration, 348 base::Bind(&ServiceWorkerStorage::DidDeleteRegistration,
343 weak_factory_.GetWeakPtr(), origin, callback))); 349 weak_factory_.GetWeakPtr(), origin, callback)));
344 350
345 // TODO(michaeln): Either its instance should also be 351 // TODO(michaeln): Either its instance should also be
346 // removed from liveregistrations map or the live object 352 // removed from liveregistrations map or the live object
347 // should marked as deleted in some way and not 'findable' 353 // should marked as deleted in some way and not 'findable'
348 // thereafter. 354 // thereafter.
349 } 355 }
350 356
351 scoped_ptr<ServiceWorkerResponseReader> 357 scoped_ptr<ServiceWorkerResponseReader>
352 ServiceWorkerStorage::CreateResponseReader(int64 response_id) { 358 ServiceWorkerStorage::CreateResponseReader(int64 response_id) {
353 return make_scoped_ptr( 359 return make_scoped_ptr(
354 new ServiceWorkerResponseReader(response_id, disk_cache())); 360 new ServiceWorkerResponseReader(response_id, disk_cache()));
355 } 361 }
356 362
357 scoped_ptr<ServiceWorkerResponseWriter> 363 scoped_ptr<ServiceWorkerResponseWriter>
358 ServiceWorkerStorage::CreateResponseWriter(int64 response_id) { 364 ServiceWorkerStorage::CreateResponseWriter(int64 response_id) {
359 return make_scoped_ptr( 365 return make_scoped_ptr(
360 new ServiceWorkerResponseWriter(response_id, disk_cache())); 366 new ServiceWorkerResponseWriter(response_id, disk_cache()));
361 } 367 }
362 368
363 void ServiceWorkerStorage::StoreUncommittedReponseId(int64 id) { 369 void ServiceWorkerStorage::StoreUncommittedResponseId(int64 id) {
364 DCHECK_NE(kInvalidServiceWorkerResponseId, id); 370 DCHECK_NE(kInvalidServiceWorkerResponseId, id);
371 DCHECK_EQ(INITIALIZED, state_);
372
373 if (!has_checked_for_stale_resources_)
374 DeleteStaleResources();
375
365 database_task_runner_->PostTask( 376 database_task_runner_->PostTask(
366 FROM_HERE, 377 FROM_HERE,
367 base::Bind(base::IgnoreResult( 378 base::Bind(base::IgnoreResult(
368 &ServiceWorkerDatabase::WriteUncommittedResourceIds), 379 &ServiceWorkerDatabase::WriteUncommittedResourceIds),
369 base::Unretained(database_.get()), 380 base::Unretained(database_.get()),
370 std::set<int64>(&id, &id + 1))); 381 std::set<int64>(&id, &id + 1)));
371 } 382 }
372 383
373 void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) { 384 void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) {
374 DCHECK_NE(kInvalidServiceWorkerResponseId, id); 385 DCHECK_NE(kInvalidServiceWorkerResponseId, id);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 : next_registration_id_(kInvalidServiceWorkerRegistrationId), 474 : next_registration_id_(kInvalidServiceWorkerRegistrationId),
464 next_version_id_(kInvalidServiceWorkerVersionId), 475 next_version_id_(kInvalidServiceWorkerVersionId),
465 next_resource_id_(kInvalidServiceWorkerResourceId), 476 next_resource_id_(kInvalidServiceWorkerResourceId),
466 state_(UNINITIALIZED), 477 state_(UNINITIALIZED),
467 path_(path), 478 path_(path),
468 context_(context), 479 context_(context),
469 database_task_runner_(database_task_runner), 480 database_task_runner_(database_task_runner),
470 disk_cache_thread_(disk_cache_thread), 481 disk_cache_thread_(disk_cache_thread),
471 quota_manager_proxy_(quota_manager_proxy), 482 quota_manager_proxy_(quota_manager_proxy),
472 is_purge_pending_(false), 483 is_purge_pending_(false),
484 has_checked_for_stale_resources_(false),
473 weak_factory_(this) { 485 weak_factory_(this) {
474 database_.reset(new ServiceWorkerDatabase(GetDatabasePath())); 486 database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
475 } 487 }
476 488
477 base::FilePath ServiceWorkerStorage::GetDatabasePath() { 489 base::FilePath ServiceWorkerStorage::GetDatabasePath() {
478 if (path_.empty()) 490 if (path_.empty())
479 return base::FilePath(); 491 return base::FilePath();
480 return path_.Append(kServiceWorkerDirectory).Append(kDatabaseName); 492 return path_.Append(kServiceWorkerDirectory).Append(kDatabaseName);
481 } 493 }
482 494
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 ServiceWorkerDatabase::Status status) { 531 ServiceWorkerDatabase::Status status) {
520 DCHECK(data); 532 DCHECK(data);
521 DCHECK_EQ(INITIALIZING, state_); 533 DCHECK_EQ(INITIALIZING, state_);
522 534
523 if (status == ServiceWorkerDatabase::STATUS_OK) { 535 if (status == ServiceWorkerDatabase::STATUS_OK) {
524 next_registration_id_ = data->next_registration_id; 536 next_registration_id_ = data->next_registration_id;
525 next_version_id_ = data->next_version_id; 537 next_version_id_ = data->next_version_id;
526 next_resource_id_ = data->next_resource_id; 538 next_resource_id_ = data->next_resource_id;
527 registered_origins_.swap(data->origins); 539 registered_origins_.swap(data->origins);
528 state_ = INITIALIZED; 540 state_ = INITIALIZED;
529 StartPurgingResources(
530 std::vector<int64>(data->purgeable_resource_ids.begin(),
531 data->purgeable_resource_ids.end()));
532 } else { 541 } else {
533 // TODO(nhiroki): Stringify |status| using StatusToString() defined in 542 // TODO(nhiroki): Stringify |status| using StatusToString() defined in
534 // service_worker_database.cc. 543 // service_worker_database.cc.
535 DVLOG(2) << "Failed to initialize: " << status; 544 DVLOG(2) << "Failed to initialize: " << status;
536 ScheduleDeleteAndStartOver(); 545 ScheduleDeleteAndStartOver();
537 } 546 }
538 547
539 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); 548 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin();
540 it != pending_tasks_.end(); ++it) { 549 it != pending_tasks_.end(); ++it) {
541 RunSoon(FROM_HERE, *it); 550 RunSoon(FROM_HERE, *it);
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 if (version && version->HasControllee()) { 865 if (version && version->HasControllee()) {
857 deleted_version_resource_ids_[version_id] = resources; 866 deleted_version_resource_ids_[version_id] = resources;
858 version->AddListener(this); 867 version->AddListener(this);
859 } else { 868 } else {
860 StartPurgingResources(resources); 869 StartPurgingResources(resources);
861 } 870 }
862 } 871 }
863 872
864 void ServiceWorkerStorage::StartPurgingResources( 873 void ServiceWorkerStorage::StartPurgingResources(
865 const std::vector<int64>& ids) { 874 const std::vector<int64>& ids) {
875 DCHECK(has_checked_for_stale_resources_);
866 for (size_t i = 0; i < ids.size(); ++i) 876 for (size_t i = 0; i < ids.size(); ++i)
867 purgeable_resource_ids_.push_back(ids[i]); 877 purgeable_resource_ids_.push_back(ids[i]);
868 ContinuePurgingResources(); 878 ContinuePurgingResources();
869 } 879 }
870 880
871 void ServiceWorkerStorage::StartPurgingResources( 881 void ServiceWorkerStorage::StartPurgingResources(
872 const ResourceList& resources) { 882 const ResourceList& resources) {
883 DCHECK(has_checked_for_stale_resources_);
873 for (size_t i = 0; i < resources.size(); ++i) 884 for (size_t i = 0; i < resources.size(); ++i)
874 purgeable_resource_ids_.push_back(resources[i].resource_id); 885 purgeable_resource_ids_.push_back(resources[i].resource_id);
875 ContinuePurgingResources(); 886 ContinuePurgingResources();
876 } 887 }
877 888
878 void ServiceWorkerStorage::ContinuePurgingResources() { 889 void ServiceWorkerStorage::ContinuePurgingResources() {
879 if (purgeable_resource_ids_.empty() || is_purge_pending_) 890 if (purgeable_resource_ids_.empty() || is_purge_pending_)
880 return; 891 return;
881 892
882 // Do one at a time until we're done, use RunSoon to avoid recursion when 893 // Do one at a time until we're done, use RunSoon to avoid recursion when
(...skipping 22 matching lines...) Expand all
905 database_task_runner_->PostTask( 916 database_task_runner_->PostTask(
906 FROM_HERE, 917 FROM_HERE,
907 base::Bind(base::IgnoreResult( 918 base::Bind(base::IgnoreResult(
908 &ServiceWorkerDatabase::ClearPurgeableResourceIds), 919 &ServiceWorkerDatabase::ClearPurgeableResourceIds),
909 base::Unretained(database_.get()), 920 base::Unretained(database_.get()),
910 std::set<int64>(&id, &id + 1))); 921 std::set<int64>(&id, &id + 1)));
911 922
912 ContinuePurgingResources(); 923 ContinuePurgingResources();
913 } 924 }
914 925
926 void ServiceWorkerStorage::DeleteStaleResources() {
927 DCHECK(!has_checked_for_stale_resources_);
928 has_checked_for_stale_resources_ = true;
929 database_task_runner_->PostTask(
930 FROM_HERE,
931 base::Bind(&ServiceWorkerStorage::CollectStaleResourcesFromDB,
932 database_.get(),
933 base::MessageLoopProxy::current(),
934 base::Bind(&ServiceWorkerStorage::DidCollectStaleResources,
935 weak_factory_.GetWeakPtr())));
936 }
937
938 void ServiceWorkerStorage::DidCollectStaleResources(
939 const std::vector<int64>& stale_resource_ids,
940 ServiceWorkerDatabase::Status status) {
941 DCHECK_EQ(ServiceWorkerDatabase::STATUS_OK, status);
942 if (status != ServiceWorkerDatabase::STATUS_OK)
943 return;
944 StartPurgingResources(stale_resource_ids);
945 }
946
947 void ServiceWorkerStorage::CollectStaleResourcesFromDB(
948 ServiceWorkerDatabase* database,
949 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
950 const GetResourcesCallback& callback) {
951 std::set<int64> ids;
952 ServiceWorkerDatabase::Status status =
953 database->GetUncommittedResourceIds(&ids);
954 if (status != ServiceWorkerDatabase::STATUS_OK) {
955 original_task_runner->PostTask(
956 FROM_HERE,
957 base::Bind(
958 callback, std::vector<int64>(ids.begin(), ids.end()), status));
959 return;
960 }
961
962 status = database->PurgeUncommittedResourceIds(ids);
963 if (status != ServiceWorkerDatabase::STATUS_OK) {
964 original_task_runner->PostTask(
965 FROM_HERE,
966 base::Bind(
967 callback, std::vector<int64>(ids.begin(), ids.end()), status));
968 return;
969 }
970
971 ids.clear();
972 status = database->GetPurgeableResourceIds(&ids);
973 original_task_runner->PostTask(
974 FROM_HERE,
975 base::Bind(callback, std::vector<int64>(ids.begin(), ids.end()), status));
976 }
977
915 void ServiceWorkerStorage::ReadInitialDataFromDB( 978 void ServiceWorkerStorage::ReadInitialDataFromDB(
916 ServiceWorkerDatabase* database, 979 ServiceWorkerDatabase* database,
917 scoped_refptr<base::SequencedTaskRunner> original_task_runner, 980 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
918 const InitializeCallback& callback) { 981 const InitializeCallback& callback) {
919 DCHECK(database); 982 DCHECK(database);
920 scoped_ptr<ServiceWorkerStorage::InitialData> data( 983 scoped_ptr<ServiceWorkerStorage::InitialData> data(
921 new ServiceWorkerStorage::InitialData()); 984 new ServiceWorkerStorage::InitialData());
922 985
923 ServiceWorkerDatabase::Status status = 986 ServiceWorkerDatabase::Status status =
924 database->GetNextAvailableIds(&data->next_registration_id, 987 database->GetNextAvailableIds(&data->next_registration_id,
925 &data->next_version_id, 988 &data->next_version_id,
926 &data->next_resource_id); 989 &data->next_resource_id);
927 if (status != ServiceWorkerDatabase::STATUS_OK) { 990 if (status != ServiceWorkerDatabase::STATUS_OK) {
928 original_task_runner->PostTask( 991 original_task_runner->PostTask(
929 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 992 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
930 return; 993 return;
931 } 994 }
932 995
933 status = database->GetOriginsWithRegistrations(&data->origins); 996 status = database->GetOriginsWithRegistrations(&data->origins);
934 if (status != ServiceWorkerDatabase::STATUS_OK) {
935 original_task_runner->PostTask(
936 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
937 return;
938 }
939
940 // TODO: Also purge uncommitted resources.
941 status = database->GetPurgeableResourceIds(&data->purgeable_resource_ids);
942 original_task_runner->PostTask( 997 original_task_runner->PostTask(
943 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 998 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
944 } 999 }
945 1000
946 void ServiceWorkerStorage::DeleteRegistrationFromDB( 1001 void ServiceWorkerStorage::DeleteRegistrationFromDB(
947 ServiceWorkerDatabase* database, 1002 ServiceWorkerDatabase* database,
948 scoped_refptr<base::SequencedTaskRunner> original_task_runner, 1003 scoped_refptr<base::SequencedTaskRunner> original_task_runner,
949 int64 registration_id, 1004 int64 registration_id,
950 const GURL& origin, 1005 const GURL& origin,
951 const DeleteRegistrationCallback& callback) { 1006 const DeleteRegistrationCallback& callback) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 // Give up the corruption recovery until the browser restarts. 1196 // Give up the corruption recovery until the browser restarts.
1142 LOG(ERROR) << "Failed to delete the diskcache."; 1197 LOG(ERROR) << "Failed to delete the diskcache.";
1143 callback.Run(SERVICE_WORKER_ERROR_FAILED); 1198 callback.Run(SERVICE_WORKER_ERROR_FAILED);
1144 return; 1199 return;
1145 } 1200 }
1146 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully."; 1201 DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
1147 callback.Run(SERVICE_WORKER_OK); 1202 callback.Run(SERVICE_WORKER_OK);
1148 } 1203 }
1149 1204
1150 } // namespace content 1205 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698