| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 DCHECK(job.purpose == SyncSessionJob::NUDGE || job.purpose == | 362 DCHECK(job.purpose == SyncSessionJob::NUDGE || job.purpose == |
| 363 SyncSessionJob::CONFIGURATION); | 363 SyncSessionJob::CONFIGURATION); |
| 364 | 364 |
| 365 SaveJob(job); | 365 SaveJob(job); |
| 366 return false; | 366 return false; |
| 367 } | 367 } |
| 368 | 368 |
| 369 void SyncScheduler::SaveJob(const SyncSessionJob& job) { | 369 void SyncScheduler::SaveJob(const SyncSessionJob& job) { |
| 370 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 370 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 371 DCHECK_NE(job.purpose, SyncSessionJob::CLEAR_USER_DATA); | 371 DCHECK_NE(job.purpose, SyncSessionJob::CLEAR_USER_DATA); |
| 372 // TODO(sync): Should we also check that job.purpose != | 372 DCHECK_NE(job.purpose, SyncSessionJob::CLEANUP_DISABLED_TYPES); |
| 373 // CLEANUP_DISABLED_TYPES? (See http://crbug.com/90868.) | |
| 374 if (job.purpose == SyncSessionJob::NUDGE) { | 373 if (job.purpose == SyncSessionJob::NUDGE) { |
| 375 SVLOG(2) << "Saving a nudge job"; | 374 SVLOG(2) << "Saving a nudge job"; |
| 376 InitOrCoalescePendingJob(job); | 375 InitOrCoalescePendingJob(job); |
| 377 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ | 376 } else if (job.purpose == SyncSessionJob::CONFIGURATION){ |
| 378 SVLOG(2) << "Saving a configuration job"; | 377 SVLOG(2) << "Saving a configuration job"; |
| 379 DCHECK(wait_interval_.get()); | 378 DCHECK(wait_interval_.get()); |
| 380 DCHECK(mode_ == CONFIGURATION_MODE); | 379 DCHECK(mode_ == CONFIGURATION_MODE); |
| 381 | 380 |
| 382 SyncSession* old = job.session.get(); | 381 SyncSession* old = job.session.get(); |
| 383 SyncSession* s(new SyncSession(session_context_.get(), this, | 382 SyncSession* s(new SyncSession(session_context_.get(), this, |
| 384 old->source(), old->routing_info(), old->workers())); | 383 old->source(), old->routing_info(), old->workers())); |
| 385 SyncSessionJob new_job(job.purpose, TimeTicks::Now(), | 384 SyncSessionJob new_job(job.purpose, TimeTicks::Now(), |
| 386 make_linked_ptr(s), false, job.from_here); | 385 make_linked_ptr(s), false, job.from_here); |
| 387 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); | 386 wait_interval_->pending_configure_job.reset(new SyncSessionJob(new_job)); |
| 388 } // drop the rest. | 387 } else { |
| 389 // TODO(sync): Is it okay to drop the rest? It's weird that | 388 // Save job should only be called with nudges or configs which need to be |
| 390 // SaveJob() only does what it says sometimes. (See | 389 // saved. Others jobs are one off jobs which dont need to be retried so |
| 391 // http://crbug.com/90868.) | 390 // dont need to be saved. |
| 391 NOTREACHED(); |
| 392 } |
| 392 } | 393 } |
| 393 | 394 |
| 394 // Functor for std::find_if to search by ModelSafeGroup. | 395 // Functor for std::find_if to search by ModelSafeGroup. |
| 395 struct ModelSafeWorkerGroupIs { | 396 struct ModelSafeWorkerGroupIs { |
| 396 explicit ModelSafeWorkerGroupIs(ModelSafeGroup group) : group(group) {} | 397 explicit ModelSafeWorkerGroupIs(ModelSafeGroup group) : group(group) {} |
| 397 bool operator()(ModelSafeWorker* w) { | 398 bool operator()(ModelSafeWorker* w) { |
| 398 return group == w->GetModelSafeGroup(); | 399 return group == w->GetModelSafeGroup(); |
| 399 } | 400 } |
| 400 ModelSafeGroup group; | 401 ModelSafeGroup group; |
| 401 }; | 402 }; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 ModelTypePayloadMap::const_iterator iter; | 758 ModelTypePayloadMap::const_iterator iter; |
| 758 for (iter = job.session->source().types.begin(); | 759 for (iter = job.session->source().types.begin(); |
| 759 iter != job.session->source().types.end(); | 760 iter != job.session->source().types.end(); |
| 760 ++iter) { | 761 ++iter) { |
| 761 syncable::PostTimeToTypeHistogram(iter->first, | 762 syncable::PostTimeToTypeHistogram(iter->first, |
| 762 now - last_sync_session_end_time_); | 763 now - last_sync_session_end_time_); |
| 763 } | 764 } |
| 764 } | 765 } |
| 765 last_sync_session_end_time_ = now; | 766 last_sync_session_end_time_ = now; |
| 766 UpdateCarryoverSessionState(job); | 767 UpdateCarryoverSessionState(job); |
| 767 if (IsSyncingCurrentlySilenced()) { | |
| 768 SVLOG(2) << "We are currently throttled; not scheduling the next sync."; | |
| 769 // TODO(sync): Investigate whether we need to check job.purpose | |
| 770 // here; see DCHECKs in SaveJob(). (See http://crbug.com/90868.) | |
| 771 SaveJob(job); | |
| 772 return; // Nothing to do. | |
| 773 } | |
| 774 | 768 |
| 775 SVLOG(2) << "Updating the next polling time after SyncMain"; | 769 SVLOG(2) << "Updating the next polling time after SyncMain"; |
| 776 ScheduleNextSync(job); | 770 ScheduleNextSync(job); |
| 777 } | 771 } |
| 778 | 772 |
| 779 void SyncScheduler::ScheduleNextSync(const SyncSessionJob& old_job) { | 773 void SyncScheduler::ScheduleNextSync(const SyncSessionJob& old_job) { |
| 780 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 774 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 781 DCHECK(!old_job.session->HasMoreToSync()); | 775 DCHECK(!old_job.session->HasMoreToSync()); |
| 776 |
| 777 // First check for one off jobs like CLEANUP_DISABLED_TYPES. Success or |
| 778 // failure of that job should not affect our states like exponential backoff, |
| 779 // pending_job etc. Also those "one off" jobs dont need to be retried. |
| 780 // TODO(lipalani) : handle the case of CLEAR_USER_DATA here. |
| 781 if (old_job.purpose == SyncSessionJob::CLEANUP_DISABLED_TYPES) |
| 782 return; |
| 783 |
| 784 // Now check for throttled. |
| 785 if (IsSyncingCurrentlySilenced()) { |
| 786 SVLOG(2) << "We are currently throttled; not scheduling the next sync."; |
| 787 SaveJob(old_job); |
| 788 return; // Nothing more to schedule. |
| 789 } // Now continue to check if we need to do exponential backoff. |
| 790 |
| 782 // Note: |num_server_changes_remaining| > 0 here implies that we received a | 791 // Note: |num_server_changes_remaining| > 0 here implies that we received a |
| 783 // broken response while trying to download all updates, because the Syncer | 792 // broken response while trying to download all updates, because the Syncer |
| 784 // will loop until this value is exhausted. Also, if unsynced_handles exist | 793 // will loop until this value is exhausted. Also, if unsynced_handles exist |
| 785 // but HasMoreToSync is false, this implies that the Syncer determined no | 794 // but HasMoreToSync is false, this implies that the Syncer determined no |
| 786 // forward progress was possible at this time (an error, such as an HTTP | 795 // forward progress was possible at this time (an error, such as an HTTP |
| 787 // 500, is likely to have occurred during commit). | 796 // 500, is likely to have occurred during commit). |
| 788 int num_server_changes_remaining = | 797 int num_server_changes_remaining = |
| 789 old_job.session->status_controller()->num_server_changes_remaining(); | 798 old_job.session->status_controller()->num_server_changes_remaining(); |
| 790 size_t num_unsynced_handles = | 799 size_t num_unsynced_handles = |
| 791 old_job.session->status_controller()->unsynced_handles().size(); | 800 old_job.session->status_controller()->unsynced_handles().size(); |
| 792 const bool work_to_do = | 801 const bool work_to_do = |
| 793 num_server_changes_remaining > 0 || num_unsynced_handles > 0; | 802 num_server_changes_remaining > 0 || num_unsynced_handles > 0; |
| 794 SVLOG(2) << "num server changes remaining: " << num_server_changes_remaining | 803 SVLOG(2) << "num server changes remaining: " << num_server_changes_remaining |
| 795 << ", num unsynced handles: " << num_unsynced_handles | 804 << ", num unsynced handles: " << num_unsynced_handles |
| 796 << ", syncer has work to do: " << work_to_do; | 805 << ", syncer has work to do: " << work_to_do; |
| 797 | 806 |
| 798 AdjustPolling(&old_job); | 807 AdjustPolling(&old_job); |
| 808 // Note one off jobs like |
| 809 // SyncSessionJob::{CLEAR_USER_DATA,CLEANUP_DISABLED_TYPES}) would |
| 810 // have been handled by now. We should either be in a nudge or config. |
| 811 DCHECK(old_job.purpose == SyncSessionJob::NUDGE || |
| 812 old_job.purpose == SyncSessionJob::CONFIGURATION); |
| 799 | 813 |
| 800 // TODO(tim): Old impl had special code if notifications disabled. Needed? | 814 // TODO(tim): Old impl had special code if notifications disabled. Needed? |
| 801 if (!work_to_do) { | 815 if (!work_to_do) { |
| 802 // Success implies backoff relief. Note that if this was a | 816 // Success implies backoff relief. |
| 803 // "one-off" job (i.e. purpose == | |
| 804 // SyncSessionJob::{CLEAR_USER_DATA,CLEANUP_DISABLED_TYPES}), if | |
| 805 // there was work_to_do before it ran this wont have changed, as | |
| 806 // jobs like this don't run a full sync cycle. So we don't need | |
| 807 // special code here. | |
| 808 wait_interval_.reset(); | 817 wait_interval_.reset(); |
| 809 SVLOG(2) << "Job succeeded so not scheduling more jobs"; | 818 SVLOG(2) << "Job succeeded so not scheduling more jobs"; |
| 810 return; | 819 return; |
| 811 } | 820 } |
| 812 | 821 |
| 813 // We are in backoff mode and our time did not run out. That means we had | 822 // We are in backoff mode and our time did not run out. That means we had |
| 814 // a local change, notification from server or a network connection change | 823 // a local change, notification from server or a network connection change |
| 815 // notification. In any case set had_nudge = true so we dont retry next | 824 // notification. In any case set had_nudge = true so we dont retry next |
| 816 // nudge. Note: we will keep retrying network connection changes though as | 825 // nudge. Note: we will keep retrying network connection changes though as |
| 817 // they are treated as canary jobs. Also we check the mode here because | 826 // they are treated as canary jobs. Also we check the mode here because |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 | 1099 |
| 1091 #undef SLOG | 1100 #undef SLOG |
| 1092 | 1101 |
| 1093 #undef VLOG_LOC | 1102 #undef VLOG_LOC |
| 1094 | 1103 |
| 1095 #undef VLOG_LOC_STREAM | 1104 #undef VLOG_LOC_STREAM |
| 1096 | 1105 |
| 1097 #undef ENUM_CASE | 1106 #undef ENUM_CASE |
| 1098 | 1107 |
| 1099 } // browser_sync | 1108 } // browser_sync |
| OLD | NEW |