create_aio
This commit is contained in:
78
internal/filesvc/store.go
Normal file
78
internal/filesvc/store.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package filesvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*** Domain ***/
|
||||
|
||||
type ID = int64
|
||||
|
||||
type File struct {
|
||||
ID ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
// weitere Metadaten optional: Size, Hash, Owner, Tags, ...
|
||||
UpdatedAt int64 `json:"updatedAt"` // UnixNano für LWW
|
||||
Deleted bool `json:"deleted"` // Tombstone für Mesh-Delete
|
||||
}
|
||||
|
||||
/*** Fehler ***/
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("file not found")
|
||||
ErrBadInput = errors.New("bad input")
|
||||
ErrConflict = errors.New("conflict")
|
||||
ErrForbidden = errors.New("forbidden")
|
||||
ErrTransient = errors.New("transient")
|
||||
)
|
||||
|
||||
/*** Basis-API (lokal nutzbar) ***/
|
||||
|
||||
type Store interface {
|
||||
// Lesen & Auflisten
|
||||
Get(ctx context.Context, id ID) (File, error)
|
||||
List(ctx context.Context, next ID, limit int) (items []File, nextOut ID, err error)
|
||||
|
||||
// Mutationen mit LWW-Semantik (UpdatedAt wird intern gesetzt, außer bei ApplyRemote)
|
||||
Create(ctx context.Context, name string) (File, error)
|
||||
Rename(ctx context.Context, id ID, newName string) (File, error)
|
||||
Delete(ctx context.Context, id ID) (File, error)
|
||||
}
|
||||
|
||||
/*** Mesh-Replikation ***/
|
||||
|
||||
type Snapshot struct {
|
||||
Items []File `json:"items"`
|
||||
}
|
||||
|
||||
type Replicable interface {
|
||||
// Snapshot liefert den vollständigen aktuellen Stand (inkl. Tombstones).
|
||||
Snapshot(ctx context.Context) (Snapshot, error)
|
||||
// ApplyRemote wendet LWW an. next-ID wird dabei korrekt fortgeschrieben.
|
||||
ApplyRemote(ctx context.Context, s Snapshot) error
|
||||
}
|
||||
|
||||
/*** Events (optional) ***/
|
||||
|
||||
// ChangeEvent kann genutzt werden, um proaktive Mesh-Pushes zu triggern.
|
||||
// Bei deiner Pull-basierten Anti-Entropy ist es optional.
|
||||
type ChangeEvent struct {
|
||||
At time.Time
|
||||
Item File
|
||||
}
|
||||
|
||||
// Watch gibt Änderungen aus; close(stop) beendet den Stream.
|
||||
// Eine Noop-Implementierung ist erlaubt, wenn Pull-Sync genügt.
|
||||
type Watchable interface {
|
||||
Watch(stop <-chan struct{}) <-chan ChangeEvent
|
||||
}
|
||||
|
||||
/*** Kombiniertes Interface ***/
|
||||
|
||||
type MeshStore interface {
|
||||
Store
|
||||
Replicable
|
||||
Watchable // optional – kann Noop sein
|
||||
}
|
||||
Reference in New Issue
Block a user