diff options
Diffstat (limited to 'sync/engine/non_blocking_type_commit_contribution.cc')
-rw-r--r-- | sync/engine/non_blocking_type_commit_contribution.cc | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/sync/engine/non_blocking_type_commit_contribution.cc b/sync/engine/non_blocking_type_commit_contribution.cc new file mode 100644 index 0000000..9e48ad6 --- /dev/null +++ b/sync/engine/non_blocking_type_commit_contribution.cc @@ -0,0 +1,119 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/engine/non_blocking_type_commit_contribution.h" + +#include "sync/engine/non_blocking_sync_common.h" +#include "sync/engine/non_blocking_type_processor_core.h" +#include "sync/protocol/proto_value_conversions.h" + +namespace syncer { + +NonBlockingTypeCommitContribution::NonBlockingTypeCommitContribution( + const sync_pb::DataTypeContext& context, + const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities, + const std::vector<int64>& sequence_numbers, + NonBlockingTypeProcessorCore* processor_core) + : processor_core_(processor_core), + context_(context), + entities_(entities), + sequence_numbers_(sequence_numbers), + cleaned_up_(false) { +} + +NonBlockingTypeCommitContribution::~NonBlockingTypeCommitContribution() { + DCHECK(cleaned_up_); +} + +void NonBlockingTypeCommitContribution::AddToCommitMessage( + sync_pb::ClientToServerMessage* msg) { + sync_pb::CommitMessage* commit_message = msg->mutable_commit(); + entries_start_index_ = commit_message->entries_size(); + + std::copy(entities_.begin(), + entities_.end(), + RepeatedPtrFieldBackInserter(commit_message->mutable_entries())); + if (!context_.context().empty()) + commit_message->add_client_contexts()->CopyFrom(context_); +} + +SyncerError NonBlockingTypeCommitContribution::ProcessCommitResponse( + const sync_pb::ClientToServerResponse& response, + sessions::StatusController* status) { + const sync_pb::CommitResponse& commit_response = response.commit(); + + bool transient_error = false; + bool commit_conflict = false; + bool unknown_error = false; + + CommitResponseDataList response_list; + + for (size_t i = 0; i < sequence_numbers_.size(); ++i) { + const sync_pb::CommitResponse_EntryResponse& entry_response = + commit_response.entryresponse(entries_start_index_ + i); + + switch (entry_response.response_type()) { + case sync_pb::CommitResponse::INVALID_MESSAGE: + LOG(ERROR) << "Server reports commit message is invalid."; + DLOG(ERROR) << "Message was: " << SyncEntityToValue(entities_.Get(i), + false); + unknown_error = true; + break; + case sync_pb::CommitResponse::CONFLICT: + DVLOG(1) << "Server reports conflict for commit message."; + DVLOG(1) << "Message was: " << SyncEntityToValue(entities_.Get(i), + false); + commit_conflict = true; + break; + case sync_pb::CommitResponse::SUCCESS: { + CommitResponseData response_data; + response_data.id = entry_response.id_string(); + response_data.client_tag_hash = + entities_.Get(i).client_defined_unique_tag(); + response_data.sequence_number = sequence_numbers_[i]; + response_data.response_version = entry_response.version(); + response_list.push_back(response_data); + break; + } + case sync_pb::CommitResponse::OVER_QUOTA: + case sync_pb::CommitResponse::RETRY: + case sync_pb::CommitResponse::TRANSIENT_ERROR: + DLOG(WARNING) << "Entity commit blocked by transient error."; + transient_error = true; + break; + default: + LOG(ERROR) << "Bad return from ProcessSingleCommitResponse."; + unknown_error = true; + } + } + + // Send whatever successful responses we did get back to our parent. + // It's the schedulers job to handle the failures. + processor_core_->OnCommitResponse(response_list); + + // Let the scheduler know about the failures. + if (unknown_error) { + return SERVER_RETURN_UNKNOWN_ERROR; + } else if (transient_error) { + return SERVER_RETURN_TRANSIENT_ERROR; + } else if (commit_conflict) { + return SERVER_RETURN_CONFLICT; + } else { + return SYNCER_OK; + } +} + +void NonBlockingTypeCommitContribution::CleanUp() { + cleaned_up_ = true; + + // We could inform our parent NonBlockingCommitContributor that a commit is + // no longer in progress. The current implementation doesn't really care + // either way, so we don't bother sending the signal. +} + +size_t NonBlockingTypeCommitContribution::GetNumEntries() const { + return sequence_numbers_.size(); +} + +} // namespace syncer |