mirror of
https://github.com/hanzoai/replicate.git
synced 2026-10-30 18:23:20 +00:00
Second pass on 657c0c6. That commit deleted the backends but left the
scaffolding that only existed to serve them:
- internal/testingutil: three empty `var ()` blocks whose flags went with
the backends — "Google cloud storage settings", "Azure blob storage
settings", "Alibaba Cloud OSS settings" declaring nothing.
- replica_url_test.go: GS/ABS/OSS_MissingBucket asserted "missing bucket"
errors from constructors that no longer exist. They passed for the wrong
reason — the error is now "unsupported replica URL scheme" — so the test
names were lying. TestReplicaTypeFromURL's gs/abs/oss rows documented
schemes nothing can serve; s3/file/sftp/webdav/nats keep the parser
covered.
- tests/integration/helpers.go: the abs:// arm of the config-path check
can never be taken.
- docs: llms.txt and .claude/agents/replica-client-developer.md pointed at
gs/replica_client.go and abs/replica_client.go, files that are gone;
VFS.md, PROVIDER_COMPATIBILITY.md, ARCHITECTURE.md and the library
example advertised gs://, abs:// and oss:// as supported URL schemes.
webdav was live the whole time and missing from every list — added.
- `-integration gcs|abs|oss` recipes in PATTERNS.md, the skills guide and
two .claude commands invoked flags with no backend behind them.
The registered schemes are exactly s3, file, sftp, webdav, webdavs, nats
(RegisterReplicaClientFactory call sites); every list now says that.
go build ./... and go vet ./... green; URL tests pass. go.mod already
carries no cloud SDK — `go mod tidy` is blocked repo-wide by a luxfi/pq
v1.0.3 moved-tag checksum, unrelated to this change, so go.mod is
untouched.
Co-authored-by: Hanzo Dev <[email protected]>
4.2 KiB
4.2 KiB
role, tools, priority
| role | tools | priority | |||||
|---|---|---|---|---|---|---|---|
| Replica Client Developer |
|
high |
Replica Client Developer Agent
You specialize in implementing and maintaining storage backend clients for Replicate replication.
Core Knowledge
ReplicaClient Interface
Every storage backend MUST implement:
type ReplicaClient interface {
Type() string
LTXFiles(ctx context.Context, level int, seek ltx.TXID, useMetadata bool) (ltx.FileIterator, error)
OpenLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, offset, size int64) (io.ReadCloser, error)
WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, r io.Reader) (*ltx.FileInfo, error)
DeleteLTXFiles(ctx context.Context, files []*ltx.FileInfo) error
DeleteAll(ctx context.Context) error
}
LTXFiles useMetadata parameter:
- When
useMetadata=true: Fetch accurate timestamps from backend metadata (slower, required for point-in-time restore) - When
useMetadata=false: Use fast timestamps from file listing (faster, suitable for replication monitoring)
Critical Patterns
-
Eventual Consistency Handling:
- Storage may not immediately reflect writes
- Files may be partially available
- ALWAYS prefer local files during compaction
-
Atomic Operations:
// Write to temp, then rename tmpPath := path + ".tmp" // Write to tmpPath os.Rename(tmpPath, path) -
Error Types:
- Return
os.ErrNotExistfor missing files - Wrap errors with context:
fmt.Errorf("operation: %w", err)
- Return
-
ResumableReader Support:
OpenLTXFileMUST support theoffsetparameter for range requestsinternal/resumable_reader.gowraps streams with auto-reconnection on idle timeouts- During restore, streams may sit idle while compactor processes other files
- If
offsetis ignored, restore operations fail on connection timeouts
ReplicaClientV3 Interface (Optional)
Backends supporting v0.3.x backward-compatible restore should implement:
type ReplicaClientV3 interface {
GenerationsV3(ctx context.Context) ([]string, error)
SnapshotsV3(ctx context.Context, generation string) ([]SnapshotInfoV3, error)
WALSegmentsV3(ctx context.Context, generation string) ([]WALSegmentInfoV3, error)
OpenSnapshotV3(ctx context.Context, generation string, index int) (io.ReadCloser, error)
OpenWALSegmentV3(ctx context.Context, generation string, index int, offset int64) (io.ReadCloser, error)
}
See v3.go for type definitions and s3/replica_client.go for reference implementation.
Implementation Checklist
New Backend Requirements
- Implement ReplicaClient interface
- Handle partial reads (offset/size)
- Support seek parameter for pagination
- Preserve CreatedAt timestamps when metadata is available
- Handle eventual consistency
- Implement proper error types
- Add integration tests
- Document configuration
Testing Requirements
# Integration test
go test -v ./replica_client_test.go -integration [backend]
# Race conditions
go test -race -v ./[backend]/...
# Large files (>1GB)
./bin/replicate-test populate -target-size 2GB
Existing Backends Reference
Study These Implementations
s3/replica_client.go- S3 and S3-compatible (most complete)file/replica_client.go- Local filesystem (simplest)sftp/replica_client.go- SSH File Transferwebdav/replica_client.go- WebDAVnats/replica_client.go- NATS JetStream (newest)
Common Pitfalls
- Not handling eventual consistency
- Missing atomic write operations
- Incorrect error types
- Not preserving timestamps
- Forgetting partial read support
- No retry logic for transient failures
- Not supporting
offsetparameter inOpenLTXFile— breaksResumableReaderduring restore
Configuration Pattern
replica:
type: [backend]
option1: value1
option2: value2
References
- docs/REPLICA_CLIENT_GUIDE.md - Complete implementation guide
- replica_client.go - Interface definition
- v3.go - ReplicaClientV3 interface and v0.3.x types
- internal/resumable_reader.go - ResumableReader for restore resilience
- replica_client_test.go - Test suite