| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "sync/engine/non_blocking_type_commit_contribution.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <algorithm> | |
| 11 | |
| 12 #include "base/values.h" | |
| 13 #include "sync/engine/model_type_worker.h" | |
| 14 #include "sync/internal_api/public/non_blocking_sync_common.h" | |
| 15 #include "sync/protocol/proto_value_conversions.h" | |
| 16 | |
| 17 namespace syncer_v2 { | |
| 18 | |
| 19 NonBlockingTypeCommitContribution::NonBlockingTypeCommitContribution( | |
| 20 const sync_pb::DataTypeContext& context, | |
| 21 const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities, | |
| 22 ModelTypeWorker* worker) | |
| 23 : worker_(worker), | |
| 24 context_(context), | |
| 25 entities_(entities), | |
| 26 cleaned_up_(false) {} | |
| 27 | |
| 28 NonBlockingTypeCommitContribution::~NonBlockingTypeCommitContribution() { | |
| 29 DCHECK(cleaned_up_); | |
| 30 } | |
| 31 | |
| 32 void NonBlockingTypeCommitContribution::AddToCommitMessage( | |
| 33 sync_pb::ClientToServerMessage* msg) { | |
| 34 sync_pb::CommitMessage* commit_message = msg->mutable_commit(); | |
| 35 entries_start_index_ = commit_message->entries_size(); | |
| 36 | |
| 37 std::copy(entities_.begin(), | |
| 38 entities_.end(), | |
| 39 RepeatedPtrFieldBackInserter(commit_message->mutable_entries())); | |
| 40 if (!context_.context().empty()) | |
| 41 commit_message->add_client_contexts()->CopyFrom(context_); | |
| 42 } | |
| 43 | |
| 44 syncer::SyncerError NonBlockingTypeCommitContribution::ProcessCommitResponse( | |
| 45 const sync_pb::ClientToServerResponse& response, | |
| 46 syncer::sessions::StatusController* status) { | |
| 47 const sync_pb::CommitResponse& commit_response = response.commit(); | |
| 48 | |
| 49 bool transient_error = false; | |
| 50 bool commit_conflict = false; | |
| 51 bool unknown_error = false; | |
| 52 | |
| 53 CommitResponseDataList response_list; | |
| 54 | |
| 55 for (int i = 0; i < entities_.size(); ++i) { | |
| 56 const sync_pb::CommitResponse_EntryResponse& entry_response = | |
| 57 commit_response.entryresponse(entries_start_index_ + i); | |
| 58 | |
| 59 switch (entry_response.response_type()) { | |
| 60 case sync_pb::CommitResponse::INVALID_MESSAGE: | |
| 61 LOG(ERROR) << "Server reports commit message is invalid."; | |
| 62 DLOG(ERROR) << "Message was: " | |
| 63 << syncer::SyncEntityToValue(entities_.Get(i), false).get(); | |
| 64 unknown_error = true; | |
| 65 break; | |
| 66 case sync_pb::CommitResponse::CONFLICT: | |
| 67 DVLOG(1) << "Server reports conflict for commit message."; | |
| 68 DVLOG(1) << "Message was: " | |
| 69 << syncer::SyncEntityToValue(entities_.Get(i), false).get(); | |
| 70 commit_conflict = true; | |
| 71 break; | |
| 72 case sync_pb::CommitResponse::SUCCESS: { | |
| 73 CommitResponseData response_data; | |
| 74 response_data.id = entry_response.id_string(); | |
| 75 response_data.client_tag_hash = | |
| 76 entities_.Get(i).client_defined_unique_tag(); | |
| 77 response_data.response_version = entry_response.version(); | |
| 78 response_list.push_back(response_data); | |
| 79 break; | |
| 80 } | |
| 81 case sync_pb::CommitResponse::OVER_QUOTA: | |
| 82 case sync_pb::CommitResponse::RETRY: | |
| 83 case sync_pb::CommitResponse::TRANSIENT_ERROR: | |
| 84 DLOG(WARNING) << "Entity commit blocked by transient error."; | |
| 85 transient_error = true; | |
| 86 break; | |
| 87 default: | |
| 88 LOG(ERROR) << "Bad return from ProcessSingleCommitResponse."; | |
| 89 unknown_error = true; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 // Send whatever successful responses we did get back to our parent. | |
| 94 // It's the schedulers job to handle the failures. | |
| 95 worker_->OnCommitResponse(&response_list); | |
| 96 | |
| 97 // Let the scheduler know about the failures. | |
| 98 if (unknown_error) { | |
| 99 return syncer::SERVER_RETURN_UNKNOWN_ERROR; | |
| 100 } else if (transient_error) { | |
| 101 return syncer::SERVER_RETURN_TRANSIENT_ERROR; | |
| 102 } else if (commit_conflict) { | |
| 103 return syncer::SERVER_RETURN_CONFLICT; | |
| 104 } else { | |
| 105 return syncer::SYNCER_OK; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 void NonBlockingTypeCommitContribution::CleanUp() { | |
| 110 cleaned_up_ = true; | |
| 111 | |
| 112 // We could inform our parent NonBlockingCommitContributor that a commit is | |
| 113 // no longer in progress. The current implementation doesn't really care | |
| 114 // either way, so we don't bother sending the signal. | |
| 115 } | |
| 116 | |
| 117 size_t NonBlockingTypeCommitContribution::GetNumEntries() const { | |
| 118 return entities_.size(); | |
| 119 } | |
| 120 | |
| 121 } // namespace syncer_v2 | |
| OLD | NEW |