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

Side by Side Diff: content/browser/background_sync/background_sync_manager.cc

Issue 1106523002: [BackgroundSync] Fire one-shot sync events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@store_origin
Patch Set: Rebase Created 5 years, 8 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/background_sync/background_sync_manager.h" 5 #include "content/browser/background_sync/background_sync_manager.h"
6 6
7 #include "base/barrier_closure.h" 7 #include "base/barrier_closure.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "content/browser/background_sync/background_sync_network_observer.h" 9 #include "content/browser/background_sync/background_sync_network_observer.h"
10 #include "content/browser/service_worker/service_worker_context_wrapper.h" 10 #include "content/browser/service_worker/service_worker_context_wrapper.h"
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 registration_proto.periodicity()); 222 registration_proto.periodicity());
223 BackgroundSyncRegistration* registration = 223 BackgroundSyncRegistration* registration =
224 &registrations->registration_map[registration_key]; 224 &registrations->registration_map[registration_key];
225 225
226 registration->id = registration_proto.id(); 226 registration->id = registration_proto.id();
227 registration->tag = registration_proto.tag(); 227 registration->tag = registration_proto.tag();
228 registration->periodicity = registration_proto.periodicity(); 228 registration->periodicity = registration_proto.periodicity();
229 registration->min_period = registration_proto.min_period(); 229 registration->min_period = registration_proto.min_period();
230 registration->network_state = registration_proto.network_state(); 230 registration->network_state = registration_proto.network_state();
231 registration->power_state = registration_proto.power_state(); 231 registration->power_state = registration_proto.power_state();
232 registration->sync_state = registration_proto.sync_state();
233 if (registration->sync_state == SYNC_STATE_FIRING) {
234 // If the browser (or worker) closed while firing the event, consider
235 // it pending again>
236 registration->sync_state = SYNC_STATE_PENDING;
237 }
232 } 238 }
233 } 239 }
234 240
235 if (corruption_detected) 241 if (corruption_detected)
236 break; 242 break;
237 } 243 }
238 244
239 if (corruption_detected) { 245 if (corruption_detected) {
240 LOG(ERROR) << "Corruption detected in background sync backend"; 246 LOG(ERROR) << "Corruption detected in background sync backend";
241 DisableAndClearManager(base::Bind(callback)); 247 DisableAndClearManager(base::Bind(callback));
242 return; 248 return;
243 } 249 }
244 250
245 // TODO(jkarlin): Call the scheduling algorithm here. 251 FireReadyEvents();
246 252
247 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 253 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
248 } 254 }
249 255
250 void BackgroundSyncManager::RegisterImpl( 256 void BackgroundSyncManager::RegisterImpl(
251 const GURL& origin, 257 const GURL& origin,
252 int64 sw_registration_id, 258 int64 sw_registration_id,
253 const BackgroundSyncRegistration& sync_registration, 259 const BackgroundSyncRegistration& sync_registration,
254 const StatusAndRegistrationCallback& callback) { 260 const StatusAndRegistrationCallback& callback) {
255 if (disabled_) { 261 if (disabled_) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 const BackgroundSyncRegistration& registration = 370 const BackgroundSyncRegistration& registration =
365 key_and_registration.second; 371 key_and_registration.second;
366 BackgroundSyncRegistrationProto* registration_proto = 372 BackgroundSyncRegistrationProto* registration_proto =
367 registrations_proto.add_registration(); 373 registrations_proto.add_registration();
368 registration_proto->set_id(registration.id); 374 registration_proto->set_id(registration.id);
369 registration_proto->set_tag(registration.tag); 375 registration_proto->set_tag(registration.tag);
370 registration_proto->set_periodicity(registration.periodicity); 376 registration_proto->set_periodicity(registration.periodicity);
371 registration_proto->set_min_period(registration.min_period); 377 registration_proto->set_min_period(registration.min_period);
372 registration_proto->set_network_state(registration.network_state); 378 registration_proto->set_network_state(registration.network_state);
373 registration_proto->set_power_state(registration.power_state); 379 registration_proto->set_power_state(registration.power_state);
380 registration_proto->set_sync_state(registration.sync_state);
374 } 381 }
375 std::string serialized; 382 std::string serialized;
376 bool success = registrations_proto.SerializeToString(&serialized); 383 bool success = registrations_proto.SerializeToString(&serialized);
377 DCHECK(success); 384 DCHECK(success);
378 385
379 StoreDataInBackend(sw_registration_id, registrations.origin, 386 StoreDataInBackend(sw_registration_id, registrations.origin,
380 kBackgroundSyncUserDataKey, serialized, callback); 387 kBackgroundSyncUserDataKey, serialized, callback);
381 } 388 }
382 389
383 void BackgroundSyncManager::RegisterDidStore( 390 void BackgroundSyncManager::RegisterDidStore(
(...skipping 11 matching lines...) Expand all
395 } 402 }
396 403
397 if (status != SERVICE_WORKER_OK) { 404 if (status != SERVICE_WORKER_OK) {
398 LOG(ERROR) << "BackgroundSync failed to store registration due to backend " 405 LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
399 "failure."; 406 "failure.";
400 DisableAndClearManager( 407 DisableAndClearManager(
401 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration())); 408 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
402 return; 409 return;
403 } 410 }
404 411
405 // TODO(jkarlin): Run the registration algorithm. 412 FireReadyEvents();
406 base::MessageLoop::current()->PostTask( 413 base::MessageLoop::current()->PostTask(
407 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, new_registration)); 414 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, new_registration));
408 } 415 }
409 416
410 void BackgroundSyncManager::RemoveRegistrationFromMap( 417 void BackgroundSyncManager::RemoveRegistrationFromMap(
411 int64 sw_registration_id, 418 int64 sw_registration_id,
412 const RegistrationKey& registration_key) { 419 const RegistrationKey& registration_key) {
413 DCHECK(LookupRegistration(sw_registration_id, registration_key)); 420 DCHECK(LookupRegistration(sw_registration_id, registration_key));
414 421
415 BackgroundSyncRegistrations* registrations = 422 BackgroundSyncRegistrations* registrations =
(...skipping 30 matching lines...) Expand all
446 void BackgroundSyncManager::GetDataFromBackend( 453 void BackgroundSyncManager::GetDataFromBackend(
447 const std::string& backend_key, 454 const std::string& backend_key,
448 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback& 455 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
449 callback) { 456 callback) {
450 DCHECK_CURRENTLY_ON(BrowserThread::IO); 457 DCHECK_CURRENTLY_ON(BrowserThread::IO);
451 458
452 service_worker_context_->GetUserDataForAllRegistrations(backend_key, 459 service_worker_context_->GetUserDataForAllRegistrations(backend_key,
453 callback); 460 callback);
454 } 461 }
455 462
463 void BackgroundSyncManager::FireOneShotSync(
464 const scoped_refptr<ServiceWorkerVersion>& active_version,
465 const ServiceWorkerVersion::StatusCallback& callback) {
466 DCHECK_CURRENTLY_ON(BrowserThread::IO);
467
468 active_version->DispatchSyncEvent(callback);
469 }
470
456 void BackgroundSyncManager::UnregisterImpl( 471 void BackgroundSyncManager::UnregisterImpl(
457 const GURL& origin, 472 const GURL& origin,
458 int64 sw_registration_id, 473 int64 sw_registration_id,
459 const RegistrationKey& registration_key, 474 const RegistrationKey& registration_key,
460 BackgroundSyncRegistration::RegistrationId sync_registration_id, 475 BackgroundSyncRegistration::RegistrationId sync_registration_id,
461 const StatusCallback& callback) { 476 const StatusCallback& callback) {
462 if (disabled_) { 477 if (disabled_) {
463 base::MessageLoop::current()->PostTask( 478 base::MessageLoop::current()->PostTask(
464 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE)); 479 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE));
465 return; 480 return;
(...skipping 27 matching lines...) Expand all
493 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE)); 508 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE));
494 return; 509 return;
495 } 510 }
496 511
497 if (status != SERVICE_WORKER_OK) { 512 if (status != SERVICE_WORKER_OK) {
498 LOG(ERROR) << "BackgroundSync failed to unregister due to backend failure."; 513 LOG(ERROR) << "BackgroundSync failed to unregister due to backend failure.";
499 DisableAndClearManager(base::Bind(callback, ERROR_TYPE_STORAGE)); 514 DisableAndClearManager(base::Bind(callback, ERROR_TYPE_STORAGE));
500 return; 515 return;
501 } 516 }
502 517
503 // TODO(jkarlin): Run the registration algorithm.
504 base::MessageLoop::current()->PostTask(FROM_HERE, 518 base::MessageLoop::current()->PostTask(FROM_HERE,
505 base::Bind(callback, ERROR_TYPE_OK)); 519 base::Bind(callback, ERROR_TYPE_OK));
506 } 520 }
507 521
508 void BackgroundSyncManager::GetRegistrationImpl( 522 void BackgroundSyncManager::GetRegistrationImpl(
509 const GURL& origin, 523 const GURL& origin,
510 int64 sw_registration_id, 524 int64 sw_registration_id,
511 const RegistrationKey& registration_key, 525 const RegistrationKey& registration_key,
512 const StatusAndRegistrationCallback& callback) { 526 const StatusAndRegistrationCallback& callback) {
513 if (disabled_) { 527 if (disabled_) {
(...skipping 25 matching lines...) Expand all
539 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 553 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
540 } 554 }
541 555
542 void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure& callback) { 556 void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure& callback) {
543 sw_to_registrations_map_.clear(); 557 sw_to_registrations_map_.clear();
544 disabled_ = false; 558 disabled_ = false;
545 InitImpl(callback); 559 InitImpl(callback);
546 } 560 }
547 561
548 void BackgroundSyncManager::OnNetworkChanged() { 562 void BackgroundSyncManager::OnNetworkChanged() {
549 // TODO(jkarlin): Run the scheduling algorithm here if initialized and not 563 FireReadyEvents();
550 // disabled.
551 } 564 }
552 565
553 void BackgroundSyncManager::PendingStatusAndRegistrationCallback( 566 void BackgroundSyncManager::PendingStatusAndRegistrationCallback(
554 const StatusAndRegistrationCallback& callback, 567 const StatusAndRegistrationCallback& callback,
555 ErrorType error, 568 ErrorType error,
556 const BackgroundSyncRegistration& sync_registration) { 569 const BackgroundSyncRegistration& sync_registration) {
557 // The callback might delete this object, so hang onto a weak ptr to find out. 570 // The callback might delete this object, so hang onto a weak ptr to find out.
558 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr(); 571 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
559 callback.Run(error, sync_registration); 572 callback.Run(error, sync_registration);
560 if (manager) 573 if (manager)
(...skipping 11 matching lines...) Expand all
572 } 585 }
573 586
574 void BackgroundSyncManager::PendingClosure(const base::Closure& callback) { 587 void BackgroundSyncManager::PendingClosure(const base::Closure& callback) {
575 // The callback might delete this object, so hang onto a weak ptr to find out. 588 // The callback might delete this object, so hang onto a weak ptr to find out.
576 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr(); 589 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
577 callback.Run(); 590 callback.Run();
578 if (manager) 591 if (manager)
579 op_scheduler_.CompleteOperationAndRunNext(); 592 op_scheduler_.CompleteOperationAndRunNext();
580 } 593 }
581 594
595 bool BackgroundSyncManager::IsRegistrationReadyToFire(
596 const BackgroundSyncRegistration& registration) {
597 // TODO(jkarlin): Add support for firing periodic registrations.
598 if (registration.periodicity == SYNC_PERIODIC)
599 return false;
600
601 if (registration.sync_state != SYNC_STATE_PENDING)
602 return false;
603
604 DCHECK_EQ(SYNC_ONE_SHOT, registration.periodicity);
605
606 return network_observer_->NetworkSufficient(registration.network_state);
607 }
608
609 void BackgroundSyncManager::FireReadyEvents() {
610 DCHECK_CURRENTLY_ON(BrowserThread::IO);
611 if (disabled_)
612 return;
613
614 op_scheduler_.ScheduleOperation(
615 base::Bind(&BackgroundSyncManager::FireReadyEventsImpl,
616 weak_ptr_factory_.GetWeakPtr(), MakeEmptyCompletion()));
617 }
618
619 void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) {
620 if (disabled_) {
621 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
622 return;
623 }
624
625 // Find the registrations that are ready to run.
626 std::vector<std::pair<int64, RegistrationKey>> sw_id_and_keys_to_fire;
627
628 for (auto& sw_id_and_registrations : sw_to_registrations_map_) {
629 const int64 service_worker_id = sw_id_and_registrations.first;
630 for (auto& key_and_registration :
631 sw_id_and_registrations.second.registration_map) {
632 BackgroundSyncRegistration* registration = &key_and_registration.second;
633 if (IsRegistrationReadyToFire(*registration)) {
634 sw_id_and_keys_to_fire.push_back(
635 std::make_pair(service_worker_id, key_and_registration.first));
636 // The state change is not saved to persistent storage because
637 // if the sync event is killed mid-sync then it should return to
638 // SYNC_STATE_PENDING.
639 registration->sync_state = SYNC_STATE_FIRING;
640 }
641 }
642 }
643
644 // Fire the sync event of the ready registrations and run |callback| once
645 // they're all done.
646 base::Closure barrier_closure =
647 base::BarrierClosure(sw_id_and_keys_to_fire.size(), base::Bind(callback));
648
649 for (const auto& sw_id_and_key : sw_id_and_keys_to_fire) {
650 int64 service_worker_id = sw_id_and_key.first;
651 const BackgroundSyncRegistration* registration =
652 LookupRegistration(service_worker_id, sw_id_and_key.second);
653
654 service_worker_context_->FindRegistrationForId(
655 service_worker_id, sw_to_registrations_map_[service_worker_id].origin,
656 base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration,
657 weak_ptr_factory_.GetWeakPtr(), sw_id_and_key.second,
658 registration->id, barrier_closure));
659 }
660 }
661
662 void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
663 const RegistrationKey& registration_key,
664 BackgroundSyncRegistration::RegistrationId registration_id,
665 const base::Closure& callback,
666 ServiceWorkerStatusCode service_worker_status,
667 const scoped_refptr<ServiceWorkerRegistration>&
668 service_worker_registration) {
669 if (service_worker_status != SERVICE_WORKER_OK) {
670 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
671 return;
672 }
673
674 ServiceWorkerVersion* active_version =
675 service_worker_registration->active_version();
676 if (!active_version) {
677 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
iclelland 2015/04/28 02:48:53 Will this happen if the service worker is still ac
jkarlin 2015/04/28 14:41:00 Ah, good point. I'll check for active registration
jkarlin 2015/04/28 16:39:22 Followup CL is here: https://crrev.com/1110993003
678 return;
679 }
680
681 FireOneShotSync(active_version,
682 base::Bind(&BackgroundSyncManager::EventComplete,
683 weak_ptr_factory_.GetWeakPtr(),
684 service_worker_registration->id(),
685 registration_key, registration_id));
686
687 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
688 }
689
690 void BackgroundSyncManager::EventComplete(
691 int64 service_worker_id,
692 const RegistrationKey& key,
693 BackgroundSyncRegistration::RegistrationId sync_registration_id,
694 ServiceWorkerStatusCode status_code) {
695 DCHECK_CURRENTLY_ON(BrowserThread::IO);
696
697 if (disabled_)
698 return;
699
700 op_scheduler_.ScheduleOperation(
701 base::Bind(&BackgroundSyncManager::EventCompleteImpl,
702 weak_ptr_factory_.GetWeakPtr(), service_worker_id, key,
703 sync_registration_id, status_code, MakeEmptyCompletion()));
704 }
705
706 void BackgroundSyncManager::EventCompleteImpl(
iclelland 2015/04/28 02:48:53 It looks like there are situations here where the
jkarlin 2015/04/28 14:41:00 Are you referring to the early returns below? In a
iclelland 2015/04/28 18:50:39 Yes, those ones. So if I'm following the code corr
jkarlin 2015/04/28 21:00:08 We should be good. If it's disabled_ then all memo
707 int64 service_worker_id,
708 const RegistrationKey& key,
709 BackgroundSyncRegistration::RegistrationId sync_registration_id,
710 ServiceWorkerStatusCode status_code,
711 const base::Closure& callback) {
712 DCHECK_CURRENTLY_ON(BrowserThread::IO);
713
714 if (disabled_) {
715 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
716 return;
717 }
718
719 BackgroundSyncRegistration* registration =
720 LookupRegistration(service_worker_id, key);
721 if (!registration || registration->id != sync_registration_id) {
722 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
723 return;
724 }
725
726 if (registration->periodicity == SYNC_ONE_SHOT) {
727 if (status_code != SERVICE_WORKER_OK) {
728 // TODO(jkarlin) Fire the sync event on the next page load controlled by
729 // this registration. (crbug.com/479665)
730 registration->sync_state = SYNC_STATE_FAILED;
731 } else {
732 registration = nullptr;
733 RemoveRegistrationFromMap(service_worker_id, key);
734 }
735 } else {
736 // TODO(jkarlin): Add support for running periodic syncs. (crbug.com/479674)
737 NOTREACHED();
738 }
739
740 StoreRegistrations(
741 service_worker_id,
742 base::Bind(&BackgroundSyncManager::EventCompleteDidStore,
743 weak_ptr_factory_.GetWeakPtr(), service_worker_id, callback));
744 }
745
746 void BackgroundSyncManager::EventCompleteDidStore(
747 int64 service_worker_id,
748 const base::Closure& callback,
749 ServiceWorkerStatusCode status_code) {
750 if (status_code == SERVICE_WORKER_ERROR_NOT_FOUND) {
751 // The registration is gone.
752 sw_to_registrations_map_.erase(service_worker_id);
753 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
754 return;
755 }
756
757 if (status_code != SERVICE_WORKER_OK) {
758 LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
759 "failure.";
760 DisableAndClearManager(base::Bind(callback));
761 return;
762 }
763
764 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
765 }
766
582 base::Closure BackgroundSyncManager::MakeEmptyCompletion() { 767 base::Closure BackgroundSyncManager::MakeEmptyCompletion() {
583 return base::Bind(&BackgroundSyncManager::PendingClosure, 768 return base::Bind(&BackgroundSyncManager::PendingClosure,
584 weak_ptr_factory_.GetWeakPtr(), 769 weak_ptr_factory_.GetWeakPtr(),
585 base::Bind(base::DoNothing)); 770 base::Bind(base::DoNothing));
586 } 771 }
587 772
588 BackgroundSyncManager::StatusAndRegistrationCallback 773 BackgroundSyncManager::StatusAndRegistrationCallback
589 BackgroundSyncManager::MakeStatusAndRegistrationCompletion( 774 BackgroundSyncManager::MakeStatusAndRegistrationCompletion(
590 const StatusAndRegistrationCallback& callback) { 775 const StatusAndRegistrationCallback& callback) {
591 return base::Bind( 776 return base::Bind(
592 &BackgroundSyncManager::PendingStatusAndRegistrationCallback, 777 &BackgroundSyncManager::PendingStatusAndRegistrationCallback,
593 weak_ptr_factory_.GetWeakPtr(), callback); 778 weak_ptr_factory_.GetWeakPtr(), callback);
594 } 779 }
595 780
596 BackgroundSyncManager::StatusCallback 781 BackgroundSyncManager::StatusCallback
597 BackgroundSyncManager::MakeStatusCompletion(const StatusCallback& callback) { 782 BackgroundSyncManager::MakeStatusCompletion(const StatusCallback& callback) {
598 return base::Bind(&BackgroundSyncManager::PendingStatusCallback, 783 return base::Bind(&BackgroundSyncManager::PendingStatusCallback,
599 weak_ptr_factory_.GetWeakPtr(), callback); 784 weak_ptr_factory_.GetWeakPtr(), callback);
600 } 785 }
601 786
602 } // namespace content 787 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698