diff options
author | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-03 03:44:20 +0000 |
---|---|---|
committer | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-03 03:44:20 +0000 |
commit | de84cfd7c982067cb1e691d2e983ec95e08b9e1b (patch) | |
tree | 645dd94ad7ac7fa4dd3ef45b967b0ad23cf1eb89 /sync/engine/syncer.cc | |
parent | e4784baf717103943f13649a2fd385404d409441 (diff) | |
download | chromium_src-de84cfd7c982067cb1e691d2e983ec95e08b9e1b.zip chromium_src-de84cfd7c982067cb1e691d2e983ec95e08b9e1b.tar.gz chromium_src-de84cfd7c982067cb1e691d2e983ec95e08b9e1b.tar.bz2 |
sync: Expose sync functionality as functions
This change is a refactor to clean up ugliness introduced in previous
commits and prepare for future features.
The most notable change is the removal of "state machine" logic from
syncer.cc. This allows us to remove the SyncerSteps enum and related
code. The SyncShare function + enum parameters have been replaced with
the functions NormalSyncShare(), ConfigureSyncShare() and
PollSyncShare(). These changes should make it possible to address
crbug.com/109422, and to re-enable commits during poll-triggered sync
cycles (if desrired, see r206475).
The logic for fetching and applying updates has been modified, too.
Since the behaviour of GetUpdates varies depending on the type of cycle
(Configure, GetUpdates, or Poll) the logic to build and execute these
GetUpdate requests has been split up. This enables us to remove the
NudgeTracker from the SyncSession (an ugly hack introduced in
r199136). It should make it easier to implement crbug.com/147685.
In the interest of keeping this change as small and simple as possible
some obvious refactorings have not been intentionally excluded from this
CL. For example, the logic around when to send SYNC_CYCLE_ENDED events
or when to return true or false frome the SyncShare functions remains
very complicated. Untangling that mess would require some non-trivial
changes to the SyncScheduler, so they've been deferred until later.
BUG=147685,109422
Review URL: https://chromiumcodereview.appspot.com/17052007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209867 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/engine/syncer.cc')
-rw-r--r-- | sync/engine/syncer.cc | 245 |
1 files changed, 103 insertions, 142 deletions
diff --git a/sync/engine/syncer.cc b/sync/engine/syncer.cc index c4ef671..9b1adb3 100644 --- a/sync/engine/syncer.cc +++ b/sync/engine/syncer.cc @@ -15,13 +15,13 @@ #include "sync/engine/build_commit_command.h" #include "sync/engine/commit.h" #include "sync/engine/conflict_resolver.h" -#include "sync/engine/download_updates_command.h" +#include "sync/engine/download.h" #include "sync/engine/net/server_connection_manager.h" #include "sync/engine/process_commit_response_command.h" -#include "sync/engine/process_updates_command.h" -#include "sync/engine/store_timestamps_command.h" #include "sync/engine/syncer_types.h" #include "sync/internal_api/public/base/unique_position.h" +#include "sync/internal_api/public/util/syncer_error.h" +#include "sync/sessions/nudge_tracker.h" #include "sync/syncable/mutable_entry.h" #include "sync/syncable/syncable-inl.h" @@ -31,35 +31,17 @@ using sync_pb::ClientCommand; namespace syncer { +// TODO(akalin): We may want to propagate this switch up +// eventually. +#if defined(OS_ANDROID) || defined(OS_IOS) +static const bool kCreateMobileBookmarksFolder = true; +#else +static const bool kCreateMobileBookmarksFolder = false; +#endif + using sessions::StatusController; using sessions::SyncSession; -using syncable::IS_UNAPPLIED_UPDATE; -using syncable::SERVER_CTIME; -using syncable::SERVER_IS_DEL; -using syncable::SERVER_IS_DIR; -using syncable::SERVER_MTIME; -using syncable::SERVER_NON_UNIQUE_NAME; -using syncable::SERVER_PARENT_ID; -using syncable::SERVER_SPECIFICS; -using syncable::SERVER_UNIQUE_POSITION; -using syncable::SERVER_VERSION; - -#define ENUM_CASE(x) case x: return #x -const char* SyncerStepToString(const SyncerStep step) -{ - switch (step) { - ENUM_CASE(SYNCER_BEGIN); - ENUM_CASE(DOWNLOAD_UPDATES); - ENUM_CASE(PROCESS_UPDATES); - ENUM_CASE(STORE_TIMESTAMPS); - ENUM_CASE(APPLY_UPDATES); - ENUM_CASE(COMMIT); - ENUM_CASE(SYNCER_END); - } - NOTREACHED(); - return ""; -} -#undef ENUM_CASE +using sessions::NudgeTracker; Syncer::Syncer() : early_exit_requested_(false) { @@ -77,121 +59,100 @@ void Syncer::RequestEarlyExit() { early_exit_requested_ = true; } -bool Syncer::SyncShare(sessions::SyncSession* session, - SyncerStep first_step, - SyncerStep last_step) { +bool Syncer::NormalSyncShare(ModelTypeSet request_types, + const NudgeTracker& nudge_tracker, + SyncSession* session) { + HandleCycleBegin(session); + VLOG(1) << "Downloading types " << ModelTypeSetToString(request_types); + if (!DownloadAndApplyUpdates( + session, + base::Bind(&NormalDownloadUpdates, + session, + kCreateMobileBookmarksFolder, + request_types, + base::ConstRef(nudge_tracker)))) { + return HandleCycleEnd(session); + } + + VLOG(1) << "Committing from types " << ModelTypeSetToString(request_types); + SyncerError commit_result = BuildAndPostCommits(request_types, this, session); + session->mutable_status_controller()->set_commit_result(commit_result); + + return HandleCycleEnd(session); +} + +bool Syncer::ConfigureSyncShare(ModelTypeSet request_types, + SyncSession* session) { + HandleCycleBegin(session); + VLOG(1) << "Configuring types " << ModelTypeSetToString(request_types); + DownloadAndApplyUpdates( + session, + base::Bind(&DownloadUpdatesForConfigure, + session, + kCreateMobileBookmarksFolder, + session->source(), + request_types)); + return HandleCycleEnd(session); +} + +bool Syncer::PollSyncShare(ModelTypeSet request_types, + SyncSession* session) { + HandleCycleBegin(session); + VLOG(1) << "Polling types " << ModelTypeSetToString(request_types); + DownloadAndApplyUpdates( + session, + base::Bind(&DownloadUpdatesForPoll, + session, + kCreateMobileBookmarksFolder, + request_types)); + return HandleCycleEnd(session); +} + +void Syncer::ApplyUpdates(SyncSession* session) { + TRACE_EVENT0("sync", "ApplyUpdates"); + + ApplyControlDataUpdates(session); + + ApplyUpdatesAndResolveConflictsCommand apply_updates; + apply_updates.Execute(session); + + session->context()->set_hierarchy_conflict_detected( + session->status_controller().num_hierarchy_conflicts() > 0); + + session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED); +} + +bool Syncer::DownloadAndApplyUpdates( + SyncSession* session, + base::Callback<SyncerError(void)> download_fn) { + while (!session->status_controller().ServerSaysNothingMoreToDownload()) { + SyncerError download_result = download_fn.Run(); + session->mutable_status_controller()->set_last_download_updates_result( + download_result); + if (download_result != SYNCER_OK) { + return false; + } + } + if (ExitRequested()) + return false; + ApplyUpdates(session); + if (ExitRequested()) + return false; + return true; +} + +void Syncer::HandleCycleBegin(SyncSession* session) { session->mutable_status_controller()->UpdateStartTime(); - SyncerStep current_step = first_step; - - SyncerStep next_step = current_step; - while (!ExitRequested()) { - TRACE_EVENT1("sync", "SyncerStateMachine", - "state", SyncerStepToString(current_step)); - DVLOG(1) << "Syncer step:" << SyncerStepToString(current_step); - - switch (current_step) { - case SYNCER_BEGIN: - session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_BEGIN); - - next_step = DOWNLOAD_UPDATES; - break; - case DOWNLOAD_UPDATES: { - // TODO(akalin): We may want to propagate this switch up - // eventually. -#if defined(OS_ANDROID) || defined(OS_IOS) - const bool kCreateMobileBookmarksFolder = true; -#else - const bool kCreateMobileBookmarksFolder = false; -#endif - DownloadUpdatesCommand download_updates(kCreateMobileBookmarksFolder); - session->mutable_status_controller()->set_last_download_updates_result( - download_updates.Execute(session)); - next_step = PROCESS_UPDATES; - break; - } - case PROCESS_UPDATES: { - ProcessUpdatesCommand process_updates; - process_updates.Execute(session); - next_step = STORE_TIMESTAMPS; - break; - } - case STORE_TIMESTAMPS: { - StoreTimestampsCommand store_timestamps; - store_timestamps.Execute(session); - session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED); - // We download all of the updates before attempting to apply them. - if (!session->status_controller().download_updates_succeeded()) { - // We may have downloaded some updates, but if the latest download - // attempt failed then we don't have all the updates. We'll leave - // it to a retry job to pick up where we left off. - last_step = SYNCER_END; // Necessary for CONFIGURATION mode. - next_step = SYNCER_END; - DVLOG(1) << "Aborting sync cycle due to download updates failure"; - } else if (!session->status_controller() - .ServerSaysNothingMoreToDownload()) { - next_step = DOWNLOAD_UPDATES; - } else { - next_step = APPLY_UPDATES; - } - break; - } - case APPLY_UPDATES: { - // These include encryption updates that should be applied early. - ApplyControlDataUpdates(session); - - ApplyUpdatesAndResolveConflictsCommand apply_updates; - apply_updates.Execute(session); - - session->context()->set_hierarchy_conflict_detected( - session->status_controller().num_hierarchy_conflicts() > 0); - - session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED); - if (last_step == APPLY_UPDATES) { - // We're in configuration mode, but we still need to run the - // SYNCER_END step. - last_step = SYNCER_END; - next_step = SYNCER_END; - } else { - next_step = COMMIT; - } - break; - } - case COMMIT: { - session->mutable_status_controller()->set_commit_result( - BuildAndPostCommits(this, session)); - next_step = SYNCER_END; - break; - } - case SYNCER_END: { - session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_ENDED); - next_step = SYNCER_END; - break; - } - default: - LOG(ERROR) << "Unknown command: " << current_step; - } // switch - DVLOG(2) << "last step: " << SyncerStepToString(last_step) << ", " - << "current step: " << SyncerStepToString(current_step) << ", " - << "next step: " << SyncerStepToString(next_step) << ", " - << "snapshot: " << session->TakeSnapshot().ToString(); - if (last_step == current_step) - return true; - current_step = next_step; - } // while - return false; + session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_BEGIN); } -void CopyServerFields(syncable::Entry* src, syncable::MutableEntry* dest) { - dest->Put(SERVER_NON_UNIQUE_NAME, src->Get(SERVER_NON_UNIQUE_NAME)); - dest->Put(SERVER_PARENT_ID, src->Get(SERVER_PARENT_ID)); - dest->Put(SERVER_MTIME, src->Get(SERVER_MTIME)); - dest->Put(SERVER_CTIME, src->Get(SERVER_CTIME)); - dest->Put(SERVER_VERSION, src->Get(SERVER_VERSION)); - dest->Put(SERVER_IS_DIR, src->Get(SERVER_IS_DIR)); - dest->Put(SERVER_IS_DEL, src->Get(SERVER_IS_DEL)); - dest->Put(IS_UNAPPLIED_UPDATE, src->Get(IS_UNAPPLIED_UPDATE)); - dest->Put(SERVER_SPECIFICS, src->Get(SERVER_SPECIFICS)); - dest->Put(SERVER_UNIQUE_POSITION, src->Get(SERVER_UNIQUE_POSITION)); +bool Syncer::HandleCycleEnd(SyncSession* session) { + if (!ExitRequested()) { + session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_ENDED); + return true; + } else { + return false; + } } } // namespace syncer |