-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine_plugin_manager.go
More file actions
108 lines (95 loc) · 3.51 KB
/
engine_plugin_manager.go
File metadata and controls
108 lines (95 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package plugin
import (
"fmt"
"github.com/GoCodeAlone/workflow/capability"
"github.com/GoCodeAlone/workflow/schema"
)
// EnginePluginManager wraps the PluginLoader with lifecycle management,
// allowing plugins to be registered, enabled, and disabled independently.
type EnginePluginManager struct {
loader *PluginLoader
capabilityReg *capability.Registry
schemaReg *schema.ModuleSchemaRegistry
plugins map[string]EnginePlugin // keyed by name
enabled map[string]bool
}
// NewEnginePluginManager creates a new manager backed by the given capability and schema registries.
func NewEnginePluginManager(capReg *capability.Registry, schemaReg *schema.ModuleSchemaRegistry) *EnginePluginManager {
return &EnginePluginManager{
loader: NewPluginLoader(capReg, schemaReg),
capabilityReg: capReg,
schemaReg: schemaReg,
plugins: make(map[string]EnginePlugin),
enabled: make(map[string]bool),
}
}
// Register adds a plugin to the manager without enabling it.
// Returns an error if a plugin with the same name is already registered.
func (m *EnginePluginManager) Register(p EnginePlugin) error {
name := p.EngineManifest().Name
if _, exists := m.plugins[name]; exists {
return fmt.Errorf("engine plugin manager: plugin %q already registered", name)
}
m.plugins[name] = p
return nil
}
// Enable activates a registered plugin, loading it into the PluginLoader.
// Returns an error if the plugin is not registered or is already enabled.
func (m *EnginePluginManager) Enable(name string) error {
p, exists := m.plugins[name]
if !exists {
return fmt.Errorf("engine plugin manager: plugin %q not registered", name)
}
if m.enabled[name] {
return fmt.Errorf("engine plugin manager: plugin %q already enabled", name)
}
if err := m.loader.LoadPlugin(p); err != nil {
return fmt.Errorf("engine plugin manager: enable %q: %w", name, err)
}
m.enabled[name] = true
return nil
}
// Disable deactivates a plugin. The plugin remains registered but its factories
// are no longer active. Note: a full rebuild of the loader is performed to
// remove the plugin's contributions.
func (m *EnginePluginManager) Disable(name string) error {
if _, exists := m.plugins[name]; !exists {
return fmt.Errorf("engine plugin manager: plugin %q not registered", name)
}
if !m.enabled[name] {
return fmt.Errorf("engine plugin manager: plugin %q not enabled", name)
}
m.enabled[name] = false
// Rebuild the loader from scratch with only the remaining enabled plugins.
newLoader := NewPluginLoader(m.capabilityReg, m.schemaReg)
for pName, p := range m.plugins {
if m.enabled[pName] {
if err := newLoader.LoadPlugin(p); err != nil {
return fmt.Errorf("engine plugin manager: rebuild after disable %q: %w", name, err)
}
}
}
m.loader = newLoader
return nil
}
// IsEnabled returns true if the named plugin is currently enabled.
func (m *EnginePluginManager) IsEnabled(name string) bool {
return m.enabled[name]
}
// Get returns the plugin with the given name and a boolean indicating whether it exists.
func (m *EnginePluginManager) Get(name string) (EnginePlugin, bool) {
p, ok := m.plugins[name]
return p, ok
}
// List returns all registered plugins (enabled and disabled).
func (m *EnginePluginManager) List() []EnginePlugin {
out := make([]EnginePlugin, 0, len(m.plugins))
for _, p := range m.plugins {
out = append(out, p)
}
return out
}
// Loader returns the underlying PluginLoader for accessing aggregated factories and hooks.
func (m *EnginePluginManager) Loader() *PluginLoader {
return m.loader
}