| // 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 ( |
| wire "v.io/v23/services/syncbase" |
| "v.io/v23/security/access" |
| ) |
| |
| // Sync defines methods for data exchange between Syncbases. |
| // TODO(hpucha): Flesh this out further. |
| type Sync interface { |
| // GetTime returns metadata related to the Syncbase virtual clock, including |
| // system clock values, last NTP timestamp, num reboots, etc. |
| GetTime(req TimeReq, initiator string) (TimeResp | error) |
| |
| // GetDeltas returns the responder's current generation vectors and all |
| // the missing log records when compared to the initiator's generation |
| // vectors for one Database for either syncgroup metadata or data. |
| // The final result (in DeltaFinalResp) currently includes the |
| // syncgroup priorities for blob ownership for the server. |
| GetDeltas(req DeltaReq, initiator string) stream<_, DeltaResp> (DeltaFinalResp | error) {access.Read} |
| |
| // Syncgroup-related methods. |
| |
| // PublishSyncgroup is invoked on the syncgroup name (typically served |
| // by a "central" peer) to publish the syncgroup. It takes the name of |
| // Syncbase doing the publishing (the publisher) and returns the name |
| // of the Syncbase where the syncgroup is published (the publishee). |
| // This allows the publisher and the publishee to learn of each other. |
| // When a syncgroup is published, the publishee is given the syncgroup |
| // metadata, its current version at the publisher, and the current |
| // syncgroup generation vector. The generation vector serves as a |
| // checkpoint at the time of publishing. The publishing proceeds |
| // asynchronously, and the publishee learns the syncgroup history |
| // through the routine p2p sync process and determines when it has |
| // caught up to the level of knowledge at the time of publishing using |
| // the checkpointed generation vector. Until that point, the publishee |
| // locally deems the syncgroup to be in a pending state and does not |
| // mutate it. Thus it locally rejects syncgroup joins or updates to |
| // its spec until it is caught up on the syncgroup history. |
| PublishSyncgroup(publisher string, sg Syncgroup, version string, genvec GenVector) (string | error) {access.Write} |
| |
| // JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's |
| // Syncbase on a syncgroup admin. It checks whether the requestor is |
| // allowed to join the named syncgroup, and if so, adds the requestor to |
| // the syncgroup. It returns a copy of the updated syncgroup metadata, |
| // its version, and the syncgroup generation vector at the time of the |
| // join. Similar to the PublishSyncgroup scenario, the joiner at that |
| // point does not have the syncgroup history and locally deems it to be |
| // in a pending state and does not mutate it. This means it rejects |
| // local updates to the syncgroup spec or, if it were also an admin on |
| // the syncgroup, it would reject syncgroup joins until it is caught up |
| // on the syncgroup history through p2p sync. |
| JoinSyncgroupAtAdmin(dbId wire.Id, sgId wire.Id, joinerName string, myInfo wire.SyncgroupMemberInfo) (sg Syncgroup, version string, genvec GenVector | error) {access.Read} |
| |
| // BlobSync methods. |
| |
| // HaveBlob verifies that the peer has the requested blob, and if |
| // present, returns its size. Otherwise, it returns -1, and the location |
| // hints (the Signpost) that the peer has for the blob, filtered to |
| // include only data the caller is permitted to see: |
| // + Device D reveals a syncgroup SG to the caller C iff |
| // - D is in SG, and |
| // - SG is in the Signpost, and |
| // - at least one of: |
| // - SG is not private, or |
| // - C has permission to join SG. |
| // + Device D reveals a location hint L to caller C iff |
| // there is a syncgroup SG such that |
| // - D is in SG, and |
| // - SG is in the Signpost, and |
| // - L is in SG, and |
| // - at least one of: |
| // - SG is not private, or |
| // - C has permission to join SG, or |
| // - L is a blob server in SG. |
| HaveBlob(br wire.BlobRef) (size int64, signpost Signpost | error) |
| |
| // FetchBlob fetches the requested blob. |
| // It returns a number of blob ownership shares that the server hopes |
| // the client will accept using the AcceptedBlobOwnership() call. |
| FetchBlob(br wire.BlobRef, mySgPriorities SgPriorities) stream<_, []byte> (shares BlobSharesBySyncgroup | error) |
| |
| // Methods for incremental blob transfer. The transfer starts with the |
| // receiver making a FetchBlobRecipe call to the sender for a given |
| // BlobRef. The sender, in turn, sends the chunk hashes of all the |
| // chunks that make up the requested blob (blob recipe). The receiver |
| // looks up the chunk hashes in its local blob store, and identifies the |
| // missing ones. The receiver then fetches the missing chunks using a |
| // FetchChunks call from the sender. Finally, the receiver finishes the |
| // blob fetch by combining the chunks obtained over the network with the |
| // already available local chunks as per the blob recipe. |
| // callerName is the syncbase Id of the caller, expressed as a string. |
| // FetchBlobRecipe returns a number of blob ownership shares that the |
| // server hopes the client will accept for each syncgroup using the |
| // AcceptedBlobOwnership() call. |
| FetchBlobRecipe(br wire.BlobRef, callerName string, mySgPriorities SgPriorities) stream<_, ChunkHash> (shares BlobSharesBySyncgroup | error) |
| FetchChunks() stream<ChunkHash, ChunkData> error |
| |
| // RequestTakeBlob indicates that the caller wishes the server to take |
| // some blob ownership shares for various syncgroups for the specified blob. |
| // If the server chooses to act on the request, it may call FetchBlob/FetchBlobRecipe, |
| // and ultimately AcceptedBlobOwnership(). |
| // callerName is the syncbase Id of the caller, expressed as a string. |
| RequestTakeBlob(br wire.BlobRef, callerName string, shares BlobSharesBySyncgroup) error |
| |
| // AcceptedBlobOwnership tells the server that the client callerName (a |
| // syncbase Id expressed as a string) has accepted blob ownership of a |
| // specified number of shares for blob br. The server may decrement |
| // its share count by up to this number. It is safe for the server to |
| // decrement its share count by fewer than the number of shares another |
| // device has taken responsibility for, but unsafe to decrement it by |
| // more than that that number. It returns a hint as to whether the |
| // server is likely to keep the blob itself, plus its syncbase Id |
| // expressed as a string. |
| AcceptedBlobOwnership(br wire.BlobRef, callerName string, shares BlobSharesBySyncgroup) (serverName string, keepingBlob bool | error) |
| } |
| |
| // TODO(ivanpi): Some methods are missing additional parameter handling ({:_}). |
| error ( |
| DupSyncgroupPublish(sgId wire.Id) {"en": "duplicate publish on syncgroup: {sgId}"} |
| ConnFail() {"en": "connection to peer failed{:_}"} |
| BrokenCrConnection() {"en": "CrConnection stream to client does not exist or is broken"} |
| DbOffline(dbId wire.Id) {"en": "database {dbId} is offline and cannot be synced{:_}"} |
| GetTimeFailed() {"en": "GetTime failed{:_}"} |
| NotAdmin() {"en": "not an admin of the syncgroup"} |
| ) |