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

Side by Side Diff: chrome/browser/sync/engine/syncer_thread.cc

Issue 6182004: [SYNC] Refactor SyncSourceInfo and add support in chrome invalidation client ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: payloads/nudge type merge Created 9 years, 11 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 (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/sync/engine/syncer_thread.h" 5 #include "chrome/browser/sync/engine/syncer_thread.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <queue> 9 #include <queue>
10 #include <string>
11 #include <vector>
akalin 2011/01/21 19:50:09 no need for this anymore
Nicolas Zea 2011/01/21 21:57:44 There is still use of vector for the model type wo
10 12
11 #include "base/rand_util.h" 13 #include "base/rand_util.h"
12 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 14 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
13 #include "build/build_config.h" 15 #include "build/build_config.h"
14 #include "chrome/browser/sync/engine/model_safe_worker.h" 16 #include "chrome/browser/sync/engine/model_safe_worker.h"
15 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 17 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
16 #include "chrome/browser/sync/engine/syncer.h" 18 #include "chrome/browser/sync/engine/syncer.h"
17 #include "chrome/browser/sync/sessions/sync_session.h" 19 #include "chrome/browser/sync/sessions/sync_session.h"
18 #include "jingle/notifier/listener/notification_constants.h" 20 #include "jingle/notifier/listener/notification_constants.h"
19 21
(...skipping 27 matching lines...) Expand all
47 // we want and allows stronger control over the poll rate from the server. We 49 // we want and allows stronger control over the poll rate from the server. We
48 // should probably re-visit this code later and figure out if user idle time 50 // should probably re-visit this code later and figure out if user idle time
49 // is really something we want and make sure it works, if it is. 51 // is really something we want and make sure it works, if it is.
50 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000; 52 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
51 53
52 // Backoff interval randomization factor. 54 // Backoff interval randomization factor.
53 static const int kBackoffRandomizationFactor = 2; 55 static const int kBackoffRandomizationFactor = 2;
54 56
55 const int SyncerThread::kMaxBackoffSeconds = 60 * 60 * 4; // 4 hours. 57 const int SyncerThread::kMaxBackoffSeconds = 60 * 60 * 4; // 4 hours.
56 58
59 void SyncerThread::NudgeSyncerWithPayloads(
60 int milliseconds_from_now,
61 NudgeSource source,
62 const SyncSourceInfo::ModelTypeMap& model_types_with_payloads) {
63 base::AutoLock lock(lock_);
64 if (vault_.syncer_ == NULL) {
65 return;
66 }
67
68 NudgeSyncImpl(milliseconds_from_now, source, model_types_with_payloads);
69 }
70
57 void SyncerThread::NudgeSyncerWithDataTypes( 71 void SyncerThread::NudgeSyncerWithDataTypes(
58 int milliseconds_from_now, 72 int milliseconds_from_now,
59 NudgeSource source, 73 NudgeSource source,
60 const syncable::ModelTypeBitSet& model_types) { 74 const syncable::ModelTypeBitSet& model_types) {
61 base::AutoLock lock(lock_); 75 base::AutoLock lock(lock_);
62 if (vault_.syncer_ == NULL) { 76 if (vault_.syncer_ == NULL) {
63 return; 77 return;
64 } 78 }
65 79
66 NudgeSyncImpl(milliseconds_from_now, source, model_types); 80 SyncSourceInfo::ModelTypeMap model_types_with_payloads;
akalin 2011/01/21 19:50:09 Could use utility function here, too
Nicolas Zea 2011/01/21 21:57:44 Done.
81 for (size_t i = syncable::FIRST_REAL_MODEL_TYPE;
82 i < syncable::MODEL_TYPE_COUNT;
83 ++i) {
84 if (model_types[i]) {
85 model_types_with_payloads[syncable::ModelTypeFromInt(i)] =
86 std::string("");
akalin 2011/01/21 19:50:09 can be just std::string()
Nicolas Zea 2011/01/21 21:57:44 Done.
87 }
88 }
89 NudgeSyncImpl(milliseconds_from_now, source, model_types_with_payloads);
67 } 90 }
68 91
69 void SyncerThread::NudgeSyncer( 92 void SyncerThread::NudgeSyncer(
70 int milliseconds_from_now, 93 int milliseconds_from_now,
71 NudgeSource source) { 94 NudgeSource source) {
72 base::AutoLock lock(lock_); 95 base::AutoLock lock(lock_);
73 if (vault_.syncer_ == NULL) { 96 if (vault_.syncer_ == NULL) {
74 return; 97 return;
75 } 98 }
76 99
77 syncable::ModelTypeBitSet model_types; // All false by default. 100 // Set all enabled datatypes.
78 NudgeSyncImpl(milliseconds_from_now, source, model_types); 101 SyncSourceInfo::ModelTypeMap model_types_with_payloads;
102 ModelSafeRoutingInfo routes;
103 session_context_->registrar()->GetModelSafeRoutingInfo(&routes);
104 for (ModelSafeRoutingInfo::const_iterator i = routes.begin();
akalin 2011/01/21 19:50:09 Room for another util. function to go from ModelSa
Nicolas Zea 2011/01/21 21:57:44 Done.
105 i != routes.end(); ++i) {
106 model_types_with_payloads[i->first] = std::string("");
107 }
108 NudgeSyncImpl(milliseconds_from_now, source, model_types_with_payloads);
79 } 109 }
80 110
81 SyncerThread::SyncerThread(sessions::SyncSessionContext* context) 111 SyncerThread::SyncerThread(sessions::SyncSessionContext* context)
82 : thread_main_started_(false, false), 112 : thread_main_started_(false, false),
83 thread_("SyncEngine_SyncerThread"), 113 thread_("SyncEngine_SyncerThread"),
84 vault_field_changed_(&lock_), 114 vault_field_changed_(&lock_),
85 conn_mgr_hookup_(NULL), 115 conn_mgr_hookup_(NULL),
86 syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds), 116 syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds),
87 syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds), 117 syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds),
88 syncer_polling_interval_(kDefaultShortPollIntervalSeconds), 118 syncer_polling_interval_(kDefaultShortPollIntervalSeconds),
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // event. This will also update the source of the following SyncMain call. 365 // event. This will also update the source of the following SyncMain call.
336 VLOG(1) << "Calling Sync Main at time " << Time::Now().ToInternalValue(); 366 VLOG(1) << "Calling Sync Main at time " << Time::Now().ToInternalValue();
337 bool nudged = false; 367 bool nudged = false;
338 scoped_ptr<SyncSession> session; 368 scoped_ptr<SyncSession> session;
339 session.reset(SyncMain(vault_.syncer_, 369 session.reset(SyncMain(vault_.syncer_,
340 throttled, continue_sync_cycle, &initial_sync_for_thread, &nudged)); 370 throttled, continue_sync_cycle, &initial_sync_for_thread, &nudged));
341 371
342 // Update timing information for how often these datatypes are triggering 372 // Update timing information for how often these datatypes are triggering
343 // nudges. 373 // nudges.
344 base::TimeTicks now = TimeTicks::Now(); 374 base::TimeTicks now = TimeTicks::Now();
345 for (size_t i = syncable::FIRST_REAL_MODEL_TYPE; 375 if (!last_sync_time.is_null()) {
346 i < session->source().second.size(); 376 SyncSourceInfo::ModelTypeMap::const_iterator iter;
347 ++i) { 377 for (iter = session->source().types.begin();
348 if (session->source().second[i]) { 378 iter != session->source().types.end();
349 syncable::PostTimeToTypeHistogram(syncable::ModelType(i), 379 ++iter) {
380 syncable::PostTimeToTypeHistogram(iter->first,
350 now - last_sync_time); 381 now - last_sync_time);
351 } 382 }
352 } 383 }
353 384
354 last_sync_time = now; 385 last_sync_time = now;
355 386
356 VLOG(1) << "Updating the next polling time after SyncMain"; 387 VLOG(1) << "Updating the next polling time after SyncMain";
357 vault_.current_wait_interval_ = CalculatePollingWaitTime( 388 vault_.current_wait_interval_ = CalculatePollingWaitTime(
358 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()), 389 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()),
359 &user_idle_milliseconds, &continue_sync_cycle, nudged); 390 &user_idle_milliseconds, &continue_sync_cycle, nudged);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 VLOG(1) << "Done calling SyncShare."; 598 VLOG(1) << "Done calling SyncShare.";
568 return session.release(); 599 return session.release();
569 } 600 }
570 601
571 SyncSourceInfo SyncerThread::GetAndResetNudgeSource(bool was_throttled, 602 SyncSourceInfo SyncerThread::GetAndResetNudgeSource(bool was_throttled,
572 bool continue_sync_cycle, 603 bool continue_sync_cycle,
573 bool* initial_sync, 604 bool* initial_sync,
574 bool* was_nudged) { 605 bool* was_nudged) {
575 bool nudged = false; 606 bool nudged = false;
576 NudgeSource nudge_source = kUnknown; 607 NudgeSource nudge_source = kUnknown;
577 syncable::ModelTypeBitSet model_types; 608 SyncSourceInfo::ModelTypeMap model_types;
578 // Has the previous sync cycle completed? 609 // Has the previous sync cycle completed?
579 if (continue_sync_cycle) 610 if (continue_sync_cycle)
580 nudge_source = kContinuation; 611 nudge_source = kContinuation;
581 // Update the nudge source if a new nudge has come through during the 612 // Update the nudge source if a new nudge has come through during the
582 // previous sync cycle. 613 // previous sync cycle.
583 if (!vault_.pending_nudge_time_.is_null()) { 614 if (!vault_.pending_nudge_time_.is_null()) {
584 if (!was_throttled) { 615 if (!was_throttled) {
585 nudge_source = vault_.pending_nudge_source_; 616 nudge_source = vault_.pending_nudge_source_;
586 model_types = vault_.pending_nudge_types_; 617 model_types = vault_.pending_nudge_types_;
587 nudged = true; 618 nudged = true;
588 } 619 }
589 VLOG(1) << "Clearing pending nudge from " << vault_.pending_nudge_source_ 620 VLOG(1) << "Clearing pending nudge from " << vault_.pending_nudge_source_
590 << " at tick " << vault_.pending_nudge_time_.ToInternalValue(); 621 << " at tick " << vault_.pending_nudge_time_.ToInternalValue();
591 vault_.pending_nudge_source_ = kUnknown; 622 vault_.pending_nudge_source_ = kUnknown;
592 vault_.pending_nudge_types_.reset(); 623 vault_.pending_nudge_types_.clear();
593 vault_.pending_nudge_time_ = base::TimeTicks(); 624 vault_.pending_nudge_time_ = base::TimeTicks();
594 } 625 }
595 626
596 *was_nudged = nudged; 627 *was_nudged = nudged;
597 628
598 // TODO(tim): Hack for bug 64136 to correctly tag continuations that result 629 // TODO(tim): Hack for bug 64136 to correctly tag continuations that result
599 // from syncer having more work to do. This will be handled properly with 630 // from syncer having more work to do. This will be handled properly with
600 // the message loop based syncer thread, bug 26339. 631 // the message loop based syncer thread, bug 26339.
601 return MakeSyncSourceInfo(nudged || nudge_source == kContinuation, 632 return MakeSyncSourceInfo(nudged || nudge_source == kContinuation,
602 nudge_source, model_types, initial_sync); 633 nudge_source, model_types, initial_sync);
603 } 634 }
604 635
605 SyncSourceInfo SyncerThread::MakeSyncSourceInfo(bool nudged, 636 SyncSourceInfo SyncerThread::MakeSyncSourceInfo(bool nudged,
606 NudgeSource nudge_source, const syncable::ModelTypeBitSet& nudge_types, 637 NudgeSource nudge_source,
638 const SyncSourceInfo::ModelTypeMap& nudge_types,
607 bool* initial_sync) { 639 bool* initial_sync) {
608 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source = 640 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source =
609 sync_pb::GetUpdatesCallerInfo::UNKNOWN; 641 sync_pb::GetUpdatesCallerInfo::UNKNOWN;
610 if (*initial_sync) { 642 if (*initial_sync) {
611 updates_source = sync_pb::GetUpdatesCallerInfo::FIRST_UPDATE; 643 updates_source = sync_pb::GetUpdatesCallerInfo::FIRST_UPDATE;
612 *initial_sync = false; 644 *initial_sync = false;
613 } else if (!nudged) { 645 } else if (!nudged) {
614 updates_source = sync_pb::GetUpdatesCallerInfo::PERIODIC; 646 updates_source = sync_pb::GetUpdatesCallerInfo::PERIODIC;
615 } else { 647 } else {
616 switch (nudge_source) { 648 switch (nudge_source) {
617 case kNotification: 649 case kNotification:
618 updates_source = sync_pb::GetUpdatesCallerInfo::NOTIFICATION; 650 updates_source = sync_pb::GetUpdatesCallerInfo::NOTIFICATION;
619 break; 651 break;
620 case kLocal: 652 case kLocal:
621 updates_source = sync_pb::GetUpdatesCallerInfo::LOCAL; 653 updates_source = sync_pb::GetUpdatesCallerInfo::LOCAL;
622 break; 654 break;
623 case kContinuation: 655 case kContinuation:
624 updates_source = sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; 656 updates_source = sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION;
625 break; 657 break;
626 case kClearPrivateData: 658 case kClearPrivateData:
627 updates_source = sync_pb::GetUpdatesCallerInfo::CLEAR_PRIVATE_DATA; 659 updates_source = sync_pb::GetUpdatesCallerInfo::CLEAR_PRIVATE_DATA;
628 break; 660 break;
629 case kUnknown: 661 case kUnknown:
630 default: 662 default:
631 updates_source = sync_pb::GetUpdatesCallerInfo::UNKNOWN; 663 updates_source = sync_pb::GetUpdatesCallerInfo::UNKNOWN;
632 break; 664 break;
633 } 665 }
634 } 666 }
635 return SyncSourceInfo(updates_source, nudge_types); 667
668 SyncSourceInfo::ModelTypeMap sync_source_types;
669 if (nudge_types.empty()) {
670 // No datatypes requested. This must be a poll so set all enabled datatypes.
671 ModelSafeRoutingInfo routes;
672 session_context_->registrar()->GetModelSafeRoutingInfo(&routes);
673 for (ModelSafeRoutingInfo::const_iterator i = routes.begin();
674 i != routes.end(); ++i) {
675 sync_source_types[i->first] = std::string("");
676 }
677 } else {
678 sync_source_types = nudge_types;
679 }
680
681 return SyncSourceInfo(updates_source, sync_source_types);
636 } 682 }
637 683
638 void SyncerThread::CreateSyncer(const std::string& dirname) { 684 void SyncerThread::CreateSyncer(const std::string& dirname) {
639 base::AutoLock lock(lock_); 685 base::AutoLock lock(lock_);
640 VLOG(1) << "Creating syncer up for: " << dirname; 686 VLOG(1) << "Creating syncer up for: " << dirname;
641 // The underlying database structure is ready, and we should create 687 // The underlying database structure is ready, and we should create
642 // the syncer. 688 // the syncer.
643 CHECK(vault_.syncer_ == NULL); 689 CHECK(vault_.syncer_ == NULL);
644 session_context_->set_account_name(dirname); 690 session_context_->set_account_name(dirname);
645 vault_.syncer_ = new Syncer(); 691 vault_.syncer_ = new Syncer();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // rate. 773 // rate.
728 if (idle >= kPollBackoffThresholdMultiplier * syncer_polling_interval_ms) { 774 if (idle >= kPollBackoffThresholdMultiplier * syncer_polling_interval_ms) {
729 next_wait = std::min(GetRecommendedDelaySeconds( 775 next_wait = std::min(GetRecommendedDelaySeconds(
730 last_interval / 1000), syncer_max_interval_ / 1000) * 1000; 776 last_interval / 1000), syncer_max_interval_ / 1000) * 1000;
731 } 777 }
732 778
733 return next_wait; 779 return next_wait;
734 } 780 }
735 781
736 // Called with mutex_ already locked. 782 // Called with mutex_ already locked.
737 void SyncerThread::NudgeSyncImpl(int milliseconds_from_now, 783 void SyncerThread::NudgeSyncImpl(
738 NudgeSource source, 784 int milliseconds_from_now,
739 const syncable::ModelTypeBitSet& model_types) { 785 NudgeSource source,
786 const SyncSourceInfo::ModelTypeMap& model_types_with_payloads) {
740 // TODO(sync): Add the option to reset the backoff state machine. 787 // TODO(sync): Add the option to reset the backoff state machine.
741 // This is needed so nudges that are a result of the user's desire 788 // This is needed so nudges that are a result of the user's desire
742 // to download updates for a new data type can be satisfied quickly. 789 // to download updates for a new data type can be satisfied quickly.
743 if (vault_.current_wait_interval_.mode == WaitInterval::THROTTLED || 790 if (vault_.current_wait_interval_.mode == WaitInterval::THROTTLED ||
744 vault_.current_wait_interval_.had_nudge_during_backoff) { 791 vault_.current_wait_interval_.had_nudge_during_backoff) {
745 // Drop nudges on the floor if we've already had one since starting this 792 // Drop nudges on the floor if we've already had one since starting this
746 // stage of exponential backoff or we are throttled. 793 // stage of exponential backoff or we are throttled.
747 return; 794 return;
748 } 795 }
749 796
750 // Union the current bitset with any from nudges that may have already 797 // Union the current ModelTypeMap with any from nudges that may have already
751 // posted (coalesce the nudge datatype information). 798 // posted (coalesce the nudge datatype information).
752 // TODO(tim): It seems weird to do this if the sources don't match up (e.g. 799 // TODO(tim): It seems weird to do this if the sources don't match up (e.g.
753 // if pending_source is kLocal and |source| is kClearPrivateData). 800 // if pending_source is kLocal and |source| is kClearPrivateData).
754 vault_.pending_nudge_types_ |= model_types; 801 for (SyncSourceInfo::ModelTypeMap::const_iterator i =
802 model_types_with_payloads.begin();
803 i != model_types_with_payloads.end();
804 ++i) {
805 if (vault_.pending_nudge_types_.count(i->first) == 0) {
806 // If this datatype isn't already in our map, add it.
807 vault_.pending_nudge_types_[i->first] = i->second;
808 } else if (i->second.length() > 0) {
809 // If it is, we only overwrite the payload if the new one is non-empty.
810 vault_.pending_nudge_types_[i->first] = i->second;
811 }
812 }
755 813
756 const TimeTicks nudge_time = TimeTicks::Now() + 814 const TimeTicks nudge_time = TimeTicks::Now() +
757 TimeDelta::FromMilliseconds(milliseconds_from_now); 815 TimeDelta::FromMilliseconds(milliseconds_from_now);
758 if (nudge_time <= vault_.pending_nudge_time_) { 816 if (nudge_time <= vault_.pending_nudge_time_) {
759 VLOG(1) << "Nudge for source " << source 817 VLOG(1) << "Nudge for source " << source
760 << " dropped due to existing later pending nudge"; 818 << " dropped due to existing later pending nudge";
761 return; 819 return;
762 } 820 }
763 821
764 VLOG(1) << "Replacing pending nudge for source " << source 822 VLOG(1) << "Replacing pending nudge for source " << source
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 was_logged = true; 900 was_logged = true;
843 VLOG(1) << "UserIdleTime unimplemented on this platform, synchronization " 901 VLOG(1) << "UserIdleTime unimplemented on this platform, synchronization "
844 "will not throttle when user idle"; 902 "will not throttle when user idle";
845 } 903 }
846 #endif 904 #endif
847 905
848 return 0; 906 return 0;
849 } 907 }
850 908
851 } // namespace browser_sync 909 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698