OLD | NEW |
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.h" | 5 #include "sync/engine/sync_scheduler.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" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 started_(false), | 188 started_(false), |
189 syncer_short_poll_interval_seconds_( | 189 syncer_short_poll_interval_seconds_( |
190 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), | 190 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), |
191 syncer_long_poll_interval_seconds_( | 191 syncer_long_poll_interval_seconds_( |
192 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), | 192 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), |
193 sessions_commit_delay_( | 193 sessions_commit_delay_( |
194 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), | 194 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), |
195 mode_(NORMAL_MODE), | 195 mode_(NORMAL_MODE), |
196 // Start with assuming everything is fine with the connection. | 196 // Start with assuming everything is fine with the connection. |
197 // At the end of the sync cycle we would have the correct status. | 197 // At the end of the sync cycle we would have the correct status. |
198 server_connection_ok_(true), | |
199 connection_code_(HttpResponse::SERVER_CONNECTION_OK), | 198 connection_code_(HttpResponse::SERVER_CONNECTION_OK), |
200 delay_provider_(new DelayProvider()), | 199 delay_provider_(new DelayProvider()), |
201 syncer_(syncer), | 200 syncer_(syncer), |
202 session_context_(context) { | 201 session_context_(context) { |
203 DCHECK(sync_loop_); | 202 DCHECK(sync_loop_); |
204 } | 203 } |
205 | 204 |
206 SyncScheduler::~SyncScheduler() { | 205 SyncScheduler::~SyncScheduler() { |
207 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 206 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
208 StopImpl(base::Closure()); | 207 StopImpl(base::Closure()); |
(...skipping 15 matching lines...) Expand all Loading... |
224 | 223 |
225 void SyncScheduler::OnConnectionStatusChange() { | 224 void SyncScheduler::OnConnectionStatusChange() { |
226 if (HttpResponse::CONNECTION_UNAVAILABLE == connection_code_) { | 225 if (HttpResponse::CONNECTION_UNAVAILABLE == connection_code_) { |
227 // Optimistically assume that the connection is fixed and try | 226 // Optimistically assume that the connection is fixed and try |
228 // connecting. | 227 // connecting. |
229 OnServerConnectionErrorFixed(); | 228 OnServerConnectionErrorFixed(); |
230 } | 229 } |
231 } | 230 } |
232 | 231 |
233 void SyncScheduler::OnServerConnectionErrorFixed() { | 232 void SyncScheduler::OnServerConnectionErrorFixed() { |
234 DCHECK(!server_connection_ok_); | |
235 connection_code_ = HttpResponse::SERVER_CONNECTION_OK; | 233 connection_code_ = HttpResponse::SERVER_CONNECTION_OK; |
236 server_connection_ok_ = true; | |
237 PostTask(FROM_HERE, "DoCanaryJob", | 234 PostTask(FROM_HERE, "DoCanaryJob", |
238 base::Bind(&SyncScheduler::DoCanaryJob, | 235 base::Bind(&SyncScheduler::DoCanaryJob, |
239 weak_ptr_factory_.GetWeakPtr())); | 236 weak_ptr_factory_.GetWeakPtr())); |
240 | 237 |
241 } | 238 } |
242 | 239 |
243 void SyncScheduler::UpdateServerConnectionManagerStatus( | 240 void SyncScheduler::UpdateServerConnectionManagerStatus( |
244 HttpResponse::ServerConnectionCode code) { | 241 HttpResponse::ServerConnectionCode code) { |
245 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 242 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
246 SDVLOG(2) << "New server connection code: " | 243 SDVLOG(2) << "New server connection code: " |
247 << HttpResponse::GetServerConnectionCodeString(code); | 244 << HttpResponse::GetServerConnectionCodeString(code); |
248 bool old_server_connection_ok = server_connection_ok_; | |
249 | 245 |
250 connection_code_ = code; | 246 connection_code_ = code; |
251 | |
252 // Note, be careful when adding cases here because if the SyncScheduler | |
253 // thinks there is no valid connection as determined by this method, it | |
254 // will drop out of *all* forward progress sync loops (it won't poll and it | |
255 // will queue up Talk notifications but not actually call SyncShare) until | |
256 // some external action causes a ServerConnectionManager to broadcast that | |
257 // a valid connection has been re-established | |
258 if (HttpResponse::CONNECTION_UNAVAILABLE == code || | |
259 HttpResponse::SYNC_AUTH_ERROR == code) { | |
260 server_connection_ok_ = false; | |
261 SDVLOG(2) << "Sync auth error or unavailable connection: " | |
262 << "server connection is down"; | |
263 } else if (HttpResponse::SERVER_CONNECTION_OK == code) { | |
264 server_connection_ok_ = true; | |
265 SDVLOG(2) << "Sync server connection is ok: " | |
266 << "server connection is up, doing canary job"; | |
267 } | |
268 | |
269 if (old_server_connection_ok != server_connection_ok_) { | |
270 const char* transition = | |
271 server_connection_ok_ ? "down -> up" : "up -> down"; | |
272 SDVLOG(2) << "Server connection changed: " << transition; | |
273 } | |
274 } | 247 } |
275 | 248 |
276 void SyncScheduler::Start(Mode mode, const base::Closure& callback) { | 249 void SyncScheduler::Start(Mode mode, const base::Closure& callback) { |
277 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 250 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
278 std::string thread_name = MessageLoop::current()->thread_name(); | 251 std::string thread_name = MessageLoop::current()->thread_name(); |
279 if (thread_name.empty()) | 252 if (thread_name.empty()) |
280 thread_name = "<Main thread>"; | 253 thread_name = "<Main thread>"; |
281 SDVLOG(2) << "Start called from thread " | 254 SDVLOG(2) << "Start called from thread " |
282 << thread_name << " with mode " << GetModeString(mode); | 255 << thread_name << " with mode " << GetModeString(mode); |
283 if (!started_) { | 256 if (!started_) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 // We are in normal mode. | 369 // We are in normal mode. |
397 DCHECK_EQ(mode_, NORMAL_MODE); | 370 DCHECK_EQ(mode_, NORMAL_MODE); |
398 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); | 371 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); |
399 | 372 |
400 // Freshness condition | 373 // Freshness condition |
401 if (job.scheduled_start < last_sync_session_end_time_) { | 374 if (job.scheduled_start < last_sync_session_end_time_) { |
402 SDVLOG(2) << "Dropping job because of freshness"; | 375 SDVLOG(2) << "Dropping job because of freshness"; |
403 return DROP; | 376 return DROP; |
404 } | 377 } |
405 | 378 |
406 if (server_connection_ok_) | 379 if (!session_context_->connection_manager()->HasInvalidAuthToken()) |
407 return CONTINUE; | 380 return CONTINUE; |
408 | 381 |
409 SDVLOG(2) << "Bad server connection. Using that to decide on job."; | 382 SDVLOG(2) << "No valid auth token. Using that to decide on job."; |
410 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; | 383 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; |
411 } | 384 } |
412 | 385 |
413 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { | 386 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { |
414 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 387 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
415 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); | 388 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); |
416 if (pending_nudge_.get() == NULL) { | 389 if (pending_nudge_.get() == NULL) { |
417 SDVLOG(2) << "Creating a pending nudge job"; | 390 SDVLOG(2) << "Creating a pending nudge job"; |
418 SyncSession* s = job.session.get(); | 391 SyncSession* s = job.session.get(); |
419 scoped_ptr<SyncSession> session(new SyncSession(s->context(), | 392 scoped_ptr<SyncSession> session(new SyncSession(s->context(), |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 ++iter) { | 839 ++iter) { |
867 #define PER_DATA_TYPE_MACRO(type_str) \ | 840 #define PER_DATA_TYPE_MACRO(type_str) \ |
868 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, \ | 841 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, \ |
869 now - last_sync_session_end_time_); | 842 now - last_sync_session_end_time_); |
870 SYNC_DATA_TYPE_HISTOGRAM(iter->first); | 843 SYNC_DATA_TYPE_HISTOGRAM(iter->first); |
871 #undef PER_DATA_TYPE_MACRO | 844 #undef PER_DATA_TYPE_MACRO |
872 } | 845 } |
873 } | 846 } |
874 last_sync_session_end_time_ = now; | 847 last_sync_session_end_time_ = now; |
875 | 848 |
876 // Now update the status of the connection from SCM. We need this | 849 // Now update the status of the connection from SCM. We need this to decide |
877 // to decide whether we need to save/run future jobs. The notifications | 850 // whether we need to save/run future jobs. The notifications from SCM are not |
878 // from SCM are not reliable. | 851 // reliable. |
| 852 // |
879 // TODO(rlarocque): crbug.com/110954 | 853 // TODO(rlarocque): crbug.com/110954 |
880 // We should get rid of the notifications and | 854 // We should get rid of the notifications and it is probably not needed to |
881 // it is probably not needed to maintain this status variable | 855 // maintain this status variable in 2 places. We should query it directly from |
882 // in 2 places. We should query it directly from SCM when needed. | 856 // SCM when needed. |
883 // But that would need little more refactoring(including a method to | |
884 // query if the auth token is invalid) from SCM side. | |
885 ServerConnectionManager* scm = session_context_->connection_manager(); | 857 ServerConnectionManager* scm = session_context_->connection_manager(); |
886 UpdateServerConnectionManagerStatus(scm->server_status()); | 858 UpdateServerConnectionManagerStatus(scm->server_status()); |
887 | 859 |
888 UpdateCarryoverSessionState(job); | 860 UpdateCarryoverSessionState(job); |
889 if (IsSyncingCurrentlySilenced()) { | 861 if (IsSyncingCurrentlySilenced()) { |
890 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; | 862 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
891 // TODO(sync): Investigate whether we need to check job.purpose | 863 // TODO(sync): Investigate whether we need to check job.purpose |
892 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | 864 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) |
893 SaveJob(job); | 865 SaveJob(job); |
894 return; // Nothing to do. | 866 return; // Nothing to do. |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 | 1196 |
1225 #undef SDVLOG_LOC | 1197 #undef SDVLOG_LOC |
1226 | 1198 |
1227 #undef SDVLOG | 1199 #undef SDVLOG |
1228 | 1200 |
1229 #undef SLOG | 1201 #undef SLOG |
1230 | 1202 |
1231 #undef ENUM_CASE | 1203 #undef ENUM_CASE |
1232 | 1204 |
1233 } // browser_sync | 1205 } // browser_sync |
OLD | NEW |