• 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 #ifndef SYNC_ENGINE_ENTITY_TRACKER_H_
6 #define SYNC_ENGINE_ENTITY_TRACKER_H_
7 
8 #include <string>
9 
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/time/time.h"
13 #include "sync/base/sync_export.h"
14 #include "sync/internal_api/public/non_blocking_sync_common.h"
15 #include "sync/protocol/sync.pb.h"
16 
17 namespace syncer {
18 
19 // Manages the pending commit and update state for an entity on the sync
20 // thread.
21 //
22 // It should be considered a helper class internal to the
23 // ModelTypeSyncWorker.
24 //
25 // Maintains the state associated with a particular sync entity which is
26 // necessary for decision-making on the sync thread.  It can track pending
27 // commit state, received update state, and can detect conflicts.
28 //
29 // This object may or may not contain state associated with a pending commit.
30 // If no commit is pending, the |is_commit_pending_| flag will be set to false
31 // and many of this object's fields will be cleared.
32 class SYNC_EXPORT EntityTracker {
33  public:
34   ~EntityTracker();
35 
36   // Initialize a new entity based on an update response.
37   static EntityTracker* FromServerUpdate(const std::string& id_string,
38                                          const std::string& client_tag_hash,
39                                          int64 version);
40 
41   // Initialize a new entity based on a commit request.
42   static EntityTracker* FromCommitRequest(
43       const std::string& id_string,
44       const std::string& client_tag_hash,
45       int64 sequence_number,
46       int64 base_version,
47       base::Time ctime,
48       base::Time mtime,
49       const std::string& non_unique_name,
50       bool deleted,
51       const sync_pb::EntitySpecifics& specifics);
52 
53   // Returns true if this entity should be commited to the server.
54   bool IsCommitPending() const;
55 
56   // Populates a sync_pb::SyncEntity for a commit.  Also sets the
57   // |sequence_number|, so we can track it throughout the commit process.
58   void PrepareCommitProto(sync_pb::SyncEntity* commit_entity,
59                           int64* sequence_number) const;
60 
61   // Updates this entity with data from the latest version that the
62   // model asked us to commit.  May clobber state related to the
63   // model's previous commit attempt(s).
64   void RequestCommit(const std::string& id,
65                      const std::string& client_tag_hash,
66                      int64 sequence_number,
67                      int64 base_version,
68                      base::Time ctime,
69                      base::Time mtime,
70                      const std::string& non_unique_name,
71                      bool deleted,
72                      const sync_pb::EntitySpecifics& specifics);
73 
74   // Handles the receipt of a commit response.
75   //
76   // Since commits happen entirely on the sync thread, we can safely assume
77   // that our item's state at the end of the commit is the same as it was at
78   // the start.
79   void ReceiveCommitResponse(const std::string& response_id,
80                              int64 response_version,
81                              int64 sequence_number);
82 
83   // Handles receipt of an update from the server.
84   void ReceiveUpdate(int64 version);
85 
86   // Handles the receipt of an pending update from the server.
87   //
88   // Returns true if the tracker decides this item is worth keeping.  Returns
89   // false if the item is discarded, which could happen if the version number
90   // is out of date.
91   bool ReceivePendingUpdate(const UpdateResponseData& data);
92 
93   // Functions to fetch the latest pending update.
94   bool HasPendingUpdate() const;
95   UpdateResponseData GetPendingUpdate() const;
96 
97   // Clears the pending update.  Allows us to resume regular commit behavior.
98   void ClearPendingUpdate();
99 
100  private:
101   // Initializes received update state.  Does not initialize state related to
102   // pending commits and sets |is_commit_pending_| to false.
103   EntityTracker(const std::string& id,
104                 const std::string& client_tag_hash,
105                 int64 highest_commit_response_version,
106                 int64 highest_gu_response_version);
107 
108   // Initializes all fields.  Sets |is_commit_pending_| to true.
109   EntityTracker(const std::string& id,
110                 const std::string& client_tag_hash,
111                 int64 highest_commit_response_version,
112                 int64 highest_gu_response_version,
113                 bool is_commit_pending,
114                 int64 sequence_number,
115                 int64 base_version,
116                 base::Time ctime,
117                 base::Time mtime,
118                 const std::string& non_unique_name,
119                 bool deleted,
120                 const sync_pb::EntitySpecifics& specifics);
121 
122   // Checks if the current state indicates a conflict.
123   //
124   // This can be true only while a call to this object is in progress.
125   // Conflicts are always cleared before the method call ends.
126   bool IsInConflict() const;
127 
128   // Checks if the server knows about this item.
129   bool IsServerKnown() const;
130 
131   // Clears flag and optionally clears state associated with a pending commit.
132   void ClearPendingCommit();
133 
134   // The ID for this entry.  May be empty if the entry has never been committed.
135   std::string id_;
136 
137   // The hashed client tag for this entry.
138   std::string client_tag_hash_;
139 
140   // The highest version seen in a commit response for this entry.
141   int64 highest_commit_response_version_;
142 
143   // The highest version seen in a GU response for this entry.
144   int64 highest_gu_response_version_;
145 
146   // Flag that indicates whether or not we're waiting for a chance to commit
147   // this item.
148   bool is_commit_pending_;
149 
150   // Used to track in-flight commit requests on the model thread.  All we need
151   // to do here is return it back to the model thread when the pending commit
152   // is completed and confirmed.  Not valid if no commit is pending.
153   int64 sequence_number_;
154 
155   // The following fields are valid only when a commit is pending.
156   // This is where we store the data that is to be sent up to the server
157   // at the next possible opportunity.
158   int64 base_version_;
159   base::Time ctime_;
160   base::Time mtime_;
161   std::string non_unique_name_;
162   bool deleted_;
163   sync_pb::EntitySpecifics specifics_;
164 
165   // An update for this item which can't be applied right now.  The presence of
166   // an pending update prevents commits.  As of this writing, the only source
167   // of pending updates is updates we can't decrypt right now.
168   scoped_ptr<UpdateResponseData> pending_update_;
169 
170   DISALLOW_COPY_AND_ASSIGN(EntityTracker);
171 };
172 
173 }  // namespace syncer
174 
175 #endif  // SYNC_ENGINE_ENTITY_TRACKER_H_
176