hako/internal/archival/archiver/manager.go
2026-01-12 19:35:18 +01:00

133 lines
3.1 KiB
Go

package archiver
import (
"context"
"encoding/json"
"fmt"
"sort"
"sync"
archivalStore "git.nakama.town/fmartingr/hako/internal/archival/store"
)
// Manager manages all registered archivers
type Manager struct {
archivers map[string]Archiver
mu sync.RWMutex
}
// NewManager creates a new archiver manager
func NewManager() *Manager {
return &Manager{
archivers: make(map[string]Archiver),
}
}
// Register registers an archiver
func (m *Manager) Register(archiver Archiver) error {
m.mu.Lock()
defer m.mu.Unlock()
key := archiver.Key()
if _, exists := m.archivers[key]; exists {
return fmt.Errorf("archiver with key %s already registered", key)
}
// Initialize the archiver
if err := archiver.Init(); err != nil {
return fmt.Errorf("failed to initialize archiver %s: %w", key, err)
}
m.archivers[key] = archiver
return nil
}
// GetArchiver retrieves an archiver by key
func (m *Manager) GetArchiver(key string) (Archiver, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
archiver, ok := m.archivers[key]
return archiver, ok
}
// ListEnabled returns all enabled archivers
func (m *Manager) ListEnabled(ctx context.Context) []Archiver {
m.mu.RLock()
defer m.mu.RUnlock()
var enabled []Archiver
for _, archiver := range m.archivers {
if archiver.IsEnabled(ctx) {
enabled = append(enabled, archiver)
}
}
return enabled
}
// List returns all registered archivers
func (m *Manager) List() []Archiver {
m.mu.RLock()
defer m.mu.RUnlock()
var all []Archiver
for _, archiver := range m.archivers {
all = append(all, archiver)
}
return all
}
// ArchiverStatus represents the status of an archiver
type ArchiverStatus struct {
Key string `json:"key"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
DefaultConfig any `json:"default_config"`
}
// GetStatus returns status information for all registered archivers
// If archiverConfigStore is provided, it will return stored configs if available, otherwise default configs
func (m *Manager) GetStatus(ctx context.Context, archiverConfigStore *archivalStore.ArchiverConfigStore) []ArchiverStatus {
m.mu.RLock()
defer m.mu.RUnlock()
var statuses []ArchiverStatus
for _, archiver := range m.archivers {
key := archiver.Key()
var config any
// Try to get stored config if store is provided
if archiverConfigStore != nil {
storedConfig, err := archiverConfigStore.Get(ctx, key)
if err == nil && storedConfig != nil && storedConfig.ConfigJSON != "" {
// Parse stored config JSON
if err := json.Unmarshal([]byte(storedConfig.ConfigJSON), &config); err != nil {
// If parsing fails, fall back to default
config = archiver.GetDefaultConfig()
}
} else {
// No stored config, use default
config = archiver.GetDefaultConfig()
}
} else {
// No store provided, use default
config = archiver.GetDefaultConfig()
}
statuses = append(statuses, ArchiverStatus{
Key: key,
Name: archiver.Name(),
Enabled: archiver.IsEnabled(ctx),
DefaultConfig: config,
})
}
// Sort by name
sort.Slice(statuses, func(i, j int) bool {
return statuses[i].Name < statuses[j].Name
})
return statuses
}