package data import ( "context" "io" "sync" "kra/internal/biz" "kra/internal/conf" datastorage "kra/internal/data/storage" ) type reloadableStorage struct { mu sync.RWMutex current biz.FileStorage } func NewFileStorage(data *Data) (biz.FileStorage, error) { storage, err := buildFileStorage(data.runtime.Admin()) if err != nil { return nil, err } wrapper := &reloadableStorage{current: storage} data.storage = wrapper return wrapper, nil } func buildFileStorage(config *conf.AdminBackend) (biz.FileStorage, error) { return datastorage.New(config) } func (s *reloadableStorage) replace(storage biz.FileStorage) { s.mu.Lock() s.current = storage s.mu.Unlock() } func (s *reloadableStorage) Put(ctx context.Context, name string, reader io.Reader) (*biz.StoredFile, error) { s.mu.RLock() defer s.mu.RUnlock() return s.current.Put(ctx, name, reader) } func (s *reloadableStorage) Open(ctx context.Context, name string) (io.ReadCloser, error) { s.mu.RLock() defer s.mu.RUnlock() return s.current.Open(ctx, name) } func (s *reloadableStorage) Delete(ctx context.Context, name string) error { s.mu.RLock() defer s.mu.RUnlock() return s.current.Delete(ctx, name) } func (s *reloadableStorage) Compose(ctx context.Context, names []string, destination string) (*biz.StoredFile, string, error) { s.mu.RLock() defer s.mu.RUnlock() return s.current.Compose(ctx, names, destination) } func (s *reloadableStorage) DeletePrefix(ctx context.Context, prefix string) error { s.mu.RLock() defer s.mu.RUnlock() return s.current.DeletePrefix(ctx, prefix) } func (s *reloadableStorage) List(ctx context.Context, prefix, cursor string, limit int) ([]*biz.StoredFile, string, bool, error) { s.mu.RLock() defer s.mu.RUnlock() return s.current.List(ctx, prefix, cursor, limit) }