Artifact f14b94f4ce60925b295779fe897b036e085897b4c869011421eaa6c03df8fed8:
- File
internal/sync/observer.go
— part of check-in
[f5744359d3]
at
2026-04-19 16:30:54
on branch trunk
— Initial open source release
libfossil is a pure-Go implementation of the Fossil SCM, reading and writing the same .fossil SQLite repository format as upstream Fossil.
This is the first public release of code that previously lived in a private repository. The module path is github.com/danmestas/libfossil and the binary is named libfossil to avoid $PATH collisions with upstream fossil.
Included: - Repo lifecycle (create, clone), checkout/checkin, timeline, merge, diff, annotate, shun, tag, branch, bisect, stash, undo/redo - Sync-over-HTTP protocol (client and handler) - Two SQLite drivers: modernc (pure Go, default) and ncruces (wasm-capable) - Observer interfaces (SyncObserver, CheckoutObserver) with an optional OpenTelemetry implementation in observer/otel (separate submodule) - Deterministic simulation testing harness with BUGGIFY fault injection - Kong-based embeddable CLI under cli/ and a standalone binary under cmd/libfossil/ (user: [email protected], size: 3698) [annotate] [blame] [check-ins using]
package sync import "context" // SessionStart describes the beginning of a sync or clone operation. type SessionStart struct { Operation string // "sync" or "clone" Push, Pull bool UV bool ProjectCode string PeerID string // identifies the leaf agent instance } // SessionEnd describes the result of a sync or clone operation. type SessionEnd struct { Operation string Rounds int FilesSent, FilesRecvd int UVFilesSent, UVFilesRecvd int UVGimmesSent int BytesSent, BytesRecvd int64 ProjectCode string Errors []string } // RoundStats reports per-round activity for observer callbacks. // Value type — no allocations on the nop path. type RoundStats struct { FilesSent int FilesReceived int GimmesSent int IgotsSent int BytesSent int64 BytesReceived int64 } // HandleStart describes the beginning of a server-side sync request. type HandleStart struct { Operation string // "sync" or "clone" ProjectCode string RemoteAddr string } // HandleEnd describes the result of a server-side sync request. type HandleEnd struct { CardsProcessed int FilesSent int FilesReceived int Err error } // TableSyncStart describes the beginning of a table sync operation. type TableSyncStart struct { Table string LocalRows int } // TableSyncEnd describes the result of a table sync operation. type TableSyncEnd struct { Table string Sent int Received int } // Observer receives lifecycle callbacks during sync and clone operations. // A single Observer instance may be shared across multiple concurrent sessions. // Pass nil for no-op default. // // Performance: nopObserver implements all methods as empty functions. // The only cost on the hot path is one indirect call per invocation (~2ns). type Observer interface { // Client-side session lifecycle. Started(ctx context.Context, info SessionStart) context.Context RoundStarted(ctx context.Context, round int) context.Context RoundCompleted(ctx context.Context, round int, stats RoundStats) Completed(ctx context.Context, info SessionEnd, err error) // Per-error recording — called on individual protocol errors. Error(ctx context.Context, err error) // Server-side request lifecycle. HandleStarted(ctx context.Context, info HandleStart) context.Context HandleCompleted(ctx context.Context, info HandleEnd) // Table sync lifecycle. TableSyncStarted(ctx context.Context, info TableSyncStart) TableSyncCompleted(ctx context.Context, info TableSyncEnd) } // nopObserver is the default observer that does nothing. type nopObserver struct{} func (nopObserver) Started(ctx context.Context, _ SessionStart) context.Context { return ctx } func (nopObserver) RoundStarted(ctx context.Context, _ int) context.Context { return ctx } func (nopObserver) RoundCompleted(_ context.Context, _ int, _ RoundStats) {} func (nopObserver) Completed(_ context.Context, _ SessionEnd, _ error) {} func (nopObserver) Error(_ context.Context, _ error) {} func (nopObserver) HandleStarted(ctx context.Context, _ HandleStart) context.Context { return ctx } func (nopObserver) HandleCompleted(_ context.Context, _ HandleEnd) {} func (nopObserver) TableSyncStarted(_ context.Context, _ TableSyncStart) {} func (nopObserver) TableSyncCompleted(_ context.Context, _ TableSyncEnd) {} // resolveObserver returns obs if non-nil, otherwise nopObserver{}. func resolveObserver(obs Observer) Observer { if obs == nil { return nopObserver{} } return obs }