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

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

Issue 299963002: sync: Implement NonBlockingTypeProcessorCore (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Unbreak some tests Created 6 years, 6 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
« no previous file with comments | « sync/engine/sync_thread_sync_entity.h ('k') | sync/engine/sync_thread_sync_entity_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/sync_thread_sync_entity.h"
6
7 #include "base/logging.h"
8 #include "sync/engine/non_blocking_sync_common.h"
9 #include "sync/internal_api/public/base/model_type.h"
10 #include "sync/syncable/syncable_util.h"
11 #include "sync/util/time.h"
12
13 namespace syncer {
14
15 SyncThreadSyncEntity* SyncThreadSyncEntity::FromServerUpdate(
16 const std::string& id_string,
17 const std::string& client_tag_hash,
18 int64 received_version) {
19 return new SyncThreadSyncEntity(
20 id_string, client_tag_hash, 0, received_version);
21 }
22
23 SyncThreadSyncEntity* SyncThreadSyncEntity::FromCommitRequest(
24 const std::string& id_string,
25 const std::string& client_tag_hash,
26 int64 sequence_number,
27 int64 base_version,
28 base::Time ctime,
29 base::Time mtime,
30 const std::string& non_unique_name,
31 bool deleted,
32 const sync_pb::EntitySpecifics& specifics) {
33 return new SyncThreadSyncEntity(id_string,
34 client_tag_hash,
35 0,
36 0,
37 true,
38 sequence_number,
39 base_version,
40 ctime,
41 mtime,
42 non_unique_name,
43 deleted,
44 specifics);
45 }
46
47 // Constructor that does not set any pending commit fields.
48 SyncThreadSyncEntity::SyncThreadSyncEntity(
49 const std::string& id,
50 const std::string& client_tag_hash,
51 int64 highest_commit_response_version,
52 int64 highest_gu_response_version)
53 : id_(id),
54 client_tag_hash_(client_tag_hash),
55 highest_commit_response_version_(highest_commit_response_version),
56 highest_gu_response_version_(highest_gu_response_version),
57 is_commit_pending_(false),
58 sequence_number_(0),
59 base_version_(0),
60 deleted_(false) {
61 }
62
63 SyncThreadSyncEntity::SyncThreadSyncEntity(
64 const std::string& id,
65 const std::string& client_tag_hash,
66 int64 highest_commit_response_version,
67 int64 highest_gu_response_version,
68 bool is_commit_pending,
69 int64 sequence_number,
70 int64 base_version,
71 base::Time ctime,
72 base::Time mtime,
73 const std::string& non_unique_name,
74 bool deleted,
75 const sync_pb::EntitySpecifics& specifics)
76 : id_(id),
77 client_tag_hash_(client_tag_hash),
78 highest_commit_response_version_(highest_commit_response_version),
79 highest_gu_response_version_(highest_gu_response_version),
80 is_commit_pending_(is_commit_pending),
81 sequence_number_(sequence_number),
82 base_version_(base_version),
83 ctime_(ctime),
84 mtime_(mtime),
85 non_unique_name_(non_unique_name),
86 deleted_(deleted),
87 specifics_(specifics) {
88 }
89
90 SyncThreadSyncEntity::~SyncThreadSyncEntity() {
91 }
92
93 bool SyncThreadSyncEntity::IsCommitPending() const {
94 return is_commit_pending_;
95 }
96
97 void SyncThreadSyncEntity::PrepareCommitProto(
98 sync_pb::SyncEntity* commit_entity,
99 int64* sequence_number) const {
100 // Set ID if we have a server-assigned ID. Otherwise, it will be up to
101 // our caller to assign a client-unique initial ID.
102 if (base_version_ != kUncommittedVersion) {
103 commit_entity->set_id_string(id_);
104 }
105
106 commit_entity->set_client_defined_unique_tag(client_tag_hash_);
107 commit_entity->set_version(base_version_);
108 commit_entity->set_deleted(deleted_);
109 commit_entity->set_folder(false);
110 commit_entity->set_name(non_unique_name_);
111 if (!deleted_) {
112 commit_entity->set_ctime(TimeToProtoTime(ctime_));
113 commit_entity->set_mtime(TimeToProtoTime(mtime_));
114 commit_entity->mutable_specifics()->CopyFrom(specifics_);
115 }
116
117 *sequence_number = sequence_number_;
118 }
119
120 void SyncThreadSyncEntity::RequestCommit(
121 const std::string& id,
122 const std::string& client_tag_hash,
123 int64 sequence_number,
124 int64 base_version,
125 base::Time ctime,
126 base::Time mtime,
127 const std::string& non_unique_name,
128 bool deleted,
129 const sync_pb::EntitySpecifics& specifics) {
130 DCHECK_GE(base_version, base_version_)
131 << "Base version should never decrease";
132
133 DCHECK_GE(sequence_number, sequence_number_)
134 << "Sequence number should never decrease";
135
136 // Update our book-keeping counters.
137 base_version_ = base_version;
138 sequence_number_ = sequence_number;
139
140 // Do our counter values indicate a conflict? If so, don't commit.
141 //
142 // There's no need to inform the model thread of the conflict. The
143 // conflicting update has already been posted to its task runner; it will
144 // figure it out as soon as it runs that task.
145 is_commit_pending_ = true;
146 if (IsInConflict()) {
147 ClearPendingCommit();
148 return;
149 }
150
151 // We don't commit deletions of server-unknown items.
152 if (deleted && !IsServerKnown()) {
153 ClearPendingCommit();
154 return;
155 }
156
157 // Otherwise, we should store the data associated with this pending commit
158 // so we're ready to commit at the next possible opportunity.
159
160 // We intentionally don't update the id_ here. Good ID values come from the
161 // server and always pass through the sync thread first. There's no way the
162 // model thread could have a better ID value than we do.
163
164 // This entity is identified by its client tag. That value can never change.
165 DCHECK_EQ(client_tag_hash_, client_tag_hash);
166
167 // Set the fields for the pending commit.
168 ctime_ = ctime;
169 mtime_ = mtime;
170 non_unique_name_ = non_unique_name;
171 deleted_ = deleted;
172 specifics_ = specifics;
173 }
174
175 void SyncThreadSyncEntity::ReceiveCommitResponse(const std::string& response_id,
176 int64 response_version,
177 int64 sequence_number) {
178 // Commit responses, especially after the first commit, can update our ID.
179 id_ = response_id;
180
181 DCHECK_GT(response_version, highest_commit_response_version_)
182 << "Had expected higher response version."
183 << " id: " << id_;
184
185 // Commits are synchronous, so there's no reason why the sequence numbers
186 // wouldn't match.
187 DCHECK_EQ(sequence_number_, sequence_number)
188 << "Unexpected sequence number mismatch."
189 << " id: " << id_;
190
191 highest_commit_response_version_ = response_version;
192
193 // Because an in-progress commit blocks the sync thread, we can assume that
194 // the item we just committed successfully is exactly the one we have now.
195 // Nothing changed it while the commit was happening. Since we're now in
196 // sync with the server, we can clear the pending commit.
197 ClearPendingCommit();
198 }
199
200 void SyncThreadSyncEntity::ReceiveUpdate(int64 version) {
201 highest_gu_response_version_ =
202 std::max(highest_gu_response_version_, version);
203
204 if (IsInConflict()) {
205 // Incoming update clobbers the pending commit on the sync thread.
206 // The model thread can re-request this commit later if it wants to.
207 ClearPendingCommit();
208 }
209 }
210
211 bool SyncThreadSyncEntity::IsInConflict() const {
212 if (!is_commit_pending_)
213 return false;
214
215 if (highest_gu_response_version_ <= highest_commit_response_version_) {
216 // The most recent server state was created in a commit made by this
217 // client. We're fully up to date, and therefore not in conflict.
218 return false;
219 } else {
220 // The most recent server state was written by someone else.
221 // Did the model thread have the most up to date version when it issued the
222 // commit request?
223 if (base_version_ >= highest_gu_response_version_) {
224 return false; // Yes.
225 } else {
226 return true; // No.
227 }
228 }
229 }
230
231 bool SyncThreadSyncEntity::IsServerKnown() const {
232 return base_version_ != kUncommittedVersion;
233 }
234
235 void SyncThreadSyncEntity::ClearPendingCommit() {
236 is_commit_pending_ = false;
237
238 // Clearing the specifics might free up some memory. It can't hurt to try.
239 specifics_.Clear();
240 }
241
242 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/engine/sync_thread_sync_entity.h ('k') | sync/engine/sync_thread_sync_entity_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698