mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"bugulma/backend/internal/domain"
|
|
)
|
|
|
|
type MaintenanceSetting struct {
|
|
Enabled bool `json:"enabled"`
|
|
Message string `json:"message"`
|
|
AllowedIPs []string `json:"allowed_ips,omitempty"`
|
|
}
|
|
|
|
type SettingsService struct {
|
|
repo domain.SystemSettingsRepository
|
|
// caching
|
|
cacheTTL time.Duration
|
|
cacheMutex sync.RWMutex
|
|
cachedMaintenance *MaintenanceSetting
|
|
cacheExpiry time.Time
|
|
}
|
|
|
|
func NewSettingsService(repo domain.SystemSettingsRepository) *SettingsService {
|
|
return &SettingsService{repo: repo, cacheTTL: 5 * time.Second}
|
|
}
|
|
|
|
func (s *SettingsService) GetMaintenance(ctx context.Context) (*MaintenanceSetting, error) {
|
|
m, err := s.repo.Get(ctx, "maintenance")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get maintenance: %w", err)
|
|
}
|
|
if m == nil {
|
|
return &MaintenanceSetting{Enabled: false, Message: ""}, nil
|
|
}
|
|
enabled, _ := m["enabled"].(bool)
|
|
msg, _ := m["message"].(string)
|
|
// allowed_ips may be stored as []interface{} from DB JSON decode
|
|
var allowed []string
|
|
if v, ok := m["allowed_ips"]; ok {
|
|
switch vv := v.(type) {
|
|
case []any:
|
|
for _, it := range vv {
|
|
if s, ok := it.(string); ok {
|
|
allowed = append(allowed, s)
|
|
}
|
|
}
|
|
case []string:
|
|
allowed = vv
|
|
}
|
|
}
|
|
return &MaintenanceSetting{Enabled: enabled, Message: msg, AllowedIPs: allowed}, nil
|
|
}
|
|
|
|
func (s *SettingsService) SetMaintenance(ctx context.Context, in *MaintenanceSetting) error {
|
|
value := map[string]any{"enabled": in.Enabled, "message": in.Message}
|
|
if in.AllowedIPs != nil {
|
|
value["allowed_ips"] = in.AllowedIPs
|
|
}
|
|
if err := s.repo.Set(ctx, "maintenance", value); err != nil {
|
|
return fmt.Errorf("failed to set maintenance: %w", err)
|
|
}
|
|
// Invalidate cache
|
|
s.cacheMutex.Lock()
|
|
s.cachedMaintenance = nil
|
|
s.cacheExpiry = time.Time{}
|
|
s.cacheMutex.Unlock()
|
|
return nil
|
|
}
|
|
|
|
// GetMaintenanceCached returns a cached maintenance setting for low-latency checks.
|
|
// Cache is refreshed after s.cacheTTL.
|
|
func (s *SettingsService) GetMaintenanceCached(ctx context.Context) (*MaintenanceSetting, error) {
|
|
s.cacheMutex.RLock()
|
|
if s.cachedMaintenance != nil && time.Now().Before(s.cacheExpiry) {
|
|
m := s.cachedMaintenance
|
|
s.cacheMutex.RUnlock()
|
|
return m, nil
|
|
}
|
|
s.cacheMutex.RUnlock()
|
|
|
|
// Fetch fresh
|
|
m, err := s.GetMaintenance(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.cacheMutex.Lock()
|
|
s.cachedMaintenance = m
|
|
s.cacheExpiry = time.Now().Add(s.cacheTTL)
|
|
s.cacheMutex.Unlock()
|
|
return m, nil
|
|
}
|