//
// TODO(satorux): We should find a way to handle the upload case more nicely,
// and shorten the delay. crbug.com/134774
-const int kDelaySeconds = 5;
+const int kDelaySeconds = 1;
// The delay constant is used to delay retrying a sync task on server errors.
const int kLongDelaySeconds = 600;
JobScheduler* scheduler,
ResourceMetadata* metadata,
FileCache* cache,
+ LoaderController* loader_controller,
const base::FilePath& temporary_file_directory)
: blocking_task_runner_(blocking_task_runner),
operation_observer_(observer),
observer,
scheduler,
metadata,
- cache)),
+ cache,
+ loader_controller)),
delay_(base::TimeDelta::FromSeconds(kDelaySeconds)),
long_delay_(base::TimeDelta::FromSeconds(kLongDelaySeconds)),
weak_ptr_factory_(this) {
tasks_.erase(it);
break;
case RUNNING:
- // TODO(kinaba): Cancel tasks in JobScheduler as well. crbug.com/248856
+ if (!task->cancel_closure.is_null())
+ task->cancel_closure.Run();
break;
}
}
base::Unretained(download_operation_.get()),
local_id,
ClientContext(BACKGROUND),
- GetFileContentInitializedCallback(),
+ base::Bind(&SyncClient::OnGetFileContentInitialized,
+ weak_ptr_factory_.GetWeakPtr()),
google_apis::GetContentCallback(),
base::Bind(&SyncClient::OnFetchFileComplete,
weak_ptr_factory_.GetWeakPtr(),
AddFetchTask((*local_ids)[i]);
}
+void SyncClient::OnGetFileContentInitialized(
+ FileError error,
+ scoped_ptr<ResourceEntry> entry,
+ const base::FilePath& local_cache_file_path,
+ const base::Closure& cancel_download_closure) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (error != FILE_ERROR_OK)
+ return;
+
+ const SyncTasks::key_type key(FETCH, entry->local_id());
+ SyncTasks::iterator it = tasks_.find(key);
+ DCHECK(it != tasks_.end());
+
+ it->second.cancel_closure = cancel_download_closure;
+}
+
bool SyncClient::OnTaskComplete(SyncType type, const std::string& local_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (error == FILE_ERROR_OK) {
DVLOG(1) << "Updated " << local_id;
+
+ // Add update tasks for child entries which may be waiting for the parent to
+ // be updated.
+ ResourceEntryVector* entries = new ResourceEntryVector;
+ base::PostTaskAndReplyWithResult(
+ blocking_task_runner_.get(),
+ FROM_HERE,
+ base::Bind(&ResourceMetadata::ReadDirectoryById,
+ base::Unretained(metadata_), local_id, entries),
+ base::Bind(&SyncClient::AddChildUpdateTasks,
+ weak_ptr_factory_.GetWeakPtr(), base::Owned(entries)));
} else {
switch (error) {
+ case FILE_ERROR_ABORT:
+ // Ignore it because this is caused by user's cancel operations.
+ break;
case FILE_ERROR_NO_CONNECTION:
// Add the task again so that we'll retry once the connection is back.
AddUpdateTaskInternal(ClientContext(BACKGROUND), local_id,
}
}
+void SyncClient::AddChildUpdateTasks(const ResourceEntryVector* entries,
+ FileError error) {
+ if (error != FILE_ERROR_OK)
+ return;
+
+ for (size_t i = 0; i < entries->size(); ++i) {
+ const ResourceEntry& entry = (*entries)[i];
+ if (entry.metadata_edit_state() != ResourceEntry::CLEAN) {
+ AddUpdateTaskInternal(ClientContext(BACKGROUND), entry.local_id(),
+ base::TimeDelta::FromSeconds(0));
+ }
+ }
+}
+
} // namespace internal
} // namespace drive