fix(gateway): keep media store aligned after reload
This commit is contained in:
parent
6e6293e596
commit
91f024eb1d
3 changed files with 45 additions and 1 deletions
|
|
@ -100,6 +100,10 @@ type Manager struct {
|
||||||
channelHashes map[string]string // channel name → config hash
|
channelHashes map[string]string // channel name → config hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mediaStoreSetter interface {
|
||||||
|
SetMediaStore(s media.MediaStore)
|
||||||
|
}
|
||||||
|
|
||||||
// ManagerOption configures a channel Manager.
|
// ManagerOption configures a channel Manager.
|
||||||
type ManagerOption func(*Manager)
|
type ManagerOption func(*Manager)
|
||||||
|
|
||||||
|
|
@ -485,6 +489,22 @@ func NewManager(
|
||||||
return m, nil
|
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.
|
// GetStreamer implements bus.StreamDelegate.
|
||||||
// It checks if the named channel supports streaming and returns a Streamer.
|
// 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) {
|
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 {
|
} else {
|
||||||
// Inject MediaStore if channel supports it
|
// Inject MediaStore if channel supports it
|
||||||
if m.mediaStore != nil {
|
if m.mediaStore != nil {
|
||||||
if setter, ok := ch.(interface{ SetMediaStore(s media.MediaStore) }); ok {
|
if setter, ok := ch.(mediaStoreSetter); ok {
|
||||||
setter.SetMediaStore(m.mediaStore)
|
setter.SetMediaStore(m.mediaStore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/sipeed/picoclaw/pkg/bus"
|
"github.com/sipeed/picoclaw/pkg/bus"
|
||||||
"github.com/sipeed/picoclaw/pkg/config"
|
"github.com/sipeed/picoclaw/pkg/config"
|
||||||
runtimeevents "github.com/sipeed/picoclaw/pkg/events"
|
runtimeevents "github.com/sipeed/picoclaw/pkg/events"
|
||||||
|
"github.com/sipeed/picoclaw/pkg/media"
|
||||||
"github.com/sipeed/picoclaw/pkg/utils"
|
"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) {
|
func TestStartAll_AllChannelsFail_ReturnsJoinedError(t *testing.T) {
|
||||||
m := newTestManager()
|
m := newTestManager()
|
||||||
errA := errors.New("channel-a start failed")
|
errA := errors.New("channel-a start failed")
|
||||||
|
|
|
||||||
|
|
@ -646,6 +646,9 @@ func restartServices(
|
||||||
if fms, ok := runningServices.MediaStore.(*media.FileMediaStore); ok {
|
if fms, ok := runningServices.MediaStore.(*media.FileMediaStore); ok {
|
||||||
fms.Start()
|
fms.Start()
|
||||||
}
|
}
|
||||||
|
if runningServices.ChannelManager != nil {
|
||||||
|
runningServices.ChannelManager.SetMediaStore(runningServices.MediaStore)
|
||||||
|
}
|
||||||
al.SetMediaStore(runningServices.MediaStore)
|
al.SetMediaStore(runningServices.MediaStore)
|
||||||
|
|
||||||
al.SetChannelManager(runningServices.ChannelManager)
|
al.SetChannelManager(runningServices.ChannelManager)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue