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

Side by Side Diff: blimp/net/helium/syncable.h

Issue 2382533002: Helium: Initial proto and Syncable interface definition (Closed)
Patch Set: changes as discussed offline with @wez and @kevin Created 4 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
OLDNEW
(Empty)
1 // Copyright 2016 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 BLIMP_NET_HELIUM_SYNCABLE_H_
6 #define BLIMP_NET_HELIUM_SYNCABLE_H_
7
8 #include <stdint.h>
9 #include <memory>
10
11 #include "base/callback.h"
12 #include "base/macros.h"
13 #include "blimp/net/helium/vector_clock.h"
14
15 namespace blimp {
16
17 namespace proto {
18 class ChangesetMessage;
19 }
20
21 // Syncable is a base class interface that is used for both SyncableObject and
22 // SyncableMember classes.
23 //
24 // Syncable is something that supports creating and restoring Changesets.
25 // Objects exchange Changesets between the client and server to keep
26 // their peer counterparts eventually synchronized.
27 //
28 // 1. Mapping: There is a one-to-one relationship between instances on the
29 // client and instances on the engine.
30 // 2. Consistency: The values stored in client-engine pairs should eventually be
31 // equal.
32 //
33 // The main difference is that SyncableObject owns its lifetime, whereas
34 // SyncableMember depends on its SyncableObject parent.
35 //
36 // An example for GeoLocation would be:
37 // GeoLocation : SyncableObject {
38 // * Frequency : SyncableMember
39 // * Position : SyncableMember
40 // }
41 //
42 // VectorClocks from a SyncableMember can be compared with the VectorClock from
43 // the SyncableObject. This reduces the amount of state that needs to be kept.
44
45 template <class ChangesetType>
46 class Syncable {
47 public:
48 using CreateChangesetCallback =
49 base::Callback<void(std::unique_ptr<ChangesetType> changeset)>;
50
51 virtual ~Syncable() {}
52
53 // Constructs a changeset between the |from| revision and its current state.
54 // The Sync layer will encapsulate the changeset with details since |from|,
55 // but the Object is responsible for including any revision information
56 // additional to that expressed by the VectorClocks, that is necessary to
57 // detect and resolve conflicts.
58 // The computed changeset is returned asynchronously as a return parameter.
59 virtual std::unique_ptr<ChangesetType> CreateChangesetToCurrent(
60 const VectorClock& from) = 0;
61
62 // Asynchronous version of the CreateChangesetToCurrent.
63 // Subclasses are free to implement a more optimal implementation, for example
64 // if a SyncableObject contains |n| SyncableMembers, it can ask to create
65 // the changeset asynchronously from all the SyncableMembers instead of using
66 // the serialized version.
67 // The closure |response_callback| its called with the changeset when its
68 // ready.
69 virtual void CreateChangesetToCurrentAsync(
70 const VectorClock& from,
71 CreateChangesetCallback response_callback) {
72 std::unique_ptr<ChangesetType> changeset = CreateChangesetToCurrent(from);
73 response_callback.Run(std::move(changeset));
74 }
75
76 // Applies a |changeset| given as parameter to the contents of the
77 // Syncable.
78 // The VectorClocks |from| and |to| can be used to detect and resolve
79 // concurrent change conflicts.
80 // The closure |done| its called when the state is applied.
81 virtual void ApplyChangeset(const VectorClock& from,
Kevin M 2016/10/05 18:42:45 I'm not very comfortable with exposing the sync an
82 const VectorClock& to,
83 std::unique_ptr<ChangesetType> changeset) = 0;
84
85 // Asynchronous version of ApplyChangeset.
86 // Subclasses are free to implement a more optimal implementation for example
87 // if a SyncableObject contains |n| SyncableMembers, it can ask to apply
88 // the changeset asynchronously from all the SyncableMembers instead of using
89 // the serialized version.
90 // The closure |done| its called when the changeset is applied.
91 virtual void ApplyChangesetAsync(const VectorClock& from,
92 const VectorClock& to,
93 std::unique_ptr<ChangesetType> changeset,
94 const base::Closure& done) {
95 ApplyChangeset(from, to, std::move(changeset));
96 done.Run();
97 }
98
99 // Gives a chance for the Syncable to delete any old data previous to the
100 // |checkpoint|. This is a pretty important method that will remove some
101 // memory pressure for example from the UniqueSet CRDTs. They need to keep
102 // a growing list of added/removed elements over time. With this checkpoint
103 // info they can delete those elements prior to the vector clock specified in
104 // |checkpoint|.
105 virtual void ReleaseCheckpointsBefore(const VectorClock& checkpoint) = 0;
106 };
107
108 class SyncableObject : public Syncable<proto::ChangesetMessage> {
109 public:
110 explicit SyncableObject(const VectorClock& clock);
111 ~SyncableObject() override {}
112
113 const VectorClock& clock() const { return clock_; }
114
115 VectorClock* mutable_clock() { return &clock_; }
116
117 protected:
118 // The clock is needed in order for the |SyncableMember| objects whenever
119 // they modify their state they update their |last_modified_| value.
120 // The rationale here is use a "global" per SyncableObject clock which makes
121 // state management a lot simpler.
122 VectorClock clock_;
123
124 private:
125 DISALLOW_COPY_AND_ASSIGN(SyncableObject);
126 };
127
128 template <class ChangesetType>
129 class SyncableMember : public Syncable<ChangesetType> {
130 public:
131 explicit SyncableMember(SyncableObject* parent);
132 ~SyncableMember() override {}
133
134 // Returns true if the object have been modified since |from|.
135 virtual bool ModifiedSince(const VectorClock& from) = 0;
136
137 protected:
138 // Increments the parent clock and returns the new value. Should be used
139 // whenever a SyncableMember updates its state.
140 VectorClock IncrementParentClock();
perumaal 2016/10/05 20:42:49 Why is there an IncrementParentClock / parent_cloc
141
142 // Returns the current value of the vector clock of the parent object (aka
143 // SyncableObject).
144 const VectorClock& parent_clock() const;
145
146 private:
147 SyncableObject* parent_;
148 DISALLOW_COPY_AND_ASSIGN(SyncableMember);
149 };
150
151 SyncableObject::SyncableObject(const VectorClock& clock) : clock_(clock) {}
152
153 template <class ChangesetType>
154 SyncableMember<ChangesetType>::SyncableMember(SyncableObject* parent)
155 : parent_(parent) {}
156
157 template <class ChangesetType>
158 VectorClock SyncableMember<ChangesetType>::IncrementParentClock() {
159 parent_->mutable_clock()->IncrementLocal();
160 return parent_->clock();
161 }
162
163 template <class ChangesetType>
164 const VectorClock& SyncableMember<ChangesetType>::parent_clock() const {
165 return parent_->clock();
166 }
167
168 } // namespace blimp
169
170 #endif // BLIMP_NET_HELIUM_SYNCABLE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698