| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 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/commit.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include "base/metrics/sparse_histogram.h" | |
| 10 #include "base/trace_event/trace_event.h" | |
| 11 #include "sync/engine/commit_contribution.h" | |
| 12 #include "sync/engine/commit_processor.h" | |
| 13 #include "sync/engine/commit_util.h" | |
| 14 #include "sync/engine/syncer.h" | |
| 15 #include "sync/engine/syncer_proto_util.h" | |
| 16 #include "sync/internal_api/public/events/commit_request_event.h" | |
| 17 #include "sync/internal_api/public/events/commit_response_event.h" | |
| 18 #include "sync/sessions/sync_session.h" | |
| 19 #include "sync/util/data_type_histogram.h" | |
| 20 | |
| 21 namespace syncer { | |
| 22 | |
| 23 Commit::Commit(ContributionMap contributions, | |
| 24 const sync_pb::ClientToServerMessage& message, | |
| 25 ExtensionsActivity::Records extensions_activity_buffer) | |
| 26 : contributions_(std::move(contributions)), | |
| 27 message_(message), | |
| 28 extensions_activity_buffer_(extensions_activity_buffer), | |
| 29 cleaned_up_(false) {} | |
| 30 | |
| 31 Commit::~Commit() { | |
| 32 DCHECK(cleaned_up_); | |
| 33 } | |
| 34 | |
| 35 Commit* Commit::Init(ModelTypeSet requested_types, | |
| 36 ModelTypeSet enabled_types, | |
| 37 size_t max_entries, | |
| 38 const std::string& account_name, | |
| 39 const std::string& cache_guid, | |
| 40 bool cookie_jar_mismatch, | |
| 41 bool cookie_jar_empty, | |
| 42 CommitProcessor* commit_processor, | |
| 43 ExtensionsActivity* extensions_activity) { | |
| 44 // Gather per-type contributions. | |
| 45 ContributionMap contributions; | |
| 46 commit_processor->GatherCommitContributions(requested_types, max_entries, | |
| 47 cookie_jar_mismatch, | |
| 48 cookie_jar_empty, &contributions); | |
| 49 | |
| 50 // Give up if no one had anything to commit. | |
| 51 if (contributions.empty()) | |
| 52 return NULL; | |
| 53 | |
| 54 sync_pb::ClientToServerMessage message; | |
| 55 message.set_message_contents(sync_pb::ClientToServerMessage::COMMIT); | |
| 56 message.set_share(account_name); | |
| 57 | |
| 58 sync_pb::CommitMessage* commit_message = message.mutable_commit(); | |
| 59 commit_message->set_cache_guid(cache_guid); | |
| 60 | |
| 61 // Set extensions activity if bookmark commits are present. | |
| 62 ExtensionsActivity::Records extensions_activity_buffer; | |
| 63 ContributionMap::const_iterator it = contributions.find(syncer::BOOKMARKS); | |
| 64 if (it != contributions.end() && it->second->GetNumEntries() != 0) { | |
| 65 commit_util::AddExtensionsActivityToMessage( | |
| 66 extensions_activity, | |
| 67 &extensions_activity_buffer, | |
| 68 commit_message); | |
| 69 } | |
| 70 | |
| 71 // Set the client config params. | |
| 72 commit_util::AddClientConfigParamsToMessage( | |
| 73 enabled_types, | |
| 74 cookie_jar_mismatch, | |
| 75 commit_message); | |
| 76 | |
| 77 int previous_message_size = message.ByteSize(); | |
| 78 // Finally, serialize all our contributions. | |
| 79 for (const auto& contribution : contributions) { | |
| 80 contribution.second->AddToCommitMessage(&message); | |
| 81 int current_entry_size = message.ByteSize() - previous_message_size; | |
| 82 previous_message_size = message.ByteSize(); | |
| 83 int local_integer_model_type = ModelTypeToHistogramInt(contribution.first); | |
| 84 if (current_entry_size > 0) { | |
| 85 SyncRecordDatatypeBin("DataUse.Sync.Upload.Bytes", | |
| 86 local_integer_model_type, current_entry_size); | |
| 87 } | |
| 88 UMA_HISTOGRAM_SPARSE_SLOWLY("DataUse.Sync.Upload.Count", | |
| 89 local_integer_model_type); | |
| 90 } | |
| 91 | |
| 92 // If we made it this far, then we've successfully prepared a commit message. | |
| 93 return new Commit(std::move(contributions), message, | |
| 94 extensions_activity_buffer); | |
| 95 } | |
| 96 | |
| 97 SyncerError Commit::PostAndProcessResponse( | |
| 98 sessions::NudgeTracker* nudge_tracker, | |
| 99 sessions::SyncSession* session, | |
| 100 sessions::StatusController* status, | |
| 101 ExtensionsActivity* extensions_activity) { | |
| 102 ModelTypeSet request_types; | |
| 103 for (ContributionMap::const_iterator it = contributions_.begin(); | |
| 104 it != contributions_.end(); ++it) { | |
| 105 request_types.Put(it->first); | |
| 106 } | |
| 107 session->mutable_status_controller()->set_commit_request_types(request_types); | |
| 108 | |
| 109 if (session->context()->debug_info_getter()) { | |
| 110 sync_pb::DebugInfo* debug_info = message_.mutable_debug_info(); | |
| 111 session->context()->debug_info_getter()->GetDebugInfo(debug_info); | |
| 112 } | |
| 113 | |
| 114 DVLOG(1) << "Sending commit message."; | |
| 115 | |
| 116 CommitRequestEvent request_event( | |
| 117 base::Time::Now(), | |
| 118 message_.commit().entries_size(), | |
| 119 request_types, | |
| 120 message_); | |
| 121 session->SendProtocolEvent(request_event); | |
| 122 | |
| 123 TRACE_EVENT_BEGIN0("sync", "PostCommit"); | |
| 124 const SyncerError post_result = SyncerProtoUtil::PostClientToServerMessage( | |
| 125 &message_, &response_, session, NULL); | |
| 126 TRACE_EVENT_END0("sync", "PostCommit"); | |
| 127 | |
| 128 // TODO(rlarocque): Use result that includes errors captured later? | |
| 129 CommitResponseEvent response_event( | |
| 130 base::Time::Now(), | |
| 131 post_result, | |
| 132 response_); | |
| 133 session->SendProtocolEvent(response_event); | |
| 134 | |
| 135 if (post_result != SYNCER_OK) { | |
| 136 LOG(WARNING) << "Post commit failed"; | |
| 137 return post_result; | |
| 138 } | |
| 139 | |
| 140 if (!response_.has_commit()) { | |
| 141 LOG(WARNING) << "Commit response has no commit body!"; | |
| 142 return SERVER_RESPONSE_VALIDATION_FAILED; | |
| 143 } | |
| 144 | |
| 145 size_t message_entries = message_.commit().entries_size(); | |
| 146 size_t response_entries = response_.commit().entryresponse_size(); | |
| 147 if (message_entries != response_entries) { | |
| 148 LOG(ERROR) | |
| 149 << "Commit response has wrong number of entries! " | |
| 150 << "Expected: " << message_entries << ", " | |
| 151 << "Got: " << response_entries; | |
| 152 return SERVER_RESPONSE_VALIDATION_FAILED; | |
| 153 } | |
| 154 | |
| 155 if (session->context()->debug_info_getter()) { | |
| 156 // Clear debug info now that we have successfully sent it to the server. | |
| 157 DVLOG(1) << "Clearing client debug info."; | |
| 158 session->context()->debug_info_getter()->ClearDebugInfo(); | |
| 159 } | |
| 160 | |
| 161 // Let the contributors process the responses to each of their requests. | |
| 162 SyncerError processing_result = SYNCER_OK; | |
| 163 for (ContributionMap::const_iterator it = contributions_.begin(); | |
| 164 it != contributions_.end(); ++it) { | |
| 165 TRACE_EVENT1("sync", "ProcessCommitResponse", | |
| 166 "type", ModelTypeToString(it->first)); | |
| 167 SyncerError type_result = | |
| 168 it->second->ProcessCommitResponse(response_, status); | |
| 169 if (type_result == SERVER_RETURN_CONFLICT) { | |
| 170 nudge_tracker->RecordCommitConflict(it->first); | |
| 171 } | |
| 172 if (processing_result == SYNCER_OK && type_result != SYNCER_OK) { | |
| 173 processing_result = type_result; | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 // Handle bookmarks' special extensions activity stats. | |
| 178 if (session->status_controller(). | |
| 179 model_neutral_state().num_successful_bookmark_commits == 0) { | |
| 180 extensions_activity->PutRecords(extensions_activity_buffer_); | |
| 181 } | |
| 182 | |
| 183 return processing_result; | |
| 184 } | |
| 185 | |
| 186 void Commit::CleanUp() { | |
| 187 for (ContributionMap::const_iterator it = contributions_.begin(); | |
| 188 it != contributions_.end(); ++it) { | |
| 189 it->second->CleanUp(); | |
| 190 } | |
| 191 cleaned_up_ = true; | |
| 192 } | |
| 193 | |
| 194 } // namespace syncer | |
| OLD | NEW |