mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-31 07:30:32 +00:00
refactor: rename pluginInstance to plugin for consistency across the codebase
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
8bfb14814e
commit
e200b70ea6
@ -29,7 +29,7 @@ type onInitOutput struct {
|
|||||||
|
|
||||||
// callPluginInit calls the plugin's nd_on_init function if it has the Lifecycle capability.
|
// callPluginInit calls the plugin's nd_on_init function if it has the Lifecycle capability.
|
||||||
// This is called after the plugin is fully loaded with all services registered.
|
// This is called after the plugin is fully loaded with all services registered.
|
||||||
func callPluginInit(ctx context.Context, instance *pluginInstance) {
|
func callPluginInit(ctx context.Context, instance *plugin) {
|
||||||
if !hasCapability(instance.capabilities, CapabilityLifecycle) {
|
if !hasCapability(instance.capabilities, CapabilityLifecycle) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ var _ = Describe("SchedulerService", Ordered, func() {
|
|||||||
|
|
||||||
// Create and start manager
|
// Create and start manager
|
||||||
manager = &Manager{
|
manager = &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
err = manager.Start(GinkgoT().Context())
|
err = manager.Start(GinkgoT().Context())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|||||||
@ -64,7 +64,7 @@ var _ = Describe("SubsonicAPI Host Function", Ordered, func() {
|
|||||||
|
|
||||||
// Create and configure manager
|
// Create and configure manager
|
||||||
manager = &Manager{
|
manager = &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
manager.SetSubsonicRouter(router)
|
manager.SetSubsonicRouter(router)
|
||||||
manager.SetDataStore(dataStore)
|
manager.SetDataStore(dataStore)
|
||||||
@ -100,7 +100,7 @@ var _ = Describe("SubsonicAPI Host Function", Ordered, func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Describe("SubsonicAPI Call", func() {
|
Describe("SubsonicAPI Call", func() {
|
||||||
var plugin *pluginInstance
|
var plugin *plugin
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
manager.mu.RLock()
|
manager.mu.RLock()
|
||||||
|
|||||||
@ -427,7 +427,7 @@ func (s *webSocketServiceImpl) invokeOnClose(ctx context.Context, connectionID s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *webSocketServiceImpl) getPluginInstance() *pluginInstance {
|
func (s *webSocketServiceImpl) getPluginInstance() *plugin {
|
||||||
s.manager.mu.RLock()
|
s.manager.mu.RLock()
|
||||||
instance, ok := s.manager.plugins[s.pluginName]
|
instance, ok := s.manager.plugins[s.pluginName]
|
||||||
s.manager.mu.RUnlock()
|
s.manager.mu.RUnlock()
|
||||||
|
|||||||
@ -49,7 +49,7 @@ var _ = Describe("WebSocketService", Ordered, func() {
|
|||||||
|
|
||||||
// Create and start manager
|
// Create and start manager
|
||||||
manager = &Manager{
|
manager = &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
err = manager.Start(GinkgoT().Context())
|
err = manager.Start(GinkgoT().Context())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|||||||
@ -44,7 +44,7 @@ type SubsonicRouter = http.Handler
|
|||||||
// It implements both agents.PluginLoader and scrobbler.PluginLoader interfaces.
|
// It implements both agents.PluginLoader and scrobbler.PluginLoader interfaces.
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
plugins map[string]*pluginInstance
|
plugins map[string]*plugin
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
cache wazero.CompilationCache
|
cache wazero.CompilationCache
|
||||||
@ -62,8 +62,8 @@ type Manager struct {
|
|||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// pluginInstance represents a loaded plugin
|
// plugin represents a loaded plugin
|
||||||
type pluginInstance struct {
|
type plugin struct {
|
||||||
name string // Plugin name (from filename)
|
name string // Plugin name (from filename)
|
||||||
path string // Path to the wasm file
|
path string // Path to the wasm file
|
||||||
manifest *Manifest
|
manifest *Manifest
|
||||||
@ -72,18 +72,18 @@ type pluginInstance struct {
|
|||||||
closers []io.Closer // Cleanup functions to call on unload
|
closers []io.Closer // Cleanup functions to call on unload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pluginInstance) instance() (*extism.Plugin, error) {
|
func (p *plugin) instance() (*extism.Plugin, error) {
|
||||||
plugin, err := p.compiled.Instance(context.Background(), extism.PluginInstanceConfig{
|
instance, err := p.compiled.Instance(context.Background(), extism.PluginInstanceConfig{
|
||||||
ModuleConfig: wazero.NewModuleConfig().WithSysWalltime().WithRandSource(rand.Reader),
|
ModuleConfig: wazero.NewModuleConfig().WithSysWalltime().WithRandSource(rand.Reader),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
plugin.SetLogger(extismLogger(p.name))
|
instance.SetLogger(extismLogger(p.name))
|
||||||
return plugin, nil
|
return instance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pluginInstance) Close() error {
|
func (p *plugin) Close() error {
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, f := range p.closers {
|
for _, f := range p.closers {
|
||||||
err := f.Close()
|
err := f.Close()
|
||||||
@ -99,7 +99,7 @@ func (p *pluginInstance) Close() error {
|
|||||||
func GetManager() *Manager {
|
func GetManager() *Manager {
|
||||||
return singleton.GetInstance(func() *Manager {
|
return singleton.GetInstance(func() *Manager {
|
||||||
return &Manager{
|
return &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -194,14 +194,14 @@ func (m *Manager) Stop() error {
|
|||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
// Close all plugins
|
// Close all plugins
|
||||||
for name, instance := range m.plugins {
|
for name, plugin := range m.plugins {
|
||||||
if instance.compiled != nil {
|
if plugin.compiled != nil {
|
||||||
if err := instance.compiled.Close(context.Background()); err != nil {
|
if err := plugin.compiled.Close(context.Background()); err != nil {
|
||||||
log.Error("Error closing plugin", "plugin", name, err)
|
log.Error("Error closing plugin", "plugin", name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.plugins = make(map[string]*pluginInstance)
|
m.plugins = make(map[string]*plugin)
|
||||||
|
|
||||||
// Close compilation cache
|
// Close compilation cache
|
||||||
if m.cache != nil {
|
if m.cache != nil {
|
||||||
@ -223,8 +223,8 @@ func (m *Manager) PluginNames(capability string) []string {
|
|||||||
|
|
||||||
var names []string
|
var names []string
|
||||||
cap := Capability(capability)
|
cap := Capability(capability)
|
||||||
for name, instance := range m.plugins {
|
for name, plugin := range m.plugins {
|
||||||
if hasCapability(instance.capabilities, cap) {
|
if hasCapability(plugin.capabilities, cap) {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,17 +235,17 @@ func (m *Manager) PluginNames(capability string) []string {
|
|||||||
// Returns false if the plugin is not found or doesn't have the MetadataAgent capability.
|
// Returns false if the plugin is not found or doesn't have the MetadataAgent capability.
|
||||||
func (m *Manager) LoadMediaAgent(name string) (agents.Interface, bool) {
|
func (m *Manager) LoadMediaAgent(name string) (agents.Interface, bool) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
instance, ok := m.plugins[name]
|
plugin, ok := m.plugins[name]
|
||||||
m.mu.RUnlock()
|
m.mu.RUnlock()
|
||||||
|
|
||||||
if !ok || !hasCapability(instance.capabilities, CapabilityMetadataAgent) {
|
if !ok || !hasCapability(plugin.capabilities, CapabilityMetadataAgent) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new metadata agent adapter for this plugin
|
// Create a new metadata agent adapter for this plugin
|
||||||
return &MetadataAgent{
|
return &MetadataAgent{
|
||||||
name: instance.name,
|
name: plugin.name,
|
||||||
plugin: instance,
|
plugin: plugin,
|
||||||
}, true
|
}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,17 +253,17 @@ func (m *Manager) LoadMediaAgent(name string) (agents.Interface, bool) {
|
|||||||
// Returns false if the plugin is not found or doesn't have the Scrobbler capability.
|
// Returns false if the plugin is not found or doesn't have the Scrobbler capability.
|
||||||
func (m *Manager) LoadScrobbler(name string) (scrobbler.Scrobbler, bool) {
|
func (m *Manager) LoadScrobbler(name string) (scrobbler.Scrobbler, bool) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
instance, ok := m.plugins[name]
|
plugin, ok := m.plugins[name]
|
||||||
m.mu.RUnlock()
|
m.mu.RUnlock()
|
||||||
|
|
||||||
if !ok || !hasCapability(instance.capabilities, CapabilityScrobbler) {
|
if !ok || !hasCapability(plugin.capabilities, CapabilityScrobbler) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new scrobbler adapter for this plugin
|
// Create a new scrobbler adapter for this plugin
|
||||||
return &ScrobblerPlugin{
|
return &ScrobblerPlugin{
|
||||||
name: instance.name,
|
name: plugin.name,
|
||||||
plugin: instance,
|
plugin: plugin,
|
||||||
}, true
|
}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,10 +279,10 @@ func (m *Manager) GetPluginInfo() map[string]PluginInfo {
|
|||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
info := make(map[string]PluginInfo, len(m.plugins))
|
info := make(map[string]PluginInfo, len(m.plugins))
|
||||||
for name, instance := range m.plugins {
|
for name, plugin := range m.plugins {
|
||||||
info[name] = PluginInfo{
|
info[name] = PluginInfo{
|
||||||
Name: instance.manifest.Name,
|
Name: plugin.manifest.Name,
|
||||||
Version: instance.manifest.Version,
|
Version: plugin.manifest.Version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
@ -442,7 +442,7 @@ func (m *Manager) loadPlugin(name, wasmPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
m.plugins[name] = &pluginInstance{
|
m.plugins[name] = &plugin{
|
||||||
name: name,
|
name: name,
|
||||||
path: wasmPath,
|
path: wasmPath,
|
||||||
manifest: &manifest,
|
manifest: &manifest,
|
||||||
@ -470,7 +470,7 @@ func (m *Manager) getPluginConfig(name string) map[string]string {
|
|||||||
// Returns an error if the plugin is not found.
|
// Returns an error if the plugin is not found.
|
||||||
func (m *Manager) UnloadPlugin(name string) error {
|
func (m *Manager) UnloadPlugin(name string) error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
instance, ok := m.plugins[name]
|
plugin, ok := m.plugins[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
return fmt.Errorf("plugin %q not found", name)
|
return fmt.Errorf("plugin %q not found", name)
|
||||||
@ -479,18 +479,18 @@ func (m *Manager) UnloadPlugin(name string) error {
|
|||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
|
|
||||||
// Run cleanup functions
|
// Run cleanup functions
|
||||||
err := instance.Close()
|
err := plugin.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error during plugin cleanup", "plugin", name, err)
|
log.Error("Error during plugin cleanup", "plugin", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the compiled plugin outside the lock with a grace period
|
// Close the compiled plugin outside the lock with a grace period
|
||||||
// to allow in-flight requests to complete
|
// to allow in-flight requests to complete
|
||||||
if instance.compiled != nil {
|
if plugin.compiled != nil {
|
||||||
// Use a brief timeout for cleanup
|
// Use a brief timeout for cleanup
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := instance.compiled.Close(ctx); err != nil {
|
if err := plugin.compiled.Close(ctx); err != nil {
|
||||||
log.Error("Error closing plugin during unload", "plugin", name, err)
|
log.Error("Error closing plugin during unload", "plugin", name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,7 +551,7 @@ var errFunctionNotFound = errors.New("function not found")
|
|||||||
|
|
||||||
// callPluginFunction is a helper to call a plugin function with input and output types.
|
// callPluginFunction is a helper to call a plugin function with input and output types.
|
||||||
// It handles JSON marshalling/unmarshalling and error checking.
|
// It handles JSON marshalling/unmarshalling and error checking.
|
||||||
func callPluginFunction[I any, O any](ctx context.Context, plugin *pluginInstance, funcName string, input I) (O, error) {
|
func callPluginFunction[I any, O any](ctx context.Context, plugin *plugin, funcName string, input I) (O, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
var result O
|
var result O
|
||||||
|
|||||||
@ -41,7 +41,7 @@ func init() {
|
|||||||
// the agents interfaces for metadata retrieval.
|
// the agents interfaces for metadata retrieval.
|
||||||
type MetadataAgent struct {
|
type MetadataAgent struct {
|
||||||
name string
|
name string
|
||||||
plugin *pluginInstance
|
plugin *plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// AgentName returns the plugin name
|
// AgentName returns the plugin name
|
||||||
|
|||||||
@ -80,7 +80,7 @@ func createTestManagerWithPlugins(pluginConfig map[string]map[string]string, plu
|
|||||||
|
|
||||||
// Create and start manager
|
// Create and start manager
|
||||||
manager := &Manager{
|
manager := &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
err = manager.Start(GinkgoT().Context())
|
err = manager.Start(GinkgoT().Context())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|||||||
@ -33,7 +33,7 @@ func init() {
|
|||||||
// the scrobbler.Scrobbler interface for scrobbling to external services.
|
// the scrobbler.Scrobbler interface for scrobbling to external services.
|
||||||
type ScrobblerPlugin struct {
|
type ScrobblerPlugin struct {
|
||||||
name string
|
name string
|
||||||
plugin *pluginInstance
|
plugin *plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAuthorized checks if the user is authorized with this scrobbler
|
// IsAuthorized checks if the user is authorized with this scrobbler
|
||||||
|
|||||||
@ -89,7 +89,7 @@ var _ = Describe("Watcher Integration", Ordered, func() {
|
|||||||
|
|
||||||
conf.Server.Plugins.AutoReload = true
|
conf.Server.Plugins.AutoReload = true
|
||||||
autoReloadManager := &Manager{
|
autoReloadManager := &Manager{
|
||||||
plugins: make(map[string]*pluginInstance),
|
plugins: make(map[string]*plugin),
|
||||||
}
|
}
|
||||||
err := autoReloadManager.Start(ctx)
|
err := autoReloadManager.Start(ctx)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user