Documentation
¶
Overview ¶
Package sync holds the offline synchronisation context's own entities (offline-sync.md §10): what the server keeps about the devices that synchronise, beside the change log they read.
Index ¶
Constants ¶
const ( PlatformMaxLength = 40 DisplayNameMaxLength = 120 )
The bounds of what a device says about itself (api/openapi.yaml, SyncPullRequest).
Variables ¶
This section is empty.
Functions ¶
func Bound ¶
Bound applies §4.1's rule to a device's clock reading: a reading further than the permitted skew from server time is replaced by a server reading, and the caller is told by how much it was out so that the fact can be logged - the device and the drift, never the content.
Both directions are bounded. A device ahead of the server would outvote everybody for as long as its lead lasted; a device behind would lose every merge it should have won, which is quieter and just as wrong. The replacement keeps the device's identifier: the reading is still the device's act, only its moment is the server's.
Types ¶
type Contact ¶
type Contact struct {
DeviceID shared.ID
AccountID shared.ID
CredentialID shared.ID
// Platform and DisplayName are optional: empty leaves what the row holds.
Platform string
DisplayName string
// LastSeq is the position after the page, zero when the contact did not finish one.
LastSeq int64
Now time.Time
}
Contact is what one pull or push says about the device making it.
func (Contact) Validate ¶
Validate bounds what a client says about its device, and normalises it: trimmed, and refused when longer than the contract allows. The identifier is required and has to be one the client minted - a UUIDv7 - because it is what every change of the device is later attributed to (offline-sync.md §9, requirement 1).
type Device ¶
type Device struct {
ID shared.ID
TenantID shared.ID
AccountID shared.ID
// Platform and DisplayName are what the device said about itself, last value standing. Both
// are personal data - a name somebody typed, a class of machine they own - and travel to the
// device list and nowhere else (rule 10).
Platform string
DisplayName string
// LastSeq is where the device last stood in the log: the position of the last page it
// pulled. Zero for a device that has never finished a page.
LastSeq int64
LastSeenAt time.Time
CreatedAt time.Time
// Blocked is a forgotten device: every contact from the identifier is refused until the
// sweep removes the row and the client mints a new identifier. The row stays rather than
// going at once, so that the list shows what a person ended and so that an identifier cannot
// register afresh while somebody still holds the old one.
Blocked bool
// CredentialID is the credential of the request that last touched the device - a session,
// for a client that signed in; a token's identifier for one that did not. Forgetting the
// device revokes it where it is a session and does nothing where it is not (migration 0082).
CredentialID shared.ID
}
Device is one installation of a client on one machine, registered to one account (offline-sync.md §6, §10). The identifier is the client's - minted once, kept in its own store, sent with every pull and push - and it is what a push's `op_id`s and a change's `device_id` name.
type MutationKind ¶
type MutationKind string
MutationKind is what a device did offline, in the contract's words (api/openapi.yaml, SyncMutation.kind).
const ( ItemCreate MutationKind = "ITEM_CREATE" ItemPatch MutationKind = "ITEM_PATCH" ItemDelete MutationKind = "ITEM_DELETE" SetAdd MutationKind = "SET_ADD" SetRemove MutationKind = "SET_REMOVE" Move MutationKind = "MOVE" CommentAdd MutationKind = "COMMENT_ADD" )
func MutationKinds ¶
func MutationKinds() []MutationKind
MutationKinds is the closed set, in the contract's order.
func (MutationKind) Valid ¶
func (k MutationKind) Valid() bool
Valid reports whether the kind is one the contract names.
type ResultKind ¶
type ResultKind string
ResultKind is what became of one mutation (offline-sync.md §3.2).
const ( // Applied: every field the device sent won, and nothing else had moved since its base. Applied ResultKind = "APPLIED" // Merged: the server's copy had moved; some of what the device sent won and some lost, and // the result carries the server's state so the device adopts it. Merged ResultKind = "MERGED" // Rejected: the mutation could not be applied at all - the use case refused it, the entry is // gone, the device may not - and the result carries the code. Rejected ResultKind = "REJECTED" // Conflict: a free-text field lost, and the displaced version is preserved as a comment; the // result carries both values so a client can offer the choice (offline-sync.md §5). Conflict ResultKind = "CONFLICT" )