You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.1 KiB
129 lines
3.1 KiB
//go:build !(js && wasm) |
|
|
|
package sync |
|
|
|
import ( |
|
"context" |
|
"sort" |
|
"sync" |
|
|
|
"lol.mleku.dev/errorf" |
|
"next.orly.dev/pkg/database" |
|
) |
|
|
|
// DriverFactory is the signature for sync driver factory functions. |
|
type DriverFactory func(ctx context.Context, db database.Database, cfg *DriverConfig) (Service, error) |
|
|
|
// DriverConfig holds configuration for sync drivers. |
|
type DriverConfig struct { |
|
// Common settings |
|
LogLevel string |
|
|
|
// Negentropy-specific settings |
|
TargetRelays []string |
|
Filter string |
|
SyncInterval string |
|
BatchSize int |
|
|
|
// Cluster-specific settings |
|
AdminNpubs []string |
|
PropagatePrivilegedEvents bool |
|
PollInterval string |
|
|
|
// Distributed-specific settings |
|
NodeID string |
|
RelayURL string |
|
Peers []string |
|
|
|
// Relay group settings |
|
RelayGroups []string |
|
} |
|
|
|
// DriverInfo contains metadata about a registered sync driver. |
|
type DriverInfo struct { |
|
Name string |
|
Description string |
|
Factory DriverFactory |
|
} |
|
|
|
// Service is the interface that sync drivers must implement. |
|
type Service interface { |
|
// Start begins the sync service |
|
Start() error |
|
// Stop stops the sync service |
|
Stop() error |
|
// Type returns the service type name |
|
Type() string |
|
} |
|
|
|
var ( |
|
driversMu sync.RWMutex |
|
drivers = make(map[string]*DriverInfo) |
|
) |
|
|
|
// RegisterDriver registers a sync driver with the given name and factory. |
|
// This is typically called from init() in the driver package. |
|
func RegisterDriver(name, description string, factory DriverFactory) { |
|
driversMu.Lock() |
|
defer driversMu.Unlock() |
|
drivers[name] = &DriverInfo{ |
|
Name: name, |
|
Description: description, |
|
Factory: factory, |
|
} |
|
} |
|
|
|
// GetDriver returns the factory for the named driver, or nil if not found. |
|
func GetDriver(name string) DriverFactory { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
if info, ok := drivers[name]; ok { |
|
return info.Factory |
|
} |
|
return nil |
|
} |
|
|
|
// HasDriver returns true if the named driver is registered. |
|
func HasDriver(name string) bool { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
_, ok := drivers[name] |
|
return ok |
|
} |
|
|
|
// ListDrivers returns a sorted list of registered driver names. |
|
func ListDrivers() []string { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
names := make([]string, 0, len(drivers)) |
|
for name := range drivers { |
|
names = append(names, name) |
|
} |
|
sort.Strings(names) |
|
return names |
|
} |
|
|
|
// ListDriversWithInfo returns information about all registered drivers. |
|
func ListDriversWithInfo() []*DriverInfo { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
infos := make([]*DriverInfo, 0, len(drivers)) |
|
for _, info := range drivers { |
|
infos = append(infos, info) |
|
} |
|
// Sort by name for consistent output |
|
sort.Slice(infos, func(i, j int) bool { |
|
return infos[i].Name < infos[j].Name |
|
}) |
|
return infos |
|
} |
|
|
|
// NewFromDriver creates a sync service using the named driver. |
|
// Returns an error if the driver is not registered. |
|
func NewFromDriver(ctx context.Context, driverName string, db database.Database, cfg *DriverConfig) (Service, error) { |
|
factory := GetDriver(driverName) |
|
if factory == nil { |
|
return nil, errorf.E("sync driver %q not available; registered: %v", driverName, ListDrivers()) |
|
} |
|
return factory(ctx, db, cfg) |
|
}
|
|
|