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

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

Issue 6270006: Revert 72685 - [SYNC] Refactor SyncSourceInfo and add support in chrome inval... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: 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 <queue> 9 #include <queue>
9 #include <string>
10 #include <vector>
11 10
12 #include "base/rand_util.h" 11 #include "base/rand_util.h"
13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 12 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
14 #include "build/build_config.h" 13 #include "build/build_config.h"
15 #include "chrome/browser/sync/engine/model_safe_worker.h" 14 #include "chrome/browser/sync/engine/model_safe_worker.h"
16 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 15 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
17 #include "chrome/browser/sync/engine/syncer.h" 16 #include "chrome/browser/sync/engine/syncer.h"
18 #include "chrome/browser/sync/sessions/sync_session.h" 17 #include "chrome/browser/sync/sessions/sync_session.h"
19 #include "jingle/notifier/listener/notification_constants.h" 18 #include "jingle/notifier/listener/notification_constants.h"
20 19
21 #if defined(OS_MACOSX) 20 #if defined(OS_MACOSX)
22 #include <CoreFoundation/CFNumber.h> 21 #include <CoreFoundation/CFNumber.h>
23 #include <IOKit/IOTypes.h> 22 #include <IOKit/IOTypes.h>
24 #include <IOKit/IOKitLib.h> 23 #include <IOKit/IOKitLib.h>
25 #endif 24 #endif
26 25
27 using std::priority_queue; 26 using std::priority_queue;
28 using std::min; 27 using std::min;
29 using base::Time; 28 using base::Time;
30 using base::TimeDelta; 29 using base::TimeDelta;
31 using base::TimeTicks; 30 using base::TimeTicks;
32 31
33 namespace browser_sync { 32 namespace browser_sync {
34 33
35 using sessions::SyncSession; 34 using sessions::SyncSession;
36 using sessions::SyncSessionSnapshot; 35 using sessions::SyncSessionSnapshot;
37 using sessions::SyncSourceInfo; 36 using sessions::SyncSourceInfo;
38 using sessions::TypePayloadMap;
39 37
40 // We use high values here to ensure that failure to receive poll updates from 38 // We use high values here to ensure that failure to receive poll updates from
41 // the server doesn't result in rapid-fire polling from the client due to low 39 // the server doesn't result in rapid-fire polling from the client due to low
42 // local limits. 40 // local limits.
43 const int SyncerThread::kDefaultShortPollIntervalSeconds = 3600 * 8; 41 const int SyncerThread::kDefaultShortPollIntervalSeconds = 3600 * 8;
44 const int SyncerThread::kDefaultLongPollIntervalSeconds = 3600 * 12; 42 const int SyncerThread::kDefaultLongPollIntervalSeconds = 3600 * 12;
45 43
46 // TODO(tim): This is used to regulate the short poll (when notifications are 44 // TODO(tim): This is used to regulate the short poll (when notifications are
47 // disabled) based on user idle time. If it is set to a smaller value than 45 // disabled) based on user idle time. If it is set to a smaller value than
48 // the short poll interval, it basically does nothing; for now, this is what 46 // the short poll interval, it basically does nothing; for now, this is what
49 // we want and allows stronger control over the poll rate from the server. We 47 // we want and allows stronger control over the poll rate from the server. We
50 // should probably re-visit this code later and figure out if user idle time 48 // should probably re-visit this code later and figure out if user idle time
51 // is really something we want and make sure it works, if it is. 49 // is really something we want and make sure it works, if it is.
52 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000; 50 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
53 51
54 // Backoff interval randomization factor. 52 // Backoff interval randomization factor.
55 static const int kBackoffRandomizationFactor = 2; 53 static const int kBackoffRandomizationFactor = 2;
56 54
57 const int SyncerThread::kMaxBackoffSeconds = 60 * 60 * 4; // 4 hours. 55 const int SyncerThread::kMaxBackoffSeconds = 60 * 60 * 4; // 4 hours.
58 56
59 void SyncerThread::NudgeSyncerWithPayloads(
60 int milliseconds_from_now,
61 NudgeSource source,
62 const TypePayloadMap& 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
71 void SyncerThread::NudgeSyncerWithDataTypes( 57 void SyncerThread::NudgeSyncerWithDataTypes(
72 int milliseconds_from_now, 58 int milliseconds_from_now,
73 NudgeSource source, 59 NudgeSource source,
74 const syncable::ModelTypeBitSet& model_types) { 60 const syncable::ModelTypeBitSet& model_types) {
75 base::AutoLock lock(lock_); 61 base::AutoLock lock(lock_);
76 if (vault_.syncer_ == NULL) { 62 if (vault_.syncer_ == NULL) {
77 return; 63 return;
78 } 64 }
79 65
80 TypePayloadMap model_types_with_payloads = 66 NudgeSyncImpl(milliseconds_from_now, source, model_types);
81 sessions::ModelTypeBitSetToTypePayloadMap(model_types, std::string());
82 NudgeSyncImpl(milliseconds_from_now, source, model_types_with_payloads);
83 } 67 }
84 68
85 void SyncerThread::NudgeSyncer( 69 void SyncerThread::NudgeSyncer(
86 int milliseconds_from_now, 70 int milliseconds_from_now,
87 NudgeSource source) { 71 NudgeSource source) {
88 base::AutoLock lock(lock_); 72 base::AutoLock lock(lock_);
89 if (vault_.syncer_ == NULL) { 73 if (vault_.syncer_ == NULL) {
90 return; 74 return;
91 } 75 }
92 76
93 // Set all enabled datatypes. 77 syncable::ModelTypeBitSet model_types; // All false by default.
94 ModelSafeRoutingInfo routes; 78 NudgeSyncImpl(milliseconds_from_now, source, model_types);
95 session_context_->registrar()->GetModelSafeRoutingInfo(&routes);
96 TypePayloadMap model_types_with_payloads =
97 sessions::RoutingInfoToTypePayloadMap(routes, std::string());
98 NudgeSyncImpl(milliseconds_from_now, source, model_types_with_payloads);
99 } 79 }
100 80
101 SyncerThread::SyncerThread(sessions::SyncSessionContext* context) 81 SyncerThread::SyncerThread(sessions::SyncSessionContext* context)
102 : thread_main_started_(false, false), 82 : thread_main_started_(false, false),
103 thread_("SyncEngine_SyncerThread"), 83 thread_("SyncEngine_SyncerThread"),
104 vault_field_changed_(&lock_), 84 vault_field_changed_(&lock_),
105 conn_mgr_hookup_(NULL), 85 conn_mgr_hookup_(NULL),
106 syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds), 86 syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds),
107 syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds), 87 syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds),
108 syncer_polling_interval_(kDefaultShortPollIntervalSeconds), 88 syncer_polling_interval_(kDefaultShortPollIntervalSeconds),
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 // event. This will also update the source of the following SyncMain call. 335 // event. This will also update the source of the following SyncMain call.
356 VLOG(1) << "Calling Sync Main at time " << Time::Now().ToInternalValue(); 336 VLOG(1) << "Calling Sync Main at time " << Time::Now().ToInternalValue();
357 bool nudged = false; 337 bool nudged = false;
358 scoped_ptr<SyncSession> session; 338 scoped_ptr<SyncSession> session;
359 session.reset(SyncMain(vault_.syncer_, 339 session.reset(SyncMain(vault_.syncer_,
360 throttled, continue_sync_cycle, &initial_sync_for_thread, &nudged)); 340 throttled, continue_sync_cycle, &initial_sync_for_thread, &nudged));
361 341
362 // Update timing information for how often these datatypes are triggering 342 // Update timing information for how often these datatypes are triggering
363 // nudges. 343 // nudges.
364 base::TimeTicks now = TimeTicks::Now(); 344 base::TimeTicks now = TimeTicks::Now();
365 if (!last_sync_time.is_null()) { 345 for (size_t i = syncable::FIRST_REAL_MODEL_TYPE;
366 TypePayloadMap::const_iterator iter; 346 i < session->source().second.size();
367 for (iter = session->source().types.begin(); 347 ++i) {
368 iter != session->source().types.end(); 348 if (session->source().second[i]) {
369 ++iter) { 349 syncable::PostTimeToTypeHistogram(syncable::ModelType(i),
370 syncable::PostTimeToTypeHistogram(iter->first,
371 now - last_sync_time); 350 now - last_sync_time);
372 } 351 }
373 } 352 }
374 353
375 last_sync_time = now; 354 last_sync_time = now;
376 355
377 VLOG(1) << "Updating the next polling time after SyncMain"; 356 VLOG(1) << "Updating the next polling time after SyncMain";
378 vault_.current_wait_interval_ = CalculatePollingWaitTime( 357 vault_.current_wait_interval_ = CalculatePollingWaitTime(
379 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()), 358 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()),
380 &user_idle_milliseconds, &continue_sync_cycle, nudged); 359 &user_idle_milliseconds, &continue_sync_cycle, nudged);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 VLOG(1) << "Done calling SyncShare."; 567 VLOG(1) << "Done calling SyncShare.";
589 return session.release(); 568 return session.release();
590 } 569 }
591 570
592 SyncSourceInfo SyncerThread::GetAndResetNudgeSource(bool was_throttled, 571 SyncSourceInfo SyncerThread::GetAndResetNudgeSource(bool was_throttled,
593 bool continue_sync_cycle, 572 bool continue_sync_cycle,
594 bool* initial_sync, 573 bool* initial_sync,
595 bool* was_nudged) { 574 bool* was_nudged) {
596 bool nudged = false; 575 bool nudged = false;
597 NudgeSource nudge_source = kUnknown; 576 NudgeSource nudge_source = kUnknown;
598 TypePayloadMap model_types_with_payloads; 577 syncable::ModelTypeBitSet model_types;
599 // Has the previous sync cycle completed? 578 // Has the previous sync cycle completed?
600 if (continue_sync_cycle) 579 if (continue_sync_cycle)
601 nudge_source = kContinuation; 580 nudge_source = kContinuation;
602 // Update the nudge source if a new nudge has come through during the 581 // Update the nudge source if a new nudge has come through during the
603 // previous sync cycle. 582 // previous sync cycle.
604 if (!vault_.pending_nudge_time_.is_null()) { 583 if (!vault_.pending_nudge_time_.is_null()) {
605 if (!was_throttled) { 584 if (!was_throttled) {
606 nudge_source = vault_.pending_nudge_source_; 585 nudge_source = vault_.pending_nudge_source_;
607 model_types_with_payloads = vault_.pending_nudge_types_; 586 model_types = vault_.pending_nudge_types_;
608 nudged = true; 587 nudged = true;
609 } 588 }
610 VLOG(1) << "Clearing pending nudge from " << vault_.pending_nudge_source_ 589 VLOG(1) << "Clearing pending nudge from " << vault_.pending_nudge_source_
611 << " at tick " << vault_.pending_nudge_time_.ToInternalValue(); 590 << " at tick " << vault_.pending_nudge_time_.ToInternalValue();
612 vault_.pending_nudge_source_ = kUnknown; 591 vault_.pending_nudge_source_ = kUnknown;
613 vault_.pending_nudge_types_.clear(); 592 vault_.pending_nudge_types_.reset();
614 vault_.pending_nudge_time_ = base::TimeTicks(); 593 vault_.pending_nudge_time_ = base::TimeTicks();
615 } 594 }
616 595
617 *was_nudged = nudged; 596 *was_nudged = nudged;
618 597
619 // TODO(tim): Hack for bug 64136 to correctly tag continuations that result 598 // TODO(tim): Hack for bug 64136 to correctly tag continuations that result
620 // from syncer having more work to do. This will be handled properly with 599 // from syncer having more work to do. This will be handled properly with
621 // the message loop based syncer thread, bug 26339. 600 // the message loop based syncer thread, bug 26339.
622 return MakeSyncSourceInfo(nudged || nudge_source == kContinuation, 601 return MakeSyncSourceInfo(nudged || nudge_source == kContinuation,
623 nudge_source, model_types_with_payloads, initial_sync); 602 nudge_source, model_types, initial_sync);
624 } 603 }
625 604
626 SyncSourceInfo SyncerThread::MakeSyncSourceInfo(bool nudged, 605 SyncSourceInfo SyncerThread::MakeSyncSourceInfo(bool nudged,
627 NudgeSource nudge_source, 606 NudgeSource nudge_source, const syncable::ModelTypeBitSet& nudge_types,
628 const TypePayloadMap& model_types_with_payloads,
629 bool* initial_sync) { 607 bool* initial_sync) {
630 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source = 608 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source =
631 sync_pb::GetUpdatesCallerInfo::UNKNOWN; 609 sync_pb::GetUpdatesCallerInfo::UNKNOWN;
632 if (*initial_sync) { 610 if (*initial_sync) {
633 updates_source = sync_pb::GetUpdatesCallerInfo::FIRST_UPDATE; 611 updates_source = sync_pb::GetUpdatesCallerInfo::FIRST_UPDATE;
634 *initial_sync = false; 612 *initial_sync = false;
635 } else if (!nudged) { 613 } else if (!nudged) {
636 updates_source = sync_pb::GetUpdatesCallerInfo::PERIODIC; 614 updates_source = sync_pb::GetUpdatesCallerInfo::PERIODIC;
637 } else { 615 } else {
638 switch (nudge_source) { 616 switch (nudge_source) {
639 case kNotification: 617 case kNotification:
640 updates_source = sync_pb::GetUpdatesCallerInfo::NOTIFICATION; 618 updates_source = sync_pb::GetUpdatesCallerInfo::NOTIFICATION;
641 break; 619 break;
642 case kLocal: 620 case kLocal:
643 updates_source = sync_pb::GetUpdatesCallerInfo::LOCAL; 621 updates_source = sync_pb::GetUpdatesCallerInfo::LOCAL;
644 break; 622 break;
645 case kContinuation: 623 case kContinuation:
646 updates_source = sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; 624 updates_source = sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION;
647 break; 625 break;
648 case kClearPrivateData: 626 case kClearPrivateData:
649 updates_source = sync_pb::GetUpdatesCallerInfo::CLEAR_PRIVATE_DATA; 627 updates_source = sync_pb::GetUpdatesCallerInfo::CLEAR_PRIVATE_DATA;
650 break; 628 break;
651 case kUnknown: 629 case kUnknown:
652 default: 630 default:
653 updates_source = sync_pb::GetUpdatesCallerInfo::UNKNOWN; 631 updates_source = sync_pb::GetUpdatesCallerInfo::UNKNOWN;
654 break; 632 break;
655 } 633 }
656 } 634 }
657 635 return SyncSourceInfo(updates_source, nudge_types);
658 TypePayloadMap sync_source_types;
659 if (model_types_with_payloads.empty()) {
660 // No datatypes requested. This must be a poll so set all enabled datatypes.
661 ModelSafeRoutingInfo routes;
662 session_context_->registrar()->GetModelSafeRoutingInfo(&routes);
663 sync_source_types = sessions::RoutingInfoToTypePayloadMap(routes,
664 std::string());
665 } else {
666 sync_source_types = model_types_with_payloads;
667 }
668
669 return SyncSourceInfo(updates_source, sync_source_types);
670 } 636 }
671 637
672 void SyncerThread::CreateSyncer(const std::string& dirname) { 638 void SyncerThread::CreateSyncer(const std::string& dirname) {
673 base::AutoLock lock(lock_); 639 base::AutoLock lock(lock_);
674 VLOG(1) << "Creating syncer up for: " << dirname; 640 VLOG(1) << "Creating syncer up for: " << dirname;
675 // The underlying database structure is ready, and we should create 641 // The underlying database structure is ready, and we should create
676 // the syncer. 642 // the syncer.
677 CHECK(vault_.syncer_ == NULL); 643 CHECK(vault_.syncer_ == NULL);
678 session_context_->set_account_name(dirname); 644 session_context_->set_account_name(dirname);
679 vault_.syncer_ = new Syncer(); 645 vault_.syncer_ = new Syncer();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 // rate. 727 // rate.
762 if (idle >= kPollBackoffThresholdMultiplier * syncer_polling_interval_ms) { 728 if (idle >= kPollBackoffThresholdMultiplier * syncer_polling_interval_ms) {
763 next_wait = std::min(GetRecommendedDelaySeconds( 729 next_wait = std::min(GetRecommendedDelaySeconds(
764 last_interval / 1000), syncer_max_interval_ / 1000) * 1000; 730 last_interval / 1000), syncer_max_interval_ / 1000) * 1000;
765 } 731 }
766 732
767 return next_wait; 733 return next_wait;
768 } 734 }
769 735
770 // Called with mutex_ already locked. 736 // Called with mutex_ already locked.
771 void SyncerThread::NudgeSyncImpl( 737 void SyncerThread::NudgeSyncImpl(int milliseconds_from_now,
772 int milliseconds_from_now, 738 NudgeSource source,
773 NudgeSource source, 739 const syncable::ModelTypeBitSet& model_types) {
774 const TypePayloadMap& model_types_with_payloads) {
775 // TODO(sync): Add the option to reset the backoff state machine. 740 // TODO(sync): Add the option to reset the backoff state machine.
776 // This is needed so nudges that are a result of the user's desire 741 // This is needed so nudges that are a result of the user's desire
777 // to download updates for a new data type can be satisfied quickly. 742 // to download updates for a new data type can be satisfied quickly.
778 if (vault_.current_wait_interval_.mode == WaitInterval::THROTTLED || 743 if (vault_.current_wait_interval_.mode == WaitInterval::THROTTLED ||
779 vault_.current_wait_interval_.had_nudge_during_backoff) { 744 vault_.current_wait_interval_.had_nudge_during_backoff) {
780 // Drop nudges on the floor if we've already had one since starting this 745 // Drop nudges on the floor if we've already had one since starting this
781 // stage of exponential backoff or we are throttled. 746 // stage of exponential backoff or we are throttled.
782 return; 747 return;
783 } 748 }
784 749
785 // Union the current TypePayloadMap with any from nudges that may have already 750 // Union the current bitset with any from nudges that may have already
786 // posted (coalesce the nudge datatype information). 751 // posted (coalesce the nudge datatype information).
787 // TODO(tim): It seems weird to do this if the sources don't match up (e.g. 752 // TODO(tim): It seems weird to do this if the sources don't match up (e.g.
788 // if pending_source is kLocal and |source| is kClearPrivateData). 753 // if pending_source is kLocal and |source| is kClearPrivateData).
789 sessions::CoalescePayloads(&vault_.pending_nudge_types_, 754 vault_.pending_nudge_types_ |= model_types;
790 model_types_with_payloads);
791 755
792 const TimeTicks nudge_time = TimeTicks::Now() + 756 const TimeTicks nudge_time = TimeTicks::Now() +
793 TimeDelta::FromMilliseconds(milliseconds_from_now); 757 TimeDelta::FromMilliseconds(milliseconds_from_now);
794 if (nudge_time <= vault_.pending_nudge_time_) { 758 if (nudge_time <= vault_.pending_nudge_time_) {
795 VLOG(1) << "Nudge for source " << source 759 VLOG(1) << "Nudge for source " << source
796 << " dropped due to existing later pending nudge"; 760 << " dropped due to existing later pending nudge";
797 return; 761 return;
798 } 762 }
799 763
800 VLOG(1) << "Replacing pending nudge for source " << source 764 VLOG(1) << "Replacing pending nudge for source " << source
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 was_logged = true; 842 was_logged = true;
879 VLOG(1) << "UserIdleTime unimplemented on this platform, synchronization " 843 VLOG(1) << "UserIdleTime unimplemented on this platform, synchronization "
880 "will not throttle when user idle"; 844 "will not throttle when user idle";
881 } 845 }
882 #endif 846 #endif
883 847
884 return 0; 848 return 0;
885 } 849 }
886 850
887 } // namespace browser_sync 851 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_thread.h ('k') | chrome/browser/sync/engine/syncer_thread_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698