Chromium Code Reviews| 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 "chrome/browser/sync/engine/sync_scheduler.h" | 5 #include "chrome/browser/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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 started_(false), | 187 started_(false), |
| 188 syncer_short_poll_interval_seconds_( | 188 syncer_short_poll_interval_seconds_( |
| 189 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), | 189 TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds)), |
| 190 syncer_long_poll_interval_seconds_( | 190 syncer_long_poll_interval_seconds_( |
| 191 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), | 191 TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds)), |
| 192 sessions_commit_delay_( | 192 sessions_commit_delay_( |
| 193 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), | 193 TimeDelta::FromSeconds(kDefaultSessionsCommitDelaySeconds)), |
| 194 mode_(NORMAL_MODE), | 194 mode_(NORMAL_MODE), |
| 195 // Start with assuming everything is fine with the connection. | 195 // Start with assuming everything is fine with the connection. |
| 196 // At the end of the sync cycle we would have the correct status. | 196 // At the end of the sync cycle we would have the correct status. |
| 197 server_connection_ok_(true), | |
| 198 connection_code_(HttpResponse::SERVER_CONNECTION_OK), | 197 connection_code_(HttpResponse::SERVER_CONNECTION_OK), |
| 199 delay_provider_(new DelayProvider()), | 198 delay_provider_(new DelayProvider()), |
| 200 syncer_(syncer), | 199 syncer_(syncer), |
| 201 session_context_(context) { | 200 session_context_(context) { |
| 202 DCHECK(sync_loop_); | 201 DCHECK(sync_loop_); |
| 203 } | 202 } |
| 204 | 203 |
| 205 SyncScheduler::~SyncScheduler() { | 204 SyncScheduler::~SyncScheduler() { |
| 206 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 205 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 207 StopImpl(base::Closure()); | 206 StopImpl(base::Closure()); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 223 | 222 |
| 224 void SyncScheduler::OnConnectionStatusChange() { | 223 void SyncScheduler::OnConnectionStatusChange() { |
| 225 if (HttpResponse::CONNECTION_UNAVAILABLE == connection_code_) { | 224 if (HttpResponse::CONNECTION_UNAVAILABLE == connection_code_) { |
| 226 // Optimistically assume that the connection is fixed and try | 225 // Optimistically assume that the connection is fixed and try |
| 227 // connecting. | 226 // connecting. |
| 228 OnServerConnectionErrorFixed(); | 227 OnServerConnectionErrorFixed(); |
| 229 } | 228 } |
| 230 } | 229 } |
| 231 | 230 |
| 232 void SyncScheduler::OnServerConnectionErrorFixed() { | 231 void SyncScheduler::OnServerConnectionErrorFixed() { |
| 233 DCHECK(!server_connection_ok_); | |
| 234 connection_code_ = HttpResponse::SERVER_CONNECTION_OK; | 232 connection_code_ = HttpResponse::SERVER_CONNECTION_OK; |
| 235 server_connection_ok_ = true; | |
| 236 PostTask(FROM_HERE, "DoCanaryJob", | 233 PostTask(FROM_HERE, "DoCanaryJob", |
| 237 base::Bind(&SyncScheduler::DoCanaryJob, | 234 base::Bind(&SyncScheduler::DoCanaryJob, |
| 238 weak_ptr_factory_.GetWeakPtr())); | 235 weak_ptr_factory_.GetWeakPtr())); |
| 239 | 236 |
| 240 } | 237 } |
| 241 | 238 |
| 242 void SyncScheduler::UpdateServerConnectionManagerStatus( | 239 void SyncScheduler::UpdateServerConnectionManagerStatus( |
| 243 HttpResponse::ServerConnectionCode code) { | 240 HttpResponse::ServerConnectionCode code) { |
| 244 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 241 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 245 SDVLOG(2) << "New server connection code: " | 242 SDVLOG(2) << "New server connection code: " |
| 246 << HttpResponse::GetServerConnectionCodeString(code); | 243 << HttpResponse::GetServerConnectionCodeString(code); |
| 247 bool old_server_connection_ok = server_connection_ok_; | |
| 248 | 244 |
| 249 connection_code_ = code; | 245 connection_code_ = code; |
| 250 | 246 |
| 251 // Note, be careful when adding cases here because if the SyncScheduler | 247 // Note, be careful when adding cases here because if the SyncScheduler |
| 252 // thinks there is no valid connection as determined by this method, it | 248 // thinks there is no valid connection as determined by this method, it |
| 253 // will drop out of *all* forward progress sync loops (it won't poll and it | 249 // will drop out of *all* forward progress sync loops (it won't poll and it |
| 254 // will queue up Talk notifications but not actually call SyncShare) until | 250 // will queue up Talk notifications but not actually call SyncShare) until |
| 255 // some external action causes a ServerConnectionManager to broadcast that | 251 // some external action causes a ServerConnectionManager to broadcast that |
| 256 // a valid connection has been re-established | 252 // a valid connection has been re-established |
| 257 if (HttpResponse::CONNECTION_UNAVAILABLE == code || | 253 if (HttpResponse::CONNECTION_UNAVAILABLE == code || |
| 258 HttpResponse::SYNC_AUTH_ERROR == code) { | 254 HttpResponse::SYNC_AUTH_ERROR == code) { |
| 259 server_connection_ok_ = false; | |
| 260 SDVLOG(2) << "Sync auth error or unavailable connection: " | 255 SDVLOG(2) << "Sync auth error or unavailable connection: " |
| 261 << "server connection is down"; | 256 << "server connection is down"; |
| 262 } else if (HttpResponse::SERVER_CONNECTION_OK == code) { | 257 } else if (HttpResponse::SERVER_CONNECTION_OK == code) { |
| 263 server_connection_ok_ = true; | |
| 264 SDVLOG(2) << "Sync server connection is ok: " | 258 SDVLOG(2) << "Sync server connection is ok: " |
| 265 << "server connection is up, doing canary job"; | 259 << "server connection is up, doing canary job"; |
| 266 } | 260 } |
| 267 | |
| 268 if (old_server_connection_ok != server_connection_ok_) { | |
| 269 const char* transition = | |
| 270 server_connection_ok_ ? "down -> up" : "up -> down"; | |
| 271 SDVLOG(2) << "Server connection changed: " << transition; | |
|
lipalani1
2012/02/11 00:12:10
There is some value to this log statement. You can
rlarocque
2012/02/11 01:31:36
This log statement exists specifically to tell us
| |
| 272 } | |
| 273 } | 261 } |
| 274 | 262 |
| 275 void SyncScheduler::Start(Mode mode, const base::Closure& callback) { | 263 void SyncScheduler::Start(Mode mode, const base::Closure& callback) { |
| 276 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 264 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 277 std::string thread_name = MessageLoop::current()->thread_name(); | 265 std::string thread_name = MessageLoop::current()->thread_name(); |
| 278 if (thread_name.empty()) | 266 if (thread_name.empty()) |
| 279 thread_name = "<Main thread>"; | 267 thread_name = "<Main thread>"; |
| 280 SDVLOG(2) << "Start called from thread " | 268 SDVLOG(2) << "Start called from thread " |
| 281 << thread_name << " with mode " << GetModeString(mode); | 269 << thread_name << " with mode " << GetModeString(mode); |
| 282 if (!started_) { | 270 if (!started_) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 // We are in normal mode. | 366 // We are in normal mode. |
| 379 DCHECK_EQ(mode_, NORMAL_MODE); | 367 DCHECK_EQ(mode_, NORMAL_MODE); |
| 380 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); | 368 DCHECK_NE(job.purpose, SyncSessionJob::CONFIGURATION); |
| 381 | 369 |
| 382 // Freshness condition | 370 // Freshness condition |
| 383 if (job.scheduled_start < last_sync_session_end_time_) { | 371 if (job.scheduled_start < last_sync_session_end_time_) { |
| 384 SDVLOG(2) << "Dropping job because of freshness"; | 372 SDVLOG(2) << "Dropping job because of freshness"; |
| 385 return DROP; | 373 return DROP; |
| 386 } | 374 } |
| 387 | 375 |
| 388 if (server_connection_ok_) | 376 if (!session_context_->connection_manager()->HasInvalidAuthToken()) |
|
rlarocque
2012/02/10 23:16:06
You might be thinking that this condition is not t
lipalani1
2012/02/11 00:12:10
Yep it was designed to capture cases where this va
| |
| 389 return CONTINUE; | 377 return CONTINUE; |
| 390 | 378 |
| 391 SDVLOG(2) << "Bad server connection. Using that to decide on job."; | 379 SDVLOG(2) << "No valid auth token. Using that to decide on job."; |
| 392 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; | 380 return job.purpose == SyncSessionJob::NUDGE ? SAVE : DROP; |
| 393 } | 381 } |
| 394 | 382 |
| 395 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { | 383 void SyncScheduler::InitOrCoalescePendingJob(const SyncSessionJob& job) { |
| 396 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 384 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 397 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); | 385 DCHECK(job.purpose != SyncSessionJob::CONFIGURATION); |
| 398 if (pending_nudge_.get() == NULL) { | 386 if (pending_nudge_.get() == NULL) { |
| 399 SDVLOG(2) << "Creating a pending nudge job"; | 387 SDVLOG(2) << "Creating a pending nudge job"; |
| 400 SyncSession* s = job.session.get(); | 388 SyncSession* s = job.session.get(); |
| 401 scoped_ptr<SyncSession> session(new SyncSession(s->context(), | 389 scoped_ptr<SyncSession> session(new SyncSession(s->context(), |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 ModelTypePayloadMap::const_iterator iter; | 833 ModelTypePayloadMap::const_iterator iter; |
| 846 for (iter = job.session->source().types.begin(); | 834 for (iter = job.session->source().types.begin(); |
| 847 iter != job.session->source().types.end(); | 835 iter != job.session->source().types.end(); |
| 848 ++iter) { | 836 ++iter) { |
| 849 syncable::PostTimeToTypeHistogram(iter->first, | 837 syncable::PostTimeToTypeHistogram(iter->first, |
| 850 now - last_sync_session_end_time_); | 838 now - last_sync_session_end_time_); |
| 851 } | 839 } |
| 852 } | 840 } |
| 853 last_sync_session_end_time_ = now; | 841 last_sync_session_end_time_ = now; |
| 854 | 842 |
| 855 // Now update the status of the connection from SCM. We need this | 843 // Now update the status of the connection from SCM. We need this to decide |
| 856 // to decide whether we need to save/run future jobs. The notifications | 844 // whether we need to save/run future jobs. The notifications from SCM are not |
| 857 // from SCM are not reliable. | 845 // reliable. |
| 846 // | |
| 858 // TODO(rlarocque): crbug.com/110954 | 847 // TODO(rlarocque): crbug.com/110954 |
| 859 // We should get rid of the notifications and | 848 // We should get rid of the notifications and it is probably not needed to |
| 860 // it is probably not needed to maintain this status variable | 849 // maintain this status variable in 2 places. We should query it directly from |
| 861 // in 2 places. We should query it directly from SCM when needed. | 850 // SCM when needed. |
| 862 // But that would need little more refactoring(including a method to | |
| 863 // query if the auth token is invalid) from SCM side. | |
| 864 ServerConnectionManager* scm = session_context_->connection_manager(); | 851 ServerConnectionManager* scm = session_context_->connection_manager(); |
| 865 UpdateServerConnectionManagerStatus(scm->server_status()); | 852 UpdateServerConnectionManagerStatus(scm->server_status()); |
| 866 | 853 |
| 867 UpdateCarryoverSessionState(job); | 854 UpdateCarryoverSessionState(job); |
| 868 if (IsSyncingCurrentlySilenced()) { | 855 if (IsSyncingCurrentlySilenced()) { |
| 869 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; | 856 SDVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
| 870 // TODO(sync): Investigate whether we need to check job.purpose | 857 // TODO(sync): Investigate whether we need to check job.purpose |
| 871 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | 858 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) |
| 872 SaveJob(job); | 859 SaveJob(job); |
| 873 return; // Nothing to do. | 860 return; // Nothing to do. |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1200 | 1187 |
| 1201 #undef SDVLOG_LOC | 1188 #undef SDVLOG_LOC |
| 1202 | 1189 |
| 1203 #undef SDVLOG | 1190 #undef SDVLOG |
| 1204 | 1191 |
| 1205 #undef SLOG | 1192 #undef SLOG |
| 1206 | 1193 |
| 1207 #undef ENUM_CASE | 1194 #undef ENUM_CASE |
| 1208 | 1195 |
| 1209 } // browser_sync | 1196 } // browser_sync |
| OLD | NEW |