| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package interfaces |
| |
| import ( |
| "time" |
| |
| wire "v.io/v23/services/syncbase" |
| "v.io/v23/security/access" |
| ) |
| |
| const ( |
| NoGroupId = GroupId("") |
| ) |
| |
| // TODO(hpucha): These are not final yet. This is an intermediate step. |
| |
| const ( |
| // NodeRec type log record adds a new node in the dag. |
| NodeRec = byte(0) |
| |
| // LinkRec type log record adds a new link in the dag. Link records are |
| // added when a conflict is resolved by picking the local or the remote |
| // version as the resolution of a conflict, instead of creating a new |
| // version. |
| LinkRec = byte(1) |
| ) |
| |
| // GenVector is the generation vector for any syncable entity, which maps each |
| // device id to its last locally known generation in the scope of that entity. |
| type GenVector map[uint64]uint64 |
| |
| // Knowledge is a mapping of syncable entities to their generation |
| // vectors. These syncable entities could be data prefixes relative to a |
| // Database id, or syncgroup oids. |
| type Knowledge map[string]GenVector |
| |
| // LogRecMetadata represents the metadata of a single log record that is |
| // exchanged between two peers. Each log record represents a change made to an |
| // object in the store. |
| // |
| // TODO(hpucha): Add readset/scanset. Look into sending tx metadata only once |
| // per transaction. |
| type LogRecMetadata struct { |
| // Log related information. |
| Id uint64 // device id that created the log record. |
| Gen uint64 // generation number for the log record. |
| RecType byte // type of log record. |
| |
| // Object related information. |
| |
| // Id of the object that was updated. This id is relative to Application |
| // and Database names and is the store key for a particular row in a |
| // collection. |
| ObjId string |
| CurVers string // current version number of the object. |
| Parents []string // 0, 1 or 2 parent versions that the current version is derived from. |
| UpdTime time.Time // timestamp when the update is generated. |
| Delete bool // indicates whether the update resulted in object being deleted from the store. |
| BatchId uint64 // unique id of the Batch this update belongs to. |
| BatchCount uint64 // number of objects in the Batch. |
| } |
| |
| // LogRec represents the on-wire representation of an entire log record: its |
| // metadata and data. Value is the actual value of a store object. |
| type LogRec struct { |
| Metadata LogRecMetadata |
| Value any |
| } |
| |
| // GroupId is a globally unique syncgroup ID. |
| // It is a hash of the syncgroup name. |
| type GroupId string |
| |
| // Possible states for a syncgroup. |
| type SyncgroupStatus enum { |
| // Indicates that a syncgroup is operational, but publishing to the |
| // remote server is pending. |
| PublishPending |
| |
| // Indicates that the syncgroup is operational, but the publishing |
| // failed. |
| PublishRejected |
| |
| // Indicates that the syncgroup is operational and published. |
| Running |
| } |
| |
| // Syncgroup contains the state of a syncgroup. |
| type Syncgroup struct { |
| Id wire.Id // the relative syncgroup Id chosen by app |
| SpecVersion string // version on syncgroup spec for concurrency control |
| Spec wire.SyncgroupSpec // app-given specification |
| Creator string // Creator's Vanadium name |
| DbId wire.Id // Globally unique database id |
| Status SyncgroupStatus // Status of the syncgroup |
| Joiners map[string]SyncgroupMemberState // map of joiners to their metadata |
| } |
| |
| // SyncgroupMemberState contains information about a joiner and the internal bookkeeping |
| // state required for resolving conflicts on this joiner's join/leave activity. |
| type SyncgroupMemberState struct { |
| // Timestamp of when the member last joined/left the syncgroup. This timestamp is updated |
| // even when an existing member rejoins a syncgroup. Represented as Unix time. |
| WhenUpdated int64 |
| |
| // If set then this record indicates that this member has left the group. The SyncgroupMember |
| // entry is retained after a delete so that it can be used during conflict resolution, when |
| // one node indicates that the member has left the group and another says that the member |
| // is still in the group. |
| HasLeft bool |
| |
| // Information supplied when requesting a join. |
| MemberInfo wire.SyncgroupMemberInfo |
| } |
| |
| // CollectionPerms represent the persistent, synced permissions of a Collection. |
| // Existence of CollectionPerms in the store determines existence of the |
| // Collection. |
| // Note: Since CollectionPerms is synced and conflict resolved, the sync |
| // protocol needs to be aware of it. Any potential additions to synced |
| // Collection metadata should be written to a separate, synced key prefix, |
| // written in the same transaction with CollectionPerms and incorporated into |
| // the sync protocol. All persistent Collection metadata should be synced; |
| // local-only metadata is acceptable only if optional (e.g. stats). |
| type CollectionPerms access.Permissions |
| |
| // DeltaReq contains a request to sync either data or syncgroup metadata for a |
| // Database. |
| type DeltaReq union { |
| Sgs SgDeltaReq |
| Data DataDeltaReq |
| } |
| |
| // DataDeltaReq contains the initiator's genvectors and the set of syncgroups it |
| // is interested in within a database when requesting deltas for that database. |
| type DataDeltaReq struct { |
| DbId wire.Id |
| SgIds set[GroupId] |
| Gvs Knowledge |
| } |
| |
| // SgDeltaReq contains the initiator's genvectors for the syncgroups it is |
| // interested in within a database when requesting deltas for those syncgroups. |
| type SgDeltaReq struct { |
| DbId wire.Id |
| Gvs Knowledge // Contains a genvector per syncgroup. |
| } |
| |
| // DeltaResp contains the responder's genvectors or the missing log records |
| // returned in response to an initiator's request for deltas for a Database. |
| type DeltaResp union { |
| Rec LogRec |
| Gvs Knowledge |
| } |
| |
| // DeltaFinalResp contains the data returned at the end of a GetDeltas call. |
| type DeltaFinalResp struct { |
| SgPriorities SgPriorities |
| } |
| |
| // ChunkHash contains the hash of a chunk that is part of a blob's recipe. |
| type ChunkHash struct { |
| Hash []byte |
| } |
| |
| // ChunkData contains the data of a chunk. |
| type ChunkData struct { |
| Data []byte |
| } |
| |
| // TimeReq contains the send timestamp from the requester. |
| type TimeReq struct { |
| SendTs time.Time |
| } |
| |
| // TimeResp contains information needed by the requester to estimate the |
| // difference between the two vclocks and to decide whether to incorporate the |
| // peer's vclock data. |
| type TimeResp struct { |
| OrigTs time.Time // when we sent request |
| RecvTs time.Time // when peer received request |
| SendTs time.Time // when peer sent response |
| |
| // NTP server timestamp from the most recent NTP sync, or zero value if none. |
| // Note, the NTP sync may have been performed by some peer device. |
| LastNtpTs time.Time |
| |
| // Number of reboots since last NTP sync, accumulated across all hops of p2p |
| // clock sync. |
| NumReboots uint16 |
| |
| // Number of sync hops between peer's device and its source of LastNtpTs. |
| NumHops uint16 |
| } |
| |
| // A SgPriority represents data used to decide whether to transfer blob ownership |
| // between two devices. |
| type SgPriority struct { |
| DevType int32 // device type (BlobDevTypeServer, BlobDevTypeNormal, BlobDevTypeLeaf) |
| Distance float32 // mean number of hops from a server-quality member of the syncgroup |
| ServerTime time.Time // when data from a server-quality member reached this device |
| } |
| |
| // A SgPriorities maps syncgroup IDs to SgPriority structures. It is sent and |
| // received in GetDeltas calls to allow the participants to assess who has |
| // higher priorities for keeping blobs. |
| type SgPriorities map[GroupId]SgPriority |
| |
| // A BlobSharesBySyncgroup maps syncgroup IDs to integer share numbers that a |
| // syncbase instance may have for a blob. |
| type BlobSharesBySyncgroup map[GroupId]int32 |
| |
| // A LocationData is the information known about a particular location in a Signpost. |
| // TODO(m3b): Include mount table information to allow the location to be found. |
| type LocationData struct { |
| WhenSeen time.Time // most recent time when blob thought to have been at location |
| IsProxy bool // whether the location is a likely proxy to another syncgroup |
| IsServer bool // whether the location is a server that may be revealed outside its syncgroup |
| } |
| |
| // A PeerToLocationDataMap is a map from syncbase peer names to LocationData structures. |
| type PeerToLocationDataMap map[string]LocationData |
| |
| // A Signpost is a hint to syncbase of the device on which a blob may be found. |
| // It represents the data known about a blob even when the blob itself is not |
| // present on the device. |
| type Signpost struct { |
| Locations PeerToLocationDataMap // Maps name of syncbase that probably has the blob to a LocationData |
| SgIds set[GroupId] // SyncGroups through which the BlobRef was learned. |
| FetchAttempts uint32 // Number of attempts made to fetch the blob. |
| } |