feat(store): add PostgreSQL-backed config store with env selection

This commit is contained in:
hkfires
2025-10-13 21:05:43 +08:00
parent 32a8102d71
commit 5123cfd47e
6 changed files with 755 additions and 28 deletions

View File

@@ -29,10 +29,10 @@ import (
log "github.com/sirupsen/logrus"
)
// gitCommitter captures the subset of git-backed token store capabilities used by the watcher.
type gitCommitter interface {
CommitConfig(ctx context.Context) error
CommitPaths(ctx context.Context, message string, paths ...string) error
// storePersister captures persistence-capable token store methods used by the watcher.
type storePersister interface {
PersistConfig(ctx context.Context) error
PersistAuthFiles(ctx context.Context, message string, paths ...string) error
}
// Watcher manages file watching for configuration and authentication files
@@ -52,7 +52,7 @@ type Watcher struct {
pendingUpdates map[string]AuthUpdate
pendingOrder []string
dispatchCancel context.CancelFunc
gitCommitter gitCommitter
storePersister storePersister
oldConfigYaml []byte
}
@@ -126,9 +126,9 @@ func NewWatcher(configPath, authDir string, reloadCallback func(*config.Config))
}
w.dispatchCond = sync.NewCond(&w.dispatchMu)
if store := sdkAuth.GetTokenStore(); store != nil {
if committer, ok := store.(gitCommitter); ok {
w.gitCommitter = committer
log.Debug("gitstore mode detected; watcher will commit changes to remote repository")
if persister, ok := store.(storePersister); ok {
w.storePersister = persister
log.Debug("persistence-capable token store detected; watcher will propagate persisted changes")
}
}
return w, nil
@@ -345,21 +345,21 @@ func (w *Watcher) stopDispatch() {
w.clientsMutex.Unlock()
}
func (w *Watcher) commitConfigAsync() {
if w == nil || w.gitCommitter == nil {
func (w *Watcher) persistConfigAsync() {
if w == nil || w.storePersister == nil {
return
}
go func() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := w.gitCommitter.CommitConfig(ctx); err != nil {
log.Errorf("failed to commit config change: %v", err)
if err := w.storePersister.PersistConfig(ctx); err != nil {
log.Errorf("failed to persist config change: %v", err)
}
}()
}
func (w *Watcher) commitAuthAsync(message string, paths ...string) {
if w == nil || w.gitCommitter == nil {
func (w *Watcher) persistAuthAsync(message string, paths ...string) {
if w == nil || w.storePersister == nil {
return
}
filtered := make([]string, 0, len(paths))
@@ -374,8 +374,8 @@ func (w *Watcher) commitAuthAsync(message string, paths ...string) {
go func() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := w.gitCommitter.CommitPaths(ctx, message, filtered...); err != nil {
log.Errorf("failed to commit auth changes: %v", err)
if err := w.storePersister.PersistAuthFiles(ctx, message, filtered...); err != nil {
log.Errorf("failed to persist auth changes: %v", err)
}
}()
}
@@ -484,7 +484,7 @@ func (w *Watcher) handleEvent(event fsnotify.Event) {
w.clientsMutex.Lock()
w.lastConfigHash = finalHash
w.clientsMutex.Unlock()
w.commitConfigAsync()
w.persistConfigAsync()
}
return
}
@@ -683,7 +683,7 @@ func (w *Watcher) addOrUpdateClient(path string) {
log.Debugf("triggering server update callback after add/update")
w.reloadCallback(cfg)
}
w.commitAuthAsync(fmt.Sprintf("Sync auth %s", filepath.Base(path)), path)
w.persistAuthAsync(fmt.Sprintf("Sync auth %s", filepath.Base(path)), path)
}
// removeClient handles the removal of a single client.
@@ -701,7 +701,7 @@ func (w *Watcher) removeClient(path string) {
log.Debugf("triggering server update callback after removal")
w.reloadCallback(cfg)
}
w.commitAuthAsync(fmt.Sprintf("Remove auth %s", filepath.Base(path)), path)
w.persistAuthAsync(fmt.Sprintf("Remove auth %s", filepath.Base(path)), path)
}
// SnapshotCombinedClients returns a snapshot of current combined clients.