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

Side by Side Diff: sync/engine/sync_scheduler_impl.cc

Issue 10837231: sync: add InternalComponentsFactory::Switches to simplify passing switches to internal components. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: pass switches in test_profile_sync_service.cc Created 8 years, 4 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/engine/sync_scheduler_impl.h" 5 #include "sync/engine/sync_scheduler_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/rand_util.h" 15 #include "sync/engine/backoff_delay_provider.h"
16 #include "sync/engine/syncer.h" 16 #include "sync/engine/syncer.h"
17 #include "sync/engine/throttled_data_type_tracker.h" 17 #include "sync/engine/throttled_data_type_tracker.h"
18 #include "sync/protocol/proto_enum_conversions.h" 18 #include "sync/protocol/proto_enum_conversions.h"
19 #include "sync/protocol/sync.pb.h" 19 #include "sync/protocol/sync.pb.h"
20 #include "sync/util/data_type_histogram.h" 20 #include "sync/util/data_type_histogram.h"
21 #include "sync/util/logging.h" 21 #include "sync/util/logging.h"
22 22
23 using base::TimeDelta; 23 using base::TimeDelta;
24 using base::TimeTicks; 24 using base::TimeTicks;
25 25
26 namespace syncer { 26 namespace syncer {
27 27
28 using sessions::SyncSession; 28 using sessions::SyncSession;
29 using sessions::SyncSessionSnapshot; 29 using sessions::SyncSessionSnapshot;
30 using sessions::SyncSourceInfo; 30 using sessions::SyncSourceInfo;
31 using sync_pb::GetUpdatesCallerInfo; 31 using sync_pb::GetUpdatesCallerInfo;
32 32
33 namespace { 33 namespace {
34 34
35 // For integration tests only. Override initial backoff value.
36 // TODO(tim): Remove this egregiousness, use command line flag and plumb
37 // through. Done this way to reduce diffs in hotfix.
38 static bool g_force_short_retry = false;
39
40 bool ShouldRequestEarlyExit(const SyncProtocolError& error) { 35 bool ShouldRequestEarlyExit(const SyncProtocolError& error) {
41 switch (error.error_type) { 36 switch (error.error_type) {
42 case SYNC_SUCCESS: 37 case SYNC_SUCCESS:
43 case MIGRATION_DONE: 38 case MIGRATION_DONE:
44 case THROTTLED: 39 case THROTTLED:
45 case TRANSIENT_ERROR: 40 case TRANSIENT_ERROR:
46 return false; 41 return false;
47 case NOT_MY_BIRTHDAY: 42 case NOT_MY_BIRTHDAY:
48 case CLEAR_PENDING: 43 case CLEAR_PENDING:
49 // If we send terminate sync early then |sync_cycle_ended| notification 44 // If we send terminate sync early then |sync_cycle_ended| notification
(...skipping 28 matching lines...) Expand all
78 const ModelSafeRoutingInfo& routing_info, 73 const ModelSafeRoutingInfo& routing_info,
79 const base::Closure& ready_task) 74 const base::Closure& ready_task)
80 : source(source), 75 : source(source),
81 types_to_download(types_to_download), 76 types_to_download(types_to_download),
82 routing_info(routing_info), 77 routing_info(routing_info),
83 ready_task(ready_task) { 78 ready_task(ready_task) {
84 DCHECK(!ready_task.is_null()); 79 DCHECK(!ready_task.is_null());
85 } 80 }
86 ConfigurationParams::~ConfigurationParams() {} 81 ConfigurationParams::~ConfigurationParams() {}
87 82
88 SyncSchedulerImpl::DelayProvider::DelayProvider() {}
89 SyncSchedulerImpl::DelayProvider::~DelayProvider() {}
90
91 SyncSchedulerImpl::WaitInterval::WaitInterval() 83 SyncSchedulerImpl::WaitInterval::WaitInterval()
92 : mode(UNKNOWN), 84 : mode(UNKNOWN),
93 had_nudge(false) { 85 had_nudge(false) {
94 } 86 }
95 87
96 SyncSchedulerImpl::WaitInterval::~WaitInterval() {} 88 SyncSchedulerImpl::WaitInterval::~WaitInterval() {}
97 89
98 #define ENUM_CASE(x) case x: return #x; break; 90 #define ENUM_CASE(x) case x: return #x; break;
99 91
100 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) { 92 const char* SyncSchedulerImpl::WaitInterval::GetModeString(Mode mode) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 switch (purpose) { 125 switch (purpose) {
134 ENUM_CASE(UNKNOWN); 126 ENUM_CASE(UNKNOWN);
135 ENUM_CASE(POLL); 127 ENUM_CASE(POLL);
136 ENUM_CASE(NUDGE); 128 ENUM_CASE(NUDGE);
137 ENUM_CASE(CONFIGURATION); 129 ENUM_CASE(CONFIGURATION);
138 } 130 }
139 NOTREACHED(); 131 NOTREACHED();
140 return ""; 132 return "";
141 } 133 }
142 134
143 TimeDelta SyncSchedulerImpl::DelayProvider::GetDelay(
144 const base::TimeDelta& last_delay) {
145 return SyncSchedulerImpl::GetRecommendedDelay(last_delay);
146 }
147
148 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource( 135 GetUpdatesCallerInfo::GetUpdatesSource GetUpdatesFromNudgeSource(
149 NudgeSource source) { 136 NudgeSource source) {
150 switch (source) { 137 switch (source) {
151 case NUDGE_SOURCE_NOTIFICATION: 138 case NUDGE_SOURCE_NOTIFICATION:
152 return GetUpdatesCallerInfo::NOTIFICATION; 139 return GetUpdatesCallerInfo::NOTIFICATION;
153 case NUDGE_SOURCE_LOCAL: 140 case NUDGE_SOURCE_LOCAL:
154 return GetUpdatesCallerInfo::LOCAL; 141 return GetUpdatesCallerInfo::LOCAL;
155 case NUDGE_SOURCE_CONTINUATION: 142 case NUDGE_SOURCE_CONTINUATION:
156 return GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; 143 return GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION;
157 case NUDGE_SOURCE_LOCAL_REFRESH: 144 case NUDGE_SOURCE_LOCAL_REFRESH:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 case GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE: 177 case GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE:
191 return true; 178 return true;
192 default: 179 default:
193 return false; 180 return false;
194 } 181 }
195 } 182 }
196 183
197 } // namespace 184 } // namespace
198 185
199 SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name, 186 SyncSchedulerImpl::SyncSchedulerImpl(const std::string& name,
187 BackoffDelayProvider* delay_provider,
200 sessions::SyncSessionContext* context, 188 sessions::SyncSessionContext* context,
201 Syncer* syncer) 189 Syncer* syncer)
202 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 190 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
203 weak_ptr_factory_for_weak_handle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 191 weak_ptr_factory_for_weak_handle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
204 weak_handle_this_(MakeWeakHandle( 192 weak_handle_this_(MakeWeakHandle(
205 weak_ptr_factory_for_weak_handle_.GetWeakPtr())), 193 weak_ptr_factory_for_weak_handle_.GetWeakPtr())),
206 name_(name), 194 name_(name),
207 sync_loop_(MessageLoop::current()), 195 sync_loop_(MessageLoop::current()),
208 started_(false), 196 started_(false),
209 syncer_short_poll_interval_seconds_( 197 syncer_short_poll_interval_seconds_(
210 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), 198 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)),
211 syncer_long_poll_interval_seconds_( 199 syncer_long_poll_interval_seconds_(
212 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), 200 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)),
213 sessions_commit_delay_( 201 sessions_commit_delay_(
214 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), 202 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)),
215 mode_(NORMAL_MODE), 203 mode_(NORMAL_MODE),
216 // Start with assuming everything is fine with the connection. 204 // Start with assuming everything is fine with the connection.
217 // At the end of the sync cycle we would have the correct status. 205 // At the end of the sync cycle we would have the correct status.
218 connection_code_(HttpResponse::SERVER_CONNECTION_OK), 206 connection_code_(HttpResponse::SERVER_CONNECTION_OK),
219 delay_provider_(new DelayProvider()), 207 delay_provider_(delay_provider),
220 syncer_(syncer), 208 syncer_(syncer),
221 session_context_(context) { 209 session_context_(context) {
222 DCHECK(sync_loop_); 210 DCHECK(sync_loop_);
223 } 211 }
224 212
225 SyncSchedulerImpl::~SyncSchedulerImpl() { 213 SyncSchedulerImpl::~SyncSchedulerImpl() {
226 DCHECK_EQ(MessageLoop::current(), sync_loop_); 214 DCHECK_EQ(MessageLoop::current(), sync_loop_);
227 StopImpl(base::Closure()); 215 StopImpl(base::Closure());
228 } 216 }
229 217
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 &SyncSchedulerImpl::PollTimerCallback); 884 &SyncSchedulerImpl::PollTimerCallback);
897 } 885 }
898 886
899 void SyncSchedulerImpl::RestartWaiting() { 887 void SyncSchedulerImpl::RestartWaiting() {
900 CHECK(wait_interval_.get()); 888 CHECK(wait_interval_.get());
901 wait_interval_->timer.Stop(); 889 wait_interval_->timer.Stop();
902 wait_interval_->timer.Start(FROM_HERE, wait_interval_->length, 890 wait_interval_->timer.Start(FROM_HERE, wait_interval_->length,
903 this, &SyncSchedulerImpl::DoCanaryJob); 891 this, &SyncSchedulerImpl::DoCanaryJob);
904 } 892 }
905 893
906 namespace {
907 // TODO(tim): Move this function to syncer_error.h.
908 // Return true if the command in question was attempted and did not complete
909 // successfully.
910 bool IsError(SyncerError error) {
911 return error != UNSET && error != SYNCER_OK;
912 }
913 } // namespace
914
915 // static
916 void SyncSchedulerImpl::ForceShortInitialBackoffRetry() {
917 g_force_short_retry = true;
918 }
919
920 TimeDelta SyncSchedulerImpl::GetInitialBackoffDelay(
921 const sessions::ModelNeutralState& state) const {
922 // TODO(tim): Remove this, provide integration-test-only mechanism
923 // for override.
924 if (g_force_short_retry) {
925 return TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds);
926 }
927
928 if (IsError(state.last_get_key_result))
929 return TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
930 // Note: If we received a MIGRATION_DONE on download updates, then commit
931 // should not have taken place. Moreover, if we receive a MIGRATION_DONE
932 // on commit, it means that download updates succeeded. Therefore, we only
933 // need to check if either code is equal to SERVER_RETURN_MIGRATION_DONE,
934 // and not if there were any more serious errors requiring the long retry.
935 if (state.last_download_updates_result == SERVER_RETURN_MIGRATION_DONE ||
936 state.commit_result == SERVER_RETURN_MIGRATION_DONE) {
937 return TimeDelta::FromSeconds(kInitialBackoffShortRetrySeconds);
938 }
939
940 return TimeDelta::FromSeconds(kInitialBackoffRetrySeconds);
941 }
942
943 void SyncSchedulerImpl::HandleContinuationError( 894 void SyncSchedulerImpl::HandleContinuationError(
944 const SyncSessionJob& old_job) { 895 const SyncSessionJob& old_job) {
945 DCHECK_EQ(MessageLoop::current(), sync_loop_); 896 DCHECK_EQ(MessageLoop::current(), sync_loop_);
946 if (DCHECK_IS_ON()) { 897 if (DCHECK_IS_ON()) {
947 if (IsBackingOff()) { 898 if (IsBackingOff()) {
948 DCHECK(wait_interval_->timer.IsRunning() || old_job.is_canary_job); 899 DCHECK(wait_interval_->timer.IsRunning() || old_job.is_canary_job);
949 } 900 }
950 } 901 }
951 902
952 TimeDelta length = delay_provider_->GetDelay( 903 TimeDelta length = delay_provider_->GetDelay(
953 IsBackingOff() ? wait_interval_->length : 904 IsBackingOff() ? wait_interval_->length :
954 GetInitialBackoffDelay( 905 delay_provider_->GetInitialDelay(
955 old_job.session->status_controller().model_neutral_state())); 906 old_job.session->status_controller().model_neutral_state()));
956 907
957 SDVLOG(2) << "In handle continuation error with " 908 SDVLOG(2) << "In handle continuation error with "
958 << SyncSessionJob::GetPurposeString(old_job.purpose) 909 << SyncSessionJob::GetPurposeString(old_job.purpose)
959 << " job. The time delta(ms) is " 910 << " job. The time delta(ms) is "
960 << length.InMilliseconds(); 911 << length.InMilliseconds();
961 912
962 // This will reset the had_nudge variable as well. 913 // This will reset the had_nudge variable as well.
963 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF, 914 wait_interval_.reset(new WaitInterval(WaitInterval::EXPONENTIAL_BACKOFF,
964 length)); 915 length));
(...skipping 12 matching lines...) Expand all
977 // We are not in configuration mode. So wait_interval's pending job 928 // We are not in configuration mode. So wait_interval's pending job
978 // should be null. 929 // should be null.
979 DCHECK(wait_interval_->pending_configure_job.get() == NULL); 930 DCHECK(wait_interval_->pending_configure_job.get() == NULL);
980 931
981 // TODO(lipalani) - handle clear user data. 932 // TODO(lipalani) - handle clear user data.
982 InitOrCoalescePendingJob(old_job); 933 InitOrCoalescePendingJob(old_job);
983 } 934 }
984 RestartWaiting(); 935 RestartWaiting();
985 } 936 }
986 937
987 // static
988 TimeDelta SyncSchedulerImpl::GetRecommendedDelay(const TimeDelta& last_delay) {
989 if (last_delay.InSeconds() >= kMaxBackoffSeconds)
990 return TimeDelta::FromSeconds(kMaxBackoffSeconds);
991
992 // This calculates approx. base_delay_seconds * 2 +/- base_delay_seconds / 2
993 int64 backoff_s =
994 std::max(static_cast<int64>(1),
995 last_delay.InSeconds() * kBackoffRandomizationFactor);
996
997 // Flip a coin to randomize backoff interval by +/- 50%.
998 int rand_sign = base::RandInt(0, 1) * 2 - 1;
999
1000 // Truncation is adequate for rounding here.
1001 backoff_s = backoff_s +
1002 (rand_sign * (last_delay.InSeconds() / kBackoffRandomizationFactor));
1003
1004 // Cap the backoff interval.
1005 backoff_s = std::max(static_cast<int64>(1),
1006 std::min(backoff_s, kMaxBackoffSeconds));
1007
1008 return TimeDelta::FromSeconds(backoff_s);
1009 }
1010
1011 void SyncSchedulerImpl::RequestStop(const base::Closure& callback) { 938 void SyncSchedulerImpl::RequestStop(const base::Closure& callback) {
1012 syncer_->RequestEarlyExit(); // Safe to call from any thread. 939 syncer_->RequestEarlyExit(); // Safe to call from any thread.
1013 DCHECK(weak_handle_this_.IsInitialized()); 940 DCHECK(weak_handle_this_.IsInitialized());
1014 SDVLOG(3) << "Posting StopImpl"; 941 SDVLOG(3) << "Posting StopImpl";
1015 weak_handle_this_.Call(FROM_HERE, 942 weak_handle_this_.Call(FROM_HERE,
1016 &SyncSchedulerImpl::StopImpl, 943 &SyncSchedulerImpl::StopImpl,
1017 callback); 944 callback);
1018 } 945 }
1019 946
1020 void SyncSchedulerImpl::StopImpl(const base::Closure& callback) { 947 void SyncSchedulerImpl::StopImpl(const base::Closure& callback) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 1119
1193 #undef SDVLOG_LOC 1120 #undef SDVLOG_LOC
1194 1121
1195 #undef SDVLOG 1122 #undef SDVLOG
1196 1123
1197 #undef SLOG 1124 #undef SLOG
1198 1125
1199 #undef ENUM_CASE 1126 #undef ENUM_CASE
1200 1127
1201 } // namespace syncer 1128 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698