diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index b25b4c100..890f9c60b 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -71,9 +71,9 @@ func CreateNativeAPIRouter(ctx context.Context) *nativeapi.Router { fFmpeg := ffmpeg.New() broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) - agentsAgents := agents.GetAgents(dataStore, manager) matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) + agentsAgents := agents.GetAgents(dataStore, manager) provider := external.NewProvider(dataStore, agentsAgents, matcherMatcher) artworkArtwork := artwork.NewArtwork(dataStore, fileCache, fFmpeg, provider) cacheWarmer := artwork.NewCacheWarmer(artworkArtwork, fileCache) @@ -93,9 +93,9 @@ func CreateSubsonicAPIRouter(ctx context.Context) *subsonic.Router { fFmpeg := ffmpeg.New() broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) - agentsAgents := agents.GetAgents(dataStore, manager) matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) + agentsAgents := agents.GetAgents(dataStore, manager) provider := external.NewProvider(dataStore, agentsAgents, matcherMatcher) artworkArtwork := artwork.NewArtwork(dataStore, fileCache, fFmpeg, provider) transcodingCache := stream.GetTranscodingCache() @@ -122,9 +122,9 @@ func CreatePublicRouter() *public.Router { fFmpeg := ffmpeg.New() broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) - agentsAgents := agents.GetAgents(dataStore, manager) matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) + agentsAgents := agents.GetAgents(dataStore, manager) provider := external.NewProvider(dataStore, agentsAgents, matcherMatcher) artworkArtwork := artwork.NewArtwork(dataStore, fileCache, fFmpeg, provider) transcodingCache := stream.GetTranscodingCache() @@ -170,9 +170,9 @@ func CreateScanner(ctx context.Context) model.Scanner { fFmpeg := ffmpeg.New() broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) - agentsAgents := agents.GetAgents(dataStore, manager) matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) + agentsAgents := agents.GetAgents(dataStore, manager) provider := external.NewProvider(dataStore, agentsAgents, matcherMatcher) artworkArtwork := artwork.NewArtwork(dataStore, fileCache, fFmpeg, provider) cacheWarmer := artwork.NewCacheWarmer(artworkArtwork, fileCache) @@ -189,9 +189,9 @@ func CreateScanWatcher(ctx context.Context) scanner.Watcher { fFmpeg := ffmpeg.New() broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) - agentsAgents := agents.GetAgents(dataStore, manager) matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) + agentsAgents := agents.GetAgents(dataStore, manager) provider := external.NewProvider(dataStore, agentsAgents, matcherMatcher) artworkArtwork := artwork.NewArtwork(dataStore, fileCache, fFmpeg, provider) cacheWarmer := artwork.NewCacheWarmer(artworkArtwork, fileCache) @@ -214,7 +214,8 @@ func getPluginManager() *plugins.Manager { dataStore := persistence.New(sqlDB) broker := events.GetBroker() metricsMetrics := metrics.GetPrometheusInstance(dataStore) - manager := plugins.GetManager(dataStore, broker, metricsMetrics) + matcherMatcher := matcher.New(dataStore) + manager := plugins.GetManager(dataStore, broker, metricsMetrics, matcherMatcher) return manager } diff --git a/core/metrics/insights.go b/core/metrics/insights.go index f069d3fb6..db835bb42 100644 --- a/core/metrics/insights.go +++ b/core/metrics/insights.go @@ -324,7 +324,7 @@ func (c *insightsCollector) hasSmartPlaylists(ctx context.Context) (bool, error) // collectPlugins collects information about installed plugins func (c *insightsCollector) collectPlugins(_ context.Context) map[string]insights.PluginInfo { // TODO Fix import/inject cycles - manager := plugins.GetManager(c.ds, events.GetBroker(), nil) + manager := plugins.GetManager(c.ds, events.GetBroker(), nil, nil) info := manager.GetPluginInfo() result := make(map[string]insights.PluginInfo, len(info)) diff --git a/plugins/manager.go b/plugins/manager.go index 0c7c91ed8..3e6cc75fe 100644 --- a/plugins/manager.go +++ b/plugins/manager.go @@ -17,6 +17,7 @@ import ( "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/core/agents" "github.com/navidrome/navidrome/core/lyrics" + "github.com/navidrome/navidrome/core/matcher" "github.com/navidrome/navidrome/core/scrobbler" "github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/model" @@ -66,16 +67,18 @@ type Manager struct { ds model.DataStore broker events.Broker metrics PluginMetricsRecorder + matcher *matcher.Matcher } // GetManager returns a singleton instance of the plugin manager. // The manager is not started automatically; call Start() to begin loading plugins. -func GetManager(ds model.DataStore, broker events.Broker, m PluginMetricsRecorder) *Manager { +func GetManager(ds model.DataStore, broker events.Broker, m PluginMetricsRecorder, mt *matcher.Matcher) *Manager { return singleton.GetInstance(func() *Manager { return &Manager{ ds: ds, broker: broker, metrics: m, + matcher: mt, plugins: make(map[string]*plugin), } }) diff --git a/plugins/manager_loader.go b/plugins/manager_loader.go index e394911f7..406c2f183 100644 --- a/plugins/manager_loader.go +++ b/plugins/manager_loader.go @@ -394,7 +394,7 @@ func (m *Manager) loadPluginWithConfig(p *model.Plugin) error { // Start PlaylistGenerator orchestrator if capability is detected loadedPlugin := m.plugins[p.ID] if hasCapability(loadedPlugin.capabilities, CapabilityPlaylistGenerator) { - orch := newPlaylistGeneratorOrchestrator(m.ctx, p.ID, loadedPlugin, m.ds) + orch := newPlaylistGeneratorOrchestrator(m.ctx, p.ID, loadedPlugin, m.ds, m.matcher) loadedPlugin.closers = append(loadedPlugin.closers, orch) go orch.run() } diff --git a/plugins/playlist_generator.go b/plugins/playlist_generator.go index 64766bb3a..a2a684228 100644 --- a/plugins/playlist_generator.go +++ b/plugins/playlist_generator.go @@ -68,13 +68,13 @@ type playlistGeneratorOrchestrator struct { done chan struct{} // closed when worker exits } -func newPlaylistGeneratorOrchestrator(parentCtx context.Context, pluginName string, p *plugin, ds model.DataStore) *playlistGeneratorOrchestrator { +func newPlaylistGeneratorOrchestrator(parentCtx context.Context, pluginName string, p *plugin, ds model.DataStore, m *matcher.Matcher) *playlistGeneratorOrchestrator { ctx, cancel := context.WithCancel(parentCtx) return &playlistGeneratorOrchestrator{ pluginName: pluginName, plugin: p, ds: ds, - matcher: matcher.New(ds), + matcher: m, ctx: ctx, cancel: cancel, workCh: make(chan workItem, workChCapacity), diff --git a/plugins/plugins_suite_test.go b/plugins/plugins_suite_test.go index 41adbc133..42bf64e5b 100644 --- a/plugins/plugins_suite_test.go +++ b/plugins/plugins_suite_test.go @@ -17,6 +17,7 @@ import ( "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/conf/configtest" + "github.com/navidrome/navidrome/core/matcher" "github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/tests" @@ -145,6 +146,7 @@ func createTestManagerWithPluginsAndMetrics(pluginConfig map[string]map[string]s manager := &Manager{ plugins: make(map[string]*plugin), ds: dataStore, + matcher: matcher.New(dataStore), metrics: metrics, subsonicRouter: http.NotFoundHandler(), // Stub router for tests }