summaryrefslogtreecommitdiff
path: root/plugins/status/plugin.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/status/plugin.go')
-rw-r--r--plugins/status/plugin.go214
1 files changed, 0 insertions, 214 deletions
diff --git a/plugins/status/plugin.go b/plugins/status/plugin.go
deleted file mode 100644
index b76ad0a3..00000000
--- a/plugins/status/plugin.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package status
-
-import (
- "fmt"
- "net/http"
- "time"
-
- "github.com/gofiber/fiber/v2"
- endure "github.com/spiral/endure/pkg/container"
- "github.com/spiral/errors"
- "github.com/spiral/roadrunner/v2/plugins/config"
- "github.com/spiral/roadrunner/v2/plugins/logger"
-)
-
-const (
- // PluginName declares public plugin name.
- PluginName = "status"
-)
-
-type Plugin struct {
- // plugins which needs to be checked just as Status
- statusRegistry map[string]Checker
- // plugins which needs to send Readiness status
- readyRegistry map[string]Readiness
- server *fiber.App
- log logger.Logger
- cfg *Config
-}
-
-func (c *Plugin) Init(log logger.Logger, cfg config.Configurer) error {
- const op = errors.Op("checker_plugin_init")
- if !cfg.Has(PluginName) {
- return errors.E(op, errors.Disabled)
- }
- err := cfg.UnmarshalKey(PluginName, &c.cfg)
- if err != nil {
- return errors.E(op, errors.Disabled, err)
- }
-
- // init defaults for the status plugin
- c.cfg.InitDefaults()
-
- c.readyRegistry = make(map[string]Readiness)
- c.statusRegistry = make(map[string]Checker)
-
- c.log = log
-
- return nil
-}
-
-func (c *Plugin) Serve() chan error {
- errCh := make(chan error, 1)
- c.server = fiber.New(fiber.Config{
- ReadTimeout: time.Second * 5,
- WriteTimeout: time.Second * 5,
- IdleTimeout: time.Second * 5,
- DisableStartupMessage: true,
- })
-
- c.server.Use("/health", c.healthHandler)
- c.server.Use("/ready", c.readinessHandler)
-
- go func() {
- err := c.server.Listen(c.cfg.Address)
- if err != nil {
- errCh <- err
- }
- }()
-
- return errCh
-}
-
-func (c *Plugin) Stop() error {
- const op = errors.Op("checker_plugin_stop")
- err := c.server.Shutdown()
- if err != nil {
- return errors.E(op, err)
- }
- return nil
-}
-
-// status returns a Checker interface implementation
-// Reset named service. This is not an Status interface implementation
-func (c *Plugin) status(name string) (Status, error) {
- const op = errors.Op("checker_plugin_status")
- svc, ok := c.statusRegistry[name]
- if !ok {
- return Status{}, errors.E(op, errors.Errorf("no such plugin: %s", name))
- }
-
- return svc.Status(), nil
-}
-
-// ready used to provide a readiness check for the plugin
-func (c *Plugin) ready(name string) (Status, error) {
- const op = errors.Op("checker_plugin_ready")
- svc, ok := c.readyRegistry[name]
- if !ok {
- return Status{}, errors.E(op, errors.Errorf("no such plugin: %s", name))
- }
-
- return svc.Ready(), nil
-}
-
-// CollectCheckerImpls collects services which can provide Status.
-func (c *Plugin) CollectCheckerImpls(name endure.Named, r Checker) error {
- c.statusRegistry[name.Name()] = r
- return nil
-}
-
-// CollectReadinessImpls collects services which can provide Readiness check.
-func (c *Plugin) CollectReadinessImpls(name endure.Named, r Readiness) error {
- c.readyRegistry[name.Name()] = r
- return nil
-}
-
-// Collects declares services to be collected.
-func (c *Plugin) Collects() []interface{} {
- return []interface{}{
- c.CollectReadinessImpls,
- c.CollectCheckerImpls,
- }
-}
-
-// Name of the service.
-func (c *Plugin) Name() string {
- return PluginName
-}
-
-// Available interface implementation
-func (c *Plugin) Available() {}
-
-// RPC returns associated rpc service.
-func (c *Plugin) RPC() interface{} {
- return &rpc{srv: c, log: c.log}
-}
-
-type Plugins struct {
- Plugins []string `query:"plugin"`
-}
-
-const template string = "Service: %s: Status: %d\n"
-
-func (c *Plugin) healthHandler(ctx *fiber.Ctx) error {
- const op = errors.Op("checker_plugin_health_handler")
- plugins := &Plugins{}
- err := ctx.QueryParser(plugins)
- if err != nil {
- return errors.E(op, err)
- }
-
- if len(plugins.Plugins) == 0 {
- ctx.Status(http.StatusOK)
- _, _ = ctx.WriteString("No plugins provided in query. Query should be in form of: health?plugin=plugin1&plugin=plugin2 \n")
- return nil
- }
-
- // iterate over all provided plugins
- for i := 0; i < len(plugins.Plugins); i++ {
- // check if the plugin exists
- if plugin, ok := c.statusRegistry[plugins.Plugins[i]]; ok {
- st := plugin.Status()
- if st.Code >= 500 {
- // if there is 500 or 503 status code return immediately
- ctx.Status(c.cfg.UnavailableStatusCode)
- return nil
- } else if st.Code >= 100 && st.Code <= 400 {
- _, _ = ctx.WriteString(fmt.Sprintf(template, plugins.Plugins[i], st.Code))
- }
- } else {
- _, _ = ctx.WriteString(fmt.Sprintf("Service: %s not found", plugins.Plugins[i]))
- }
- }
-
- ctx.Status(http.StatusOK)
- return nil
-}
-
-// readinessHandler return 200OK if all plugins are ready to serve
-// if one of the plugins return status from the 5xx range, the status for all query will be 503
-func (c *Plugin) readinessHandler(ctx *fiber.Ctx) error {
- const op = errors.Op("checker_plugin_readiness_handler")
- plugins := &Plugins{}
- err := ctx.QueryParser(plugins)
- if err != nil {
- return errors.E(op, err)
- }
-
- if len(plugins.Plugins) == 0 {
- ctx.Status(http.StatusOK)
- _, _ = ctx.WriteString("No plugins provided in query. Query should be in form of: ready?plugin=plugin1&plugin=plugin2 \n")
- return nil
- }
-
- // iterate over all provided plugins
- for i := 0; i < len(plugins.Plugins); i++ {
- // check if the plugin exists
- if plugin, ok := c.readyRegistry[plugins.Plugins[i]]; ok {
- st := plugin.Ready()
- if st.Code >= 500 {
- // if there is 500 or 503 status code return immediately
- ctx.Status(c.cfg.UnavailableStatusCode)
- return nil
- } else if st.Code >= 100 && st.Code <= 400 {
- _, _ = ctx.WriteString(fmt.Sprintf(template, plugins.Plugins[i], st.Code))
- }
- } else {
- _, _ = ctx.WriteString(fmt.Sprintf("Service: %s not found", plugins.Plugins[i]))
- }
- }
-
- ctx.Status(http.StatusOK)
- return nil
-}