Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: sync/engine/sync_directory_commit_contribution.cc

Issue 25638003: sync: Implement per-type commit interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile warning Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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/sync_directory_commit_contribution.h"
6
7 #include "sync/engine/build_commit_command.h"
8 #include "sync/engine/get_commit_ids.h"
9 #include "sync/engine/process_commit_response_command.h"
10 #include "sync/engine/syncer_util.h"
11 #include "sync/syncable/model_neutral_mutable_entry.h"
12 #include "sync/syncable/syncable_model_neutral_write_transaction.h"
13
14 namespace syncer {
15
16 using syncable::SYNCER;
17 using syncable::GET_BY_HANDLE;
18
19 SyncDirectoryCommitContribution::SyncDirectoryCommitContribution(
20 syncable::Directory* dir,
21 std::vector<int64> metahandles,
22 google::protobuf::RepeatedPtrField<sync_pb::SyncEntity> entities)
23 : dir_(dir),
24 metahandles_(metahandles),
25 entities_(entities),
26 entries_start_index_(0xDEADBEEF) {
27 }
28
29 SyncDirectoryCommitContribution::~SyncDirectoryCommitContribution() {
30 syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir_);
31 for (std::vector<int64>::const_iterator it = metahandles_.begin();
32 it != metahandles_.end(); ++it) {
33 syncable::ModelNeutralMutableEntry entry(&trans, GET_BY_HANDLE, *it);
34 entry.PutSyncing(false);
35 }
36 }
37
38 // static.
39 SyncDirectoryCommitContribution* SyncDirectoryCommitContribution::Build(
40 syncable::Directory* dir,
41 ModelType type,
42 size_t max_entries) {
43 std::vector<int64> metahandles;
44
45 syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir);
46 GetCommitIdsForType(&trans, type, max_entries, &metahandles);
47
48 if (metahandles.empty())
49 return NULL;
50
51 google::protobuf::RepeatedPtrField<sync_pb::SyncEntity> entities;
52 for (std::vector<int64>::iterator it = metahandles.begin();
53 it != metahandles.end(); ++it) {
54 sync_pb::SyncEntity* entity = entities.Add();
55 syncable::ModelNeutralMutableEntry entry(&trans, GET_BY_HANDLE, *it);
56 BuildCommitCommand::BuildCommitItem(entry, entity);
57 entry.PutSyncing(true);
58 }
59
60 return new SyncDirectoryCommitContribution(dir, metahandles, entities);
61 }
62
63 void SyncDirectoryCommitContribution::AddToCommitMessage(
64 sync_pb::ClientToServerMessage* msg) {
65 sync_pb::CommitMessage* commit_message = msg->mutable_commit();
66 entries_start_index_ = commit_message->entries_size();
67 std::copy(entities_.begin(),
68 entities_.end(),
69 RepeatedPtrFieldBackInserter(commit_message->mutable_entries()));
70 }
71
72 SyncerError SyncDirectoryCommitContribution::ProcessCommitResponse(
73 const sync_pb::ClientToServerResponse& response,
74 sessions::StatusController* status) {
75 const sync_pb::CommitResponse& commit_response = response.commit();
76
77 int transient_error_commits = 0;
78 int conflicting_commits = 0;
79 int error_commits = 0;
80 int successes = 0;
81
82 std::set<syncable::Id> deleted_folders;
83 {
84 syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir_);
85 for (size_t i = 0; i < metahandles_.size(); ++i) {
86 sync_pb::CommitResponse::ResponseType response_type =
87 ProcessCommitResponseCommand::ProcessSingleCommitResponse(
88 &trans,
89 commit_response.entryresponse(entries_start_index_ + i),
90 entities_.Get(i),
91 metahandles_[i],
92 &deleted_folders);
93 switch (response_type) {
94 case sync_pb::CommitResponse::INVALID_MESSAGE:
95 ++error_commits;
96 break;
97 case sync_pb::CommitResponse::CONFLICT:
98 ++conflicting_commits;
99 status->increment_num_server_conflicts();
100 break;
101 case sync_pb::CommitResponse::SUCCESS:
102 ++successes;
103 {
104 syncable::Entry e(&trans, GET_BY_HANDLE, metahandles_[i]);
105 if (e.GetModelType() == BOOKMARKS)
106 status->increment_num_successful_bookmark_commits();
107 }
108 status->increment_num_successful_commits();
109 break;
110 case sync_pb::CommitResponse::OVER_QUOTA:
111 // We handle over quota like a retry, which is same as transient.
112 case sync_pb::CommitResponse::RETRY:
113 case sync_pb::CommitResponse::TRANSIENT_ERROR:
114 ++transient_error_commits;
115 break;
116 default:
117 LOG(FATAL) << "Bad return from ProcessSingleCommitResponse";
118 }
119 }
120 MarkDeletedChildrenSynced(dir_, &trans, &deleted_folders);
121 }
122
123 int commit_count = static_cast<int>(metahandles_.size());
124 if (commit_count == successes) {
125 return SYNCER_OK;
126 } else if (error_commits > 0) {
127 return SERVER_RETURN_UNKNOWN_ERROR;
128 } else if (transient_error_commits > 0) {
129 return SERVER_RETURN_TRANSIENT_ERROR;
130 } else if (conflicting_commits > 0) {
131 // This means that the server already has an item with this version, but
132 // we haven't seen that update yet.
133 //
134 // A well-behaved client should respond to this by proceeding to the
135 // download updates phase, fetching the conflicting items, then attempting
136 // to resolve the conflict. That's not what this client does.
137 //
138 // We don't currently have any code to support that exceptional control
139 // flow. Instead, we abort the current sync cycle and start a new one. The
140 // end result is the same.
141 return SERVER_RETURN_CONFLICT;
142 } else {
143 LOG(FATAL) << "Inconsistent counts when processing commit response";
144 return SYNCER_OK;
145 }
146 }
147
148 size_t SyncDirectoryCommitContribution::GetNumEntries() {
149 return metahandles_.size();
150 }
151
152 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698