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..6adba6ad187c9450eebf88a8ab890c93e190c03f |
| --- /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 |
| +// Syncable depends on its SyncableObject parent. |
|
Brian Goldman
2016/09/29 23:18:03
Replace "Syncable" with "SyncableMember" here.
scf
2016/09/30 17:26:23
#goodcatch
|
| +// |
| +// 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(){} |
| + 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; |
| + |
| + // 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, |
| + 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); |
| + ~SyncableObject() override {} |
| + |
| + VectorClock& get_clock() { return clock_; } |
| + |
| + protected: |
| + // The clock is needed in order for the |SyncableMember| objects whenever |
| + // 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_; |
| +}; |
| + |
| +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_; |
| +}; |
| + |
| +} // namespace blimp |
| + |
| +#endif // BLIMP_NET_HELIUM_SYNCABLE_H_ |