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