fix(gateway): keep media store aligned after reload

This commit is contained in:
xp
2026-05-06 20:50:58 +08:00
parent 6e6293e596
commit 91f024eb1d
3 changed files with 45 additions and 1 deletions
+21 -1
View File
@@ -100,6 +100,10 @@ type Manager struct {
channelHashes map[string]string // channel name → config hash
}
type mediaStoreSetter interface {
SetMediaStore(s media.MediaStore)
}
// ManagerOption configures a channel Manager.
type ManagerOption func(*Manager)
@@ -485,6 +489,22 @@ func NewManager(
return m, nil
}
// SetMediaStore updates the store used by the manager and every channel that
// accepts media store injection. Gateway reload creates a fresh store, so
// keeping existing channels on the same store as the agent is required for
// inbound media refs to remain resolvable after reload.
func (m *Manager) SetMediaStore(store media.MediaStore) {
m.mu.Lock()
defer m.mu.Unlock()
m.mediaStore = store
for _, ch := range m.channels {
if setter, ok := ch.(mediaStoreSetter); ok {
setter.SetMediaStore(store)
}
}
}
// GetStreamer implements bus.StreamDelegate.
// It checks if the named channel supports streaming and returns a Streamer.
func (m *Manager) GetStreamer(ctx context.Context, channelName, chatID string) (bus.Streamer, bool) {
@@ -582,7 +602,7 @@ func (m *Manager) initChannel(typeName, channelName string) {
} else {
// Inject MediaStore if channel supports it
if m.mediaStore != nil {
if setter, ok := ch.(interface{ SetMediaStore(s media.MediaStore) }); ok {
if setter, ok := ch.(mediaStoreSetter); ok {
setter.SetMediaStore(m.mediaStore)
}
}
+21
View File
@@ -15,6 +15,7 @@ import (
"github.com/sipeed/picoclaw/pkg/bus"
"github.com/sipeed/picoclaw/pkg/config"
runtimeevents "github.com/sipeed/picoclaw/pkg/events"
"github.com/sipeed/picoclaw/pkg/media"
"github.com/sipeed/picoclaw/pkg/utils"
)
@@ -149,6 +150,26 @@ func newTestManager() *Manager {
}
}
func TestSetMediaStorePropagatesToExistingChannels(t *testing.T) {
oldStore := media.NewFileMediaStore()
newStore := media.NewFileMediaStore()
ch := &mockChannel{}
ch.SetMediaStore(oldStore)
m := newTestManager()
m.mediaStore = oldStore
m.channels["telegram"] = ch
m.SetMediaStore(newStore)
if m.mediaStore != newStore {
t.Fatal("manager media store was not updated")
}
if got := ch.GetMediaStore(); got != newStore {
t.Fatalf("channel media store = %p, want %p", got, newStore)
}
}
func TestStartAll_AllChannelsFail_ReturnsJoinedError(t *testing.T) {
m := newTestManager()
errA := errors.New("channel-a start failed")
+3
View File
@@ -646,6 +646,9 @@ func restartServices(
if fms, ok := runningServices.MediaStore.(*media.FileMediaStore); ok {
fms.Start()
}
if runningServices.ChannelManager != nil {
runningServices.ChannelManager.SetMediaStore(runningServices.MediaStore)
}
al.SetMediaStore(runningServices.MediaStore)
al.SetChannelManager(runningServices.ChannelManager)