summaryrefslogtreecommitdiff
path: root/plugins/resetter
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/resetter')
-rw-r--r--plugins/resetter/interface.go17
-rw-r--r--plugins/resetter/plugin.go80
-rw-r--r--plugins/resetter/rpc.go30
3 files changed, 127 insertions, 0 deletions
diff --git a/plugins/resetter/interface.go b/plugins/resetter/interface.go
new file mode 100644
index 00000000..47d8d791
--- /dev/null
+++ b/plugins/resetter/interface.go
@@ -0,0 +1,17 @@
+package resetter
+
+// If plugin implements Resettable interface, than it state can be resetted without reload in runtime via RPC/HTTP
+type Resettable interface {
+ // Reset reload all plugins
+ Reset() error
+}
+
+// Resetter interface is the Resetter plugin main interface
+type Resetter interface {
+ // Reset all registered plugins
+ ResetAll() error
+ // Reset by plugin name
+ ResetByName(string) error
+ // GetAll registered plugins
+ GetAll() []string
+}
diff --git a/plugins/resetter/plugin.go b/plugins/resetter/plugin.go
new file mode 100644
index 00000000..5d294086
--- /dev/null
+++ b/plugins/resetter/plugin.go
@@ -0,0 +1,80 @@
+package resetter
+
+import (
+ "github.com/spiral/endure"
+ "github.com/spiral/errors"
+ "github.com/spiral/roadrunner/v2/plugins/logger"
+)
+
+const PluginName = "resetter"
+
+type Plugin struct {
+ registry map[string]Resettable
+ log logger.Logger
+}
+
+func (p *Plugin) ResetAll() error {
+ const op = errors.Op("reset all")
+ for name := range p.registry {
+ err := p.registry[name].Reset()
+ if err != nil {
+ return errors.E(op, err)
+ }
+ }
+ return nil
+}
+
+func (p *Plugin) ResetByName(plugin string) error {
+ const op = errors.Op("reset by name")
+ if plugin, ok := p.registry[plugin]; ok {
+ return plugin.Reset()
+ }
+ return errors.E(op, errors.Errorf("can't find plugin: %s", plugin))
+}
+
+func (p *Plugin) GetAll() []string {
+ all := make([]string, 0, len(p.registry))
+ for name := range p.registry {
+ all = append(all, name)
+ }
+ return all
+}
+
+func (p *Plugin) Init(log logger.Logger) error {
+ p.registry = make(map[string]Resettable)
+ p.log = log
+ return nil
+}
+
+// Reset named service.
+func (p *Plugin) Reset(name string) error {
+ svc, ok := p.registry[name]
+ if !ok {
+ return errors.E("no such service", errors.Str(name))
+ }
+
+ return svc.Reset()
+}
+
+// RegisterTarget resettable service.
+func (p *Plugin) RegisterTarget(name endure.Named, r Resettable) error {
+ p.registry[name.Name()] = r
+ return nil
+}
+
+// Collects declares services to be collected.
+func (p *Plugin) Collects() []interface{} {
+ return []interface{}{
+ p.RegisterTarget,
+ }
+}
+
+// Name of the service.
+func (p *Plugin) Name() string {
+ return PluginName
+}
+
+// RPCService returns associated rpc service.
+func (p *Plugin) RPC() interface{} {
+ return &rpc{srv: p, log: p.log}
+}
diff --git a/plugins/resetter/rpc.go b/plugins/resetter/rpc.go
new file mode 100644
index 00000000..69c955b0
--- /dev/null
+++ b/plugins/resetter/rpc.go
@@ -0,0 +1,30 @@
+package resetter
+
+import "github.com/spiral/roadrunner/v2/plugins/logger"
+
+type rpc struct {
+ srv *Plugin
+ log logger.Logger
+}
+
+// List all resettable plugins.
+func (rpc *rpc) List(_ bool, list *[]string) error {
+ rpc.log.Debug("started List method")
+ *list = make([]string, 0)
+
+ for name := range rpc.srv.registry {
+ *list = append(*list, name)
+ }
+ rpc.log.Debug("services list", "services", *list)
+
+ rpc.log.Debug("finished List method")
+ return nil
+}
+
+// Reset named plugin.
+func (rpc *rpc) Reset(service string, done *bool) error {
+ rpc.log.Debug("started Reset method for the service", "service", service)
+ defer rpc.log.Debug("finished Reset method for the service", "service", service)
+ *done = true
+ return rpc.srv.Reset(service)
+}