summaryrefslogtreecommitdiffstats
path: root/sync/engine/syncer.cc
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 03:44:20 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 03:44:20 +0000
commitde84cfd7c982067cb1e691d2e983ec95e08b9e1b (patch)
tree645dd94ad7ac7fa4dd3ef45b967b0ad23cf1eb89 /sync/engine/syncer.cc
parente4784baf717103943f13649a2fd385404d409441 (diff)
downloadchromium_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.cc245
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