diff options
Diffstat (limited to 'plugins/status')
-rw-r--r-- | plugins/status/config.go | 18 | ||||
-rw-r--r-- | plugins/status/interface.go | 18 | ||||
-rw-r--r-- | plugins/status/plugin.go | 214 | ||||
-rw-r--r-- | plugins/status/rpc.go | 43 |
4 files changed, 0 insertions, 293 deletions
diff --git a/plugins/status/config.go b/plugins/status/config.go deleted file mode 100644 index f751898b..00000000 --- a/plugins/status/config.go +++ /dev/null @@ -1,18 +0,0 @@ -package status - -import "net/http" - -// Config is the configuration reference for the Status plugin -type Config struct { - // Address of the http server - Address string - // Status code returned in case of fail, 503 by default - UnavailableStatusCode int `mapstructure:"unavailable_status_code"` -} - -// InitDefaults configuration options -func (c *Config) InitDefaults() { - if c.UnavailableStatusCode == 0 { - c.UnavailableStatusCode = http.StatusServiceUnavailable - } -} diff --git a/plugins/status/interface.go b/plugins/status/interface.go deleted file mode 100644 index 9d5a13af..00000000 --- a/plugins/status/interface.go +++ /dev/null @@ -1,18 +0,0 @@ -package status - -// Status consists of status code from the service -type Status struct { - Code int -} - -// Checker interface used to get latest status from plugin -type Checker interface { - Status() Status -} - -// Readiness interface used to get readiness status from the plugin -// that means, that worker poll inside the plugin has 1+ plugins which are ready to work -// at the particular moment -type Readiness interface { - Ready() Status -} 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 -} diff --git a/plugins/status/rpc.go b/plugins/status/rpc.go deleted file mode 100644 index 755a06fa..00000000 --- a/plugins/status/rpc.go +++ /dev/null @@ -1,43 +0,0 @@ -package status - -import ( - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -type rpc struct { - srv *Plugin - log logger.Logger -} - -// Status return current status of the provided plugin -func (rpc *rpc) Status(service string, status *Status) error { - const op = errors.Op("checker_rpc_status") - rpc.log.Debug("started Status method", "service", service) - st, err := rpc.srv.status(service) - if err != nil { - return errors.E(op, err) - } - - *status = st - - rpc.log.Debug("status code", "code", st.Code) - rpc.log.Debug("successfully finished the Status method") - return nil -} - -// Status return current status of the provided plugin -func (rpc *rpc) Ready(service string, status *Status) error { - const op = errors.Op("checker_rpc_ready") - rpc.log.Debug("started Ready method", "service", service) - st, err := rpc.srv.ready(service) - if err != nil { - return errors.E(op, err) - } - - *status = st - - rpc.log.Debug("status code", "code", st.Code) - rpc.log.Debug("successfully finished the Ready method") - return nil -} |