Documentation
¶
Index ¶
- Constants
- Variables
- func HeartbeatCapabilities(cfg *config.Instance) map[string]any
- func IsPlaySyncDisabledError(err error) bool
- func IsRateLimitedError(err error) bool
- func IsRemoteUnlinkedError(err error) bool
- func LibrarySyncCapability(cfg *config.Instance) map[string]any
- func RemoteAvailabilityNeedsRefresh(now time.Time, status *models.BackupStatusEntry) bool
- type APIError
- type BusyError
- type Coordinator
- type FileRef
- type Info
- type Lease
- type ListInfo
- type Manager
- func (m *Manager) Create(ctx context.Context) (Info, error)
- func (m *Manager) Delete(ctx context.Context, name string) error
- func (m *Manager) Inspect(ctx context.Context, name string) (Info, error)
- func (m *Manager) List() ([]ListInfo, error)
- func (m *Manager) ListRemote(ctx context.Context) (RemoteListInfo, error)
- func (m *Manager) MarkRemoteLinked()
- func (m *Manager) MarkRemoteUnlinked()
- func (m *Manager) NewOnlineClient(baseURL string) (*OnlineClient, error)
- func (m *Manager) NotifyScheduleStale()
- func (m *Manager) RecoverInterruptedRuns()
- func (m *Manager) RecoverRestore(ctx context.Context) error
- func (m *Manager) RefreshRemoteAvailability(ctx context.Context) (string, error)
- func (m *Manager) RefreshRemoteAvailabilityIfStale(ctx context.Context) (string, error)
- func (m *Manager) RefreshRemoteAvailabilityIfStaleAsync()
- func (m *Manager) Restore(ctx context.Context, name string) (RestoreInfo, error)
- func (m *Manager) RestoreRemote(ctx context.Context, id string) (RemoteRestoreInfo, error)
- func (m *Manager) RevokeRemoteLink(ctx context.Context) error
- func (m *Manager) RunRemote(ctx context.Context, backupType string) (RemoteRunInfo, error)
- func (m *Manager) SendCapabilityHeartbeat(ctx context.Context) error
- func (m *Manager) SendHeartbeat(ctx context.Context) error
- func (m *Manager) Status() models.BackupStatusResponse
- func (m *Manager) SyncPlayHistory(ctx context.Context) (PlaySyncInfo, error)
- func (m *Manager) TrackScheduleStale(now time.Time, active bool, staleAfter time.Duration) bool
- func (m *Manager) WithActiveMedia(activeMedia func() *models.ActiveMedia) *Manager
- func (m *Manager) WithCoordinator(coordinator *Coordinator) *Manager
- func (m *Manager) WithInbox(inbox *inboxservice.Service) *Manager
- func (m *Manager) WithPauser(pauser *syncutil.Pauser) *Manager
- func (m *Manager) WithRateLimitWaits(minWait, defaultWait, maxWait time.Duration) *Manager
- func (m *Manager) WithRestoreGate(restoreGate func() (func(bool), error)) *Manager
- type Manifest
- type OnlineClient
- func (o *OnlineClient) BaseURL() string
- func (o *OnlineClient) CredentialTag() string
- func (o *OnlineClient) DoBytes(ctx context.Context, method, path string, body []byte, headers http.Header, ...) error
- func (o *OnlineClient) DoJSON(ctx context.Context, method, path string, body, out any) error
- func (o *OnlineClient) RetryRateLimited(ctx context.Context, op func() error) error
- type OperationKind
- type OperationMode
- type PlaySyncInfo
- type RemoteBackupInfo
- type RemoteBackupSourceDevice
- type RemoteListInfo
- type RemoteRestoreInfo
- type RemoteRunInfo
- type RestoreInfo
Constants ¶
const ( CategoryZaparoo = "zaparoo" CategorySettings = "settings" CategoryInputs = "inputs" CategorySaves = "saves" CategorySavestates = "savestates" StatusNever = "never" StatusRunning = "running" StatusSuccess = "success" StatusPartial = "partial" StatusFailed = "failed" IntegrityUnchecked = "unchecked" IntegrityValid = "valid" RemoteAvailabilityUnknown = "unknown" RemoteAvailabilityAvailable = "available" )
const ( OperationLocalCreate = backupcoordinator.OperationLocalCreate OperationLocalInspect = backupcoordinator.OperationLocalInspect OperationLocalDelete = backupcoordinator.OperationLocalDelete OperationLocalRestore = backupcoordinator.OperationLocalRestore OperationRemoteUpload = backupcoordinator.OperationRemoteUpload OperationRemoteRestore = backupcoordinator.OperationRemoteRestore OperationRecovery = backupcoordinator.OperationRecovery OperationRead = backupcoordinator.OperationRead OperationWrite = backupcoordinator.OperationWrite )
const ( RemoteBackupTypeManual = "manual" RemoteBackupTypeScheduled = "scheduled" )
Remote snapshot types accepted by the server for Core-initiated commits.
Variables ¶
var ( ErrRestoreMediaActive = errors.New("cannot restore backup while media is active") ErrRestoreLaunchInProgress = errors.New("cannot restore backup while media is launching") ErrRestoreRecoveryNeeded = errors.New("backup restore rollback requires recovery") ErrRestoreJournalConflict = errors.New("a pending backup restore transaction exists") )
var ErrCoordinatorStopped = backupcoordinator.ErrStopped
Functions ¶
func HeartbeatCapabilities ¶ added in v2.18.0
HeartbeatCapabilities is the capability document every heartbeat carries: what this Core can do for the linked account, and which optional features the user has turned on.
func IsPlaySyncDisabledError ¶
IsPlaySyncDisabledError reports an expected opt-out or mid-sync disable. Background schedulers use this to keep intentional inactivity quiet while surfacing real upload failures at warning level.
func IsRateLimitedError ¶ added in v2.18.0
IsRateLimitedError reports a request the server kept refusing with a rate limit after every retry.
func IsRemoteUnlinkedError ¶
IsRemoteUnlinkedError reports expected inactivity when no usable online credential exists. Background schedulers use this to avoid warning on devices that have intentionally never linked or have since unlinked.
func LibrarySyncCapability ¶ added in v2.18.0
LibrarySyncCapability is the library_sync entry of the heartbeat capability document. It is always reported, with enabled false while the user has not opted in, so the account can tell a device that turned Library sync off from one whose Core does not support it.
func RemoteAvailabilityNeedsRefresh ¶
func RemoteAvailabilityNeedsRefresh(now time.Time, status *models.BackupStatusEntry) bool
Types ¶
type APIError ¶ added in v2.18.0
type APIError struct {
Code string
Message string
Status int
// contains filtered or unexported fields
}
APIError is an error response from a Zaparoo Online endpoint. Code is the machine-readable error code when the response carried one. A code that backup handles itself also matches that sentinel through errors.Is, and reads as it always has.
func AsAPIError ¶ added in v2.18.0
AsAPIError returns the API error response err carries, if any.
type BusyError ¶
type BusyError = backupcoordinator.BusyError
type Coordinator ¶
type Coordinator = backupcoordinator.Coordinator
func NewCoordinator ¶
func NewCoordinator() *Coordinator
type Info ¶
type Info struct {
CreatedAt time.Time `json:"createdAt"`
Categories map[string]models.BackupCategoryStatus `json:"categories,omitempty"`
Name string `json:"name"`
Path string `json:"path,omitempty"`
Status string `json:"status"`
Integrity string `json:"integrity"`
Error string `json:"error,omitempty"`
Warnings []models.BackupWarning `json:"warnings,omitempty"`
Size int64 `json:"size"`
}
type Lease ¶
type Lease = backupcoordinator.Lease
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
func NewManager ¶
func (*Manager) ListRemote ¶
func (m *Manager) ListRemote(ctx context.Context) (RemoteListInfo, error)
func (*Manager) MarkRemoteLinked ¶
func (m *Manager) MarkRemoteLinked()
MarkRemoteLinked clears a persisted unlinked marker after a successful claim/link, so the status UI reflects the fresh credential immediately.
func (*Manager) MarkRemoteUnlinked ¶
func (m *Manager) MarkRemoteUnlinked()
MarkRemoteUnlinked records that no valid remote credential exists (the token was revoked server-side or removed by logout), so the status UI prompts a re-link and the scheduler stops attempting remote backups.
func (*Manager) NewOnlineClient ¶ added in v2.18.0
func (m *Manager) NewOnlineClient(baseURL string) (*OnlineClient, error)
NewOnlineClient returns a client for the endpoint at baseURL. It fails with an error matching IsRemoteUnlinkedError when the device holds no credential for that endpoint, and a 401 response fails the same way.
func (*Manager) NotifyScheduleStale ¶
func (m *Manager) NotifyScheduleStale()
NotifyScheduleStale posts the deduplicated overdue-backup inbox notice.
func (*Manager) RecoverInterruptedRuns ¶
func (m *Manager) RecoverInterruptedRuns()
RecoverInterruptedRuns converts a persisted "running" status left behind by an interrupted run (power loss, hard shutdown) into a failure. The coordinator lease is in-memory, so at service startup no run can actually be in flight: a lingering "running" is always stale. Recording it as failed makes the scheduler retry on the short failure interval instead of waiting out the full daily/weekly cadence.
func (*Manager) RefreshRemoteAvailability ¶
func (*Manager) RefreshRemoteAvailabilityIfStale ¶
func (*Manager) RefreshRemoteAvailabilityIfStaleAsync ¶
func (m *Manager) RefreshRemoteAvailabilityIfStaleAsync()
RefreshRemoteAvailabilityIfStaleAsync refreshes remote availability in the background when the cached value is past its TTL, so status requests return immediately instead of blocking on a network round trip.
func (*Manager) RestoreRemote ¶
func (*Manager) RevokeRemoteLink ¶
RevokeRemoteLink invalidates the current device on the backup server before Core removes its local bearer. An already-missing or revoked credential is treated as success so local cleanup can finish.
func (*Manager) SendCapabilityHeartbeat ¶ added in v2.17.0
SendCapabilityHeartbeat reports liveness and the complete capability document without coupling callers to backup entitlement checks.
func (*Manager) SendHeartbeat ¶
SendHeartbeat reports liveness (Core version + capabilities) when the device is linked. Callers use it independently of backup runs so "last seen" stays fresh even with remote backup disabled.
func (*Manager) Status ¶
func (m *Manager) Status() models.BackupStatusResponse
func (*Manager) SyncPlayHistory ¶
func (m *Manager) SyncPlayHistory(ctx context.Context) (PlaySyncInfo, error)
SyncPlayHistory uploads every session updated since the server's watermark. The first call after linking is the bulk import of the whole local history; afterwards each pass sends only what changed. A pass is cheap when nothing changed: one watermark GET and one empty local query.
func (*Manager) TrackScheduleStale ¶
TrackScheduleStale maintains the persisted record of when remote backup scheduling became active and reports whether scheduled backups are stale: scheduling active for at least staleAfter with no successful run inside that window. Staleness is only judged against a reliable clock.
func (*Manager) WithActiveMedia ¶
func (m *Manager) WithActiveMedia(activeMedia func() *models.ActiveMedia) *Manager
func (*Manager) WithCoordinator ¶
func (m *Manager) WithCoordinator(coordinator *Coordinator) *Manager
func (*Manager) WithPauser ¶
WithPauser subjects backup work to the shared media pause/throttle policy: file collection, hashing, packing, and uploads checkpoint on the pauser so they yield to a running game the same way media indexing does. A nil pauser (the default) leaves backups unthrottled.
func (*Manager) WithRateLimitWaits ¶ added in v2.18.0
WithRateLimitWaits overrides how long rate-limited requests wait before a retry, for tests that exercise the retry path.
type Manifest ¶
type Manifest struct {
CreatedAt time.Time `json:"createdAt"`
Categories map[string]models.BackupCategoryStatus `json:"categories"`
Warnings []models.BackupWarning `json:"warnings,omitempty"`
Platform string `json:"platform"`
CoreVersion string `json:"coreVersion"`
Files []FileRef `json:"files"`
Version int `json:"version"`
}
type OnlineClient ¶ added in v2.18.0
type OnlineClient struct {
// contains filtered or unexported fields
}
OnlineClient sends authenticated device requests to a Zaparoo Online endpoint for features other than backup. It shares the backup client's credential lookup, device headers, per-request timeouts and rate-limit handling, so every Online feature behaves the same on the wire.
func (*OnlineClient) BaseURL ¶ added in v2.18.0
func (o *OnlineClient) BaseURL() string
BaseURL returns the endpoint the client talks to, without a trailing slash.
func (*OnlineClient) CredentialTag ¶ added in v2.18.0
func (o *OnlineClient) CredentialTag() string
CredentialTag returns a short digest of the device credential, so sync bookkeeping can tell that the device was linked again since it last synced without keeping the credential itself.
func (*OnlineClient) DoBytes ¶ added in v2.18.0
func (o *OnlineClient) DoBytes( ctx context.Context, method, path string, body []byte, headers http.Header, out any, ) error
DoBytes sends body as application/octet-stream with the extra headers, and decodes a successful JSON response into out unless out is nil.
func (*OnlineClient) DoJSON ¶ added in v2.18.0
DoJSON sends body encoded as JSON, or no body when it is nil, and decodes a successful JSON response into out unless out is nil. path may end in a query string.
func (*OnlineClient) RetryRateLimited ¶ added in v2.18.0
func (o *OnlineClient) RetryRateLimited(ctx context.Context, op func() error) error
RetryRateLimited runs op, waiting out and retrying rate-limited responses. The wait honours the server's Retry-After within the client's bounds.
type OperationKind ¶
type OperationKind = backupcoordinator.OperationKind
type OperationMode ¶
type OperationMode = backupcoordinator.OperationMode
type PlaySyncInfo ¶
PlaySyncInfo summarizes one play-history sync pass.
type RemoteBackupInfo ¶
type RemoteBackupInfo struct {
CoreVersion *string `json:"coreVersion,omitempty"`
Platform *string `json:"platform,omitempty"`
VerifiedAt *time.Time `json:"verifiedAt,omitempty"`
RestoredAt *time.Time `json:"restoredAt,omitempty"`
SourceDevice *RemoteBackupSourceDevice `json:"sourceDevice,omitempty"`
Categories map[string]remoteCategorySummary `json:"categories"`
ManifestHash string `json:"manifestHash"`
BackupType string `json:"backupType"`
CreatedAt time.Time `json:"createdAt"`
Manifest json.RawMessage `json:"manifest,omitempty"`
ID string `json:"id"`
SchemaVersion int `json:"schemaVersion"`
SizeBytes int64 `json:"sizeBytes"`
// Incompatible marks snapshots committed with a newer schema version
// than this Core supports: they list fine but refuse to restore.
Incompatible bool `json:"incompatible,omitempty"`
}
RemoteBackupInfo is remote snapshot metadata returned to Core clients.
type RemoteBackupSourceDevice ¶
type RemoteBackupSourceDevice struct {
Platform *string `json:"platform,omitempty"`
ID string `json:"id"`
Name string `json:"name"`
Linked bool `json:"linked"`
Current bool `json:"current"`
}
RemoteBackupSourceDevice identifies the account device that created a snapshot. Current is relative to the device requesting the catalog.
type RemoteListInfo ¶
type RemoteListInfo struct {
Items []RemoteBackupInfo `json:"items"`
StorageUsedBytes int64 `json:"storageUsedBytes"`
StorageQuotaBytes int64 `json:"storageQuotaBytes"`
}
RemoteListInfo contains remote backups and quota usage.
type RemoteRestoreInfo ¶
type RemoteRestoreInfo struct {
PreRestoreBackup *Info `json:"preRestoreBackup,omitempty"`
RestoredFrom RemoteBackupInfo `json:"restoredFrom"`
}
RemoteRestoreInfo describes one completed remote restore.
type RemoteRunInfo ¶
type RemoteRunInfo struct {
Backup RemoteBackupInfo `json:"backup"`
Categories map[string]remoteCategorySummary `json:"categories"`
Warnings []models.BackupWarning `json:"warnings,omitempty"`
UploadedFiles int `json:"uploadedFiles"`
DedupedFiles int `json:"dedupedFiles"`
SkippedFiles int `json:"skippedFiles,omitempty"`
UploadedPacks int `json:"uploadedPacks"`
UploadedBytes int64 `json:"uploadedBytes"`
StorageUsedBytes int64 `json:"storageUsedBytes,omitempty"`
StorageQuotaBytes int64 `json:"storageQuotaBytes,omitempty"`
// NoChanges marks a run whose manifest matched the server's existing
// snapshot: the run succeeded and the content is verified stored, but
// nothing new was uploaded and no new snapshot record was created.
NoChanges bool `json:"noChanges,omitempty"`
}
RemoteRunInfo describes one completed remote backup run.