Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1858)

Unified Diff: chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc

Issue 554213002: [SyncFS] Run RemoteToLocalSyncer as a background task (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc
diff --git a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc
index 003622cea4621b11b04340040a0f284008c57774..26485121764a2d966cc996faf81400e4dcf2d1f1 100644
--- a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.cc
@@ -106,15 +106,6 @@ RemoteToLocalSyncer::~RemoteToLocalSyncer() {
void RemoteToLocalSyncer::RunPreflight(scoped_ptr<SyncTaskToken> token) {
token->InitializeTaskLog("Remote -> Local");
- scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
- task_blocker->exclusive = true;
- SyncTaskManager::UpdateTaskBlocker(
- token.Pass(), task_blocker.Pass(),
- base::Bind(&RemoteToLocalSyncer::RunExclusive,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void RemoteToLocalSyncer::RunExclusive(scoped_ptr<SyncTaskToken> token) {
if (!drive_service() || !metadata_database() || !remote_change_processor()) {
token->RecordLog("Context not ready.");
SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED);
@@ -146,7 +137,11 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
NOTREACHED();
}
token->RecordLog("Missing remote metadata case.");
- HandleMissingRemoteMetadata(token.Pass());
+
+ MoveToBackground(
+ token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleMissingRemoteMetadata,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
@@ -183,7 +178,8 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
synced_details.title() != remote_details.title() ||
remote_details.parent_folder_ids_size()) {
token->RecordLog("Sync-root deletion.");
- HandleSyncRootDeletion(token.Pass());
+ sync_root_deletion_ = true;
+ SyncCompleted(token.Pass(), SYNC_STATUS_OK);
return;
}
token->RecordLog("Trivial sync-root change.");
@@ -194,10 +190,20 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
DCHECK_NE(dirty_tracker_->tracker_id(),
metadata_database()->GetSyncRootTrackerID());
+ if (!BuildFileSystemURL(metadata_database(), *dirty_tracker_, &url_)) {
+ NOTREACHED();
+ SyncCompleted(token.Pass(), SYNC_STATUS_FAILED);
+ return;
+ }
+
+ DCHECK(url_.is_valid());
+
if (remote_details.missing()) {
if (!synced_details.missing()) {
token->RecordLog("Remote file deletion.");
- HandleDeletion(token.Pass());
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleDeletion,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
@@ -238,9 +244,10 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
if (synced_details.title() != remote_details.title()) {
// Handle rename as deletion + addition.
token->RecordLog("Detected file rename.");
- Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(&token)));
+
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleFileMove,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
DCHECK_EQ(synced_details.title(), remote_details.title());
@@ -258,28 +265,35 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
if (!HasFolderAsParent(remote_details, parent_tracker.file_id())) {
// Handle reorganize as deletion + addition.
token->RecordLog("Detected file reorganize.");
- Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(&token)));
+
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleFileMove,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
if (synced_details.file_kind() == FILE_KIND_FILE) {
if (synced_details.md5() != remote_details.md5()) {
token->RecordLog("Detected file content update.");
- HandleContentUpdate(token.Pass());
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleContentUpdate,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
} else {
DCHECK_EQ(FILE_KIND_FOLDER, synced_details.file_kind());
if (synced_details.missing()) {
token->RecordLog("Detected folder update.");
- HandleFolderUpdate(token.Pass());
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::HandleFolderUpdate,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
if (dirty_tracker_->needs_folder_listing()) {
token->RecordLog("Needs listing folder.");
- ListFolderContent(token.Pass());
+ MoveToBackground(token.Pass(),
+ base::Bind(&RemoteToLocalSyncer::ListFolderContent,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
SyncCompleted(token.Pass(), SYNC_STATUS_OK);
@@ -290,6 +304,88 @@ void RemoteToLocalSyncer::ResolveRemoteChange(scoped_ptr<SyncTaskToken> token) {
SyncCompleted(token.Pass(), SYNC_STATUS_OK);
}
+void RemoteToLocalSyncer::MoveToBackground(scoped_ptr<SyncTaskToken> token,
+ const Continuation& continuation) {
+ DCHECK(dirty_tracker_);
+
+ scoped_ptr<TaskBlocker> blocker(new TaskBlocker);
+ blocker->app_id = dirty_tracker_->app_id();
+ if (url_.is_valid())
+ blocker->paths.push_back(url_.path());
+ blocker->file_ids.push_back(dirty_tracker_->file_id());
+ blocker->tracker_ids.push_back(dirty_tracker_->tracker_id());
+
+ SyncTaskManager::UpdateTaskBlocker(
+ token.Pass(), blocker.Pass(),
+ base::Bind(&RemoteToLocalSyncer::ContinueAsBackgroundTask,
+ weak_ptr_factory_.GetWeakPtr(), continuation));
+}
+
+void RemoteToLocalSyncer::ContinueAsBackgroundTask(
+ const Continuation& continuation,
+ scoped_ptr<SyncTaskToken> token) {
+ DCHECK(dirty_tracker_);
+
+ // The SyncTask runs as a background task beyond this point.
+ // Not that any task can run between MoveToBackground() and
+ // ContinueAsBackgroundTask(), so we need to make sure other tasks didn't
+ // affect to the current RemoteToLocalSyncer task.
+ //
+ // - For LocalToRemoteSyncer, it may update or delete any of FileTracker and
+ // FileMetadata. When it updates FileMetadata or FileDetais in FileTracker,
nhiroki 2014/09/16 08:42:27 s/FileDetais/FileDetails/
tzik 2014/09/24 06:01:49 Done.
+ // it also updates |change_id|. So, ensure the target FileTracker and
+ // FileMetadata exist and their |change_id|s are not updated.
+ // - For ListChangesTask, it may update FileMetadata together with |change_id|
+ // and may delete FileTracker.
+ // - For UnininstallAppTask, it may delete FileMetadata and FileTracker.
nhiroki 2014/09/16 08:42:27 s/UnininstallAppTask/UninstallAppTask/
tzik 2014/09/24 06:01:49 Done.
+ // Check if FileTracker still exists.
+ // - For other RemoteToLocalSyncer, it may delete the FileTracker of parent.
+ // Note that since RemoteToLocalSyncer demotes the target FileTracker first,
+ // any other RemoteToLocalSyncer does not run for current |dirty_tracker_|.
+ // - Others, SyncEngineInitializer and RegisterAppTask doesn't affect to
+
+ FileTracker latest_dirty_tracker;
+ if (!metadata_database()->FindTrackerByTrackerID(
+ dirty_tracker_->tracker_id(), &latest_dirty_tracker) ||
+ dirty_tracker_->active() != latest_dirty_tracker.active() ||
+ !latest_dirty_tracker.dirty()) {
+ SyncCompleted(token.Pass(), SYNC_STATUS_RETRY);
+ return;
+ }
+
+ int64 current_change_id = kint64min;
+ int64 latest_change_id = kint64min;
+ if (dirty_tracker_->has_synced_details())
+ current_change_id = dirty_tracker_->synced_details().change_id();
+ if (latest_dirty_tracker.has_synced_details())
+ latest_change_id = latest_dirty_tracker.synced_details().change_id();
+ if (current_change_id != latest_change_id) {
+ SyncCompleted(token.Pass(), SYNC_STATUS_RETRY);
+ return;
+ }
+
+ FileMetadata latest_file_metadata;
+ if (metadata_database()->FindFileByFileID(dirty_tracker_->file_id(),
+ &latest_file_metadata)) {
+ if (!remote_metadata_) {
+ SyncCompleted(token.Pass(), SYNC_STATUS_RETRY);
+ return;
+ }
+
+ if (remote_metadata_->details().change_id() !=
+ latest_file_metadata.details().change_id()) {
nhiroki 2014/09/16 08:42:27 nit: You may need a 4-space indent.
tzik 2014/09/24 06:01:49 Done. I introduced local variable for them.
+ SyncCompleted(token.Pass(), SYNC_STATUS_RETRY);
+ return;
+ }
+ } else {
+ if (remote_metadata_) {
+ SyncCompleted(token.Pass(), SYNC_STATUS_RETRY);
+ return;
+ }
+ }
+ continuation.Run(token.Pass());
+}
+
void RemoteToLocalSyncer::HandleMissingRemoteMetadata(
scoped_ptr<SyncTaskToken> token) {
DCHECK(dirty_tracker_);
@@ -444,12 +540,6 @@ void RemoteToLocalSyncer::DidPrepareForFolderUpdate(
CreateFolder(token.Pass());
}
-void RemoteToLocalSyncer::HandleSyncRootDeletion(
- scoped_ptr<SyncTaskToken> token) {
- sync_root_deletion_ = true;
- SyncCompleted(token.Pass(), SYNC_STATUS_OK);
-}
-
void RemoteToLocalSyncer::HandleDeletion(
scoped_ptr<SyncTaskToken> token) {
DCHECK(dirty_tracker_);
@@ -467,6 +557,21 @@ void RemoteToLocalSyncer::HandleDeletion(
base::Passed(&token)));
}
+void RemoteToLocalSyncer::HandleFileMove(scoped_ptr<SyncTaskToken> token) {
+ DCHECK(dirty_tracker_);
+ DCHECK(dirty_tracker_->active());
+ DCHECK(!HasDisabledAppRoot(metadata_database(), *dirty_tracker_));
+ DCHECK(dirty_tracker_->has_synced_details());
+
+ DCHECK(remote_metadata_);
+ DCHECK(remote_metadata_->has_details());
+ DCHECK(!remote_metadata_->details().missing());
+
+ Prepare(base::Bind(&RemoteToLocalSyncer::DidPrepareForDeletion,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&token)));
+}
+
void RemoteToLocalSyncer::DidPrepareForDeletion(
scoped_ptr<SyncTaskToken> token,
SyncStatusCode status) {
@@ -639,9 +744,6 @@ void RemoteToLocalSyncer::FinalizeSync(scoped_ptr<SyncTaskToken> token,
}
void RemoteToLocalSyncer::Prepare(const SyncStatusCallback& callback) {
- bool should_success = BuildFileSystemURL(
- metadata_database(), *dirty_tracker_, &url_);
- DCHECK(should_success);
DCHECK(url_.is_valid());
remote_change_processor()->PrepareForProcessRemoteChange(
url_,
« no previous file with comments | « chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698