Chromium Code Reviews| Index: blimp/net/helium/syncable.h |
| diff --git a/blimp/net/helium/syncable.h b/blimp/net/helium/syncable.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..00945f46a4306c2e6cfc9c1337cbc88067640e1e |
| --- /dev/null |
| +++ b/blimp/net/helium/syncable.h |
| @@ -0,0 +1,107 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef BLIMP_NET_HELIUM_SYNCABLE_H_ |
| +#define BLIMP_NET_HELIUM_SYNCABLE_H_ |
| + |
| +#include <stdint.h> |
| + |
| +#include "base/callback.h" |
| +#include "blimp/common/proto/helium.pb.h" |
| +#include "blimp/net/helium/vector_clock.h" |
| + |
| +namespace blimp { |
| + |
| +// SyncableObject and SyncableMember are conceptually very similar. |
| +// Both are objects that will be synchronized between client and engine. |
| +// |
| +// 1. There is a one-to-one relationship between instances on the client and |
| +// instances on the engine. |
| +// 2. The values stored in client-engine pairs should eventually be equal. |
| +// |
| +// The main difference is that SyncableObject owns its lifetime, whereas |
| +// SyncableMember depends on its SyncableObject parent. |
| +// |
| +// An example for GeoLocation would be: |
| +// GeoLocation : SyncableObject { |
| +// * Frequency : SyncableMember |
| +// * Position : SyncableMember |
| +// } |
| +// |
| +// VectorClocks from a SyncableMember can be compared with the VectorClock from |
| +// the SyncableObject. This reduces the amount of state that needs to be kept. |
| + |
| +template <class ChangesetType> |
| +class Syncable { |
| + public: |
| + using CreateChangesetCallback = |
| + base::Callback<void(std::unique_ptr<ChangesetType>)>; |
| + |
| + Syncable() {} |
|
Kevin M
2016/09/30 18:34:36
Don't need to add ctor - class doesn't have any co
scf
2016/09/30 22:13:24
Done.
|
| + virtual ~Syncable() {} |
| + |
| + // Constructs a changeset between the |from| revision and its current state. |
| + // The Sync layer will encapsulate the changeset with details since |from|, |
| + // but the Object is responsible for including any revision information |
| + // additional to that expressed by the VectorClocks, that is necessary to |
| + // detect and resolve conflicts. |
| + // The computed changeset is returned asynchronously via |response_callback|. |
| + virtual void CreateChangesetToCurrent( |
| + const VectorClock& from, |
| + const CreateChangesetCallback& response_callback) = 0; |
|
Kevin M
2016/09/30 18:34:37
Sorry - it now occurs to me that this should proba
scf
2016/09/30 22:13:24
Done.
|
| + |
| + // Applies a |changeset| given as parameter to the contents of the |
| + // Syncable. |
| + // The VectorClocks |from| and |to| can be used to detect and resolve |
| + // concurrent change conflicts. |
| + // The closure |done| its called when the state is applied. |
| + virtual void ApplyChangeset(const VectorClock& from, |
| + const VectorClock& to, |
| + const ChangesetType& changeset, |
|
Kevin M
2016/09/30 18:34:36
We should take this as a unique_ptr so that we can
scf
2016/09/30 22:13:23
Done.
|
| + const base::Closure& done) = 0; |
| + |
| + // Gives a chance for the Syncable to delete any old data previous to the |
| + // |checkpoint|. This is a pretty important method that will remove some |
| + // memory pressure for example from the UniqueSet CRDTs. They need to keep |
| + // a growing list of added/removed elements over time. With this checkpoint |
| + // info they can delete those elements prior to the vector clock specified in |
| + // |checkpoint|. |
| + virtual void ReleaseCheckpointsBefore(const VectorClock& checkpoint) = 0; |
| +}; |
| + |
| +class SyncableObject : public Syncable<helium::Changeset> { |
| + public: |
| + explicit SyncableObject(const VectorClock& clock); |
|
Kevin M
2016/09/30 18:34:36
Maybe add a no-arg constructor that just uses a ze
scf
2016/09/30 22:13:24
Done.
|
| + ~SyncableObject() override {} |
| + |
| + VectorClock& get_clock() { return clock_; } |
|
Kevin M
2016/09/30 18:34:36
* Inline getters don't need a get_ prefix.
* Refer
scf
2016/09/30 22:13:24
done. using the proto convention (mutable_name)
|
| + |
| + protected: |
| + // The clock is needed in order for the |SyncableMember| objects whenever |
|
Kevin M
2016/09/30 18:34:36
Remove space before The
scf
2016/09/30 22:13:24
Done.
|
| + // they modify their state they update their |last_modified_| value. |
| + // The rationale here is use a "global" per SyncableObject clock which makes |
| + // state management a lot simpler. |
| + VectorClock clock_; |
|
Kevin M
2016/09/30 18:34:36
Add DISALLOW_COPY_AND_ASSIGN(SyncableObject);
scf
2016/09/30 22:13:24
Done.
|
| +}; |
| + |
| +template <class ChangesetType> |
| +class SyncableMember : public Syncable<ChangesetType> { |
| + public: |
| + explicit SyncableMember(SyncableObject* parent); |
| + ~SyncableMember() override {} |
| + |
| + // Returns true if the object have been modified since |from| |
| + virtual bool ModifiedSince(const VectorClock& from) = 0; |
| + |
| + protected: |
| + // Increments the parent clock and returns the new value. Should be used |
| + // whenever a SyncableMember updates its state. |
| + VectorClock IncrementParentClock(); |
| + |
| + SyncableObject* parent_; |
|
Kevin M
2016/09/30 18:34:36
DISALLOW_COPY_AND_ASSIGN
scf
2016/09/30 22:13:24
Done.
|
| +}; |
| + |
| +} // namespace blimp |
| + |
| +#endif // BLIMP_NET_HELIUM_SYNCABLE_H_ |