summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2020-12-03 13:08:38 +0300
committerValery Piashchynski <[email protected]>2020-12-03 13:08:38 +0300
commit31e4bb7b236fe0ae59fd42d66af0d718b67a2a4b (patch)
treecd51f81b20dc32666165ff85d8b8bdad0e6c464c
parentbdabf97a6463c0e3897063235f3d556d4f75c4bd (diff)
Initial commit of checker plugin
-rwxr-xr-x.github/workflows/ci-build.yml3
-rw-r--r--Makefile5
-rwxr-xr-xgo.mod5
-rwxr-xr-xgo.sum20
-rw-r--r--interfaces/informer/interface.go1
-rw-r--r--interfaces/status/interface.go11
-rw-r--r--plugins/checker/config.go5
-rw-r--r--plugins/checker/plugin.go138
-rw-r--r--plugins/checker/rpc.go28
-rwxr-xr-xplugins/checker/tests/configs/.rr-checker-init.yaml29
-rw-r--r--plugins/checker/tests/plugin_test.go82
-rw-r--r--plugins/http/plugin.go17
-rw-r--r--plugins/informer/plugin.go2
13 files changed, 342 insertions, 4 deletions
diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 7e3e9c03..49d1d1d6 100755
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -80,12 +80,13 @@ jobs:
go test -v -race -cover -tags=debug -coverprofile=static.txt -covermode=atomic ./plugins/static/tests
go test -v -race -cover -tags=debug -coverprofile=static_root.txt -covermode=atomic ./plugins/static
go test -v -race -cover -tags=debug -coverprofile=headers.txt -covermode=atomic ./plugins/headers/tests
+ go test -v -race -cover -tags=debug -coverprofile=checker.txt -covermode=atomic ./plugins/checker/tests
- name: Run code coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
- files: headers.txt, static.txt, static_root.txt, gzip.txt, lib.txt, rpc_config.txt, rpc.txt, plugin_config.txt, logger.txt, server.txt, metrics.txt, informer.txt attributes.txt http_tests.txt
+ files: checker.txt, headers.txt, static.txt, static_root.txt, gzip.txt, lib.txt, rpc_config.txt, rpc.txt, plugin_config.txt, logger.txt, server.txt, metrics.txt, informer.txt attributes.txt http_tests.txt
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
diff --git a/Makefile b/Makefile
index bcfe8d93..383b7699 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,9 @@ test:
go test -v -race -cover ./plugins/static/tests -tags=debug
go test -v -race -cover ./plugins/static -tags=debug
go test -v -race -cover ./plugins/headers/tests -tags=debug
+ go test -v -race -cover ./plugins/checker/tests -tags=debug
test_headers:
- go test -v -race -cover ./plugins/headers/tests -tags=debug \ No newline at end of file
+ go test -v -race -cover ./plugins/headers/tests -tags=debug
+test_checker:
+ go test -v -race -cover ./plugins/checker/tests -tags=debug \ No newline at end of file
diff --git a/go.mod b/go.mod
index 8eb59574..4129a3e8 100755
--- a/go.mod
+++ b/go.mod
@@ -5,11 +5,14 @@ go 1.15
require (
github.com/NYTimes/gziphandler v1.1.1
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
+ github.com/andybalholm/brotli v1.0.1 // indirect
github.com/fatih/color v1.10.0
github.com/go-ole/go-ole v1.2.4 // indirect
+ github.com/gofiber/fiber/v2 v2.2.2
github.com/golang/mock v1.4.4
github.com/hashicorp/go-multierror v1.0.0
github.com/json-iterator/go v1.1.10
+ github.com/klauspost/compress v1.11.3 // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1
github.com/shirou/gopsutil v3.20.10+incompatible
@@ -24,6 +27,6 @@ require (
go.uber.org/zap v1.16.0
golang.org/x/net v0.0.0-20201021035429-f5854403a974
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
- golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
+ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
golang.org/x/tools v0.0.0-20201119174615-0557df368a99 // indirect
)
diff --git a/go.sum b/go.sum
index 7762cc67..1e2a5ae0 100755
--- a/go.sum
+++ b/go.sum
@@ -23,6 +23,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
+github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
+github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@@ -67,6 +71,9 @@ github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-restit/lzjson v0.0.0-20161206095556-efe3c53acc68/go.mod h1:7vXSKQt83WmbPeyVjCfNT9YDJ5BUFmcwFsEjI9SCvYM=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o=
+github.com/gofiber/fiber/v2 v2.2.2 h1:D8ch8HTdVZgT5Y4c5JCPAoqNlEm+LrgIw5KkE5XTze4=
+github.com/gofiber/fiber/v2 v2.2.2/go.mod h1:Aso7/M+EQOinVkWp4LUYjdlTpKTBoCk2Qo4djnMsyHE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -143,6 +150,10 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
+github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
+github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -260,6 +271,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.17.0 h1:P8/koH4aSnJ4xbd0cUUFEGQs3jQqIxoDDyRQrUiAkqg=
+github.com/valyala/fasthttp v1.17.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -326,6 +341,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -364,6 +380,10 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
diff --git a/interfaces/informer/interface.go b/interfaces/informer/interface.go
index 42e82338..a8d32841 100644
--- a/interfaces/informer/interface.go
+++ b/interfaces/informer/interface.go
@@ -2,6 +2,7 @@ package informer
import "github.com/spiral/roadrunner/v2"
+// Informer used to get workers from particular plugin or set of plugins
type Informer interface {
Workers() []roadrunner.WorkerBase
}
diff --git a/interfaces/status/interface.go b/interfaces/status/interface.go
new file mode 100644
index 00000000..0a92bc52
--- /dev/null
+++ b/interfaces/status/interface.go
@@ -0,0 +1,11 @@
+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
+}
diff --git a/plugins/checker/config.go b/plugins/checker/config.go
new file mode 100644
index 00000000..5f952592
--- /dev/null
+++ b/plugins/checker/config.go
@@ -0,0 +1,5 @@
+package checker
+
+type Config struct {
+ Address string
+}
diff --git a/plugins/checker/plugin.go b/plugins/checker/plugin.go
new file mode 100644
index 00000000..11dce06e
--- /dev/null
+++ b/plugins/checker/plugin.go
@@ -0,0 +1,138 @@
+package checker
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/logger"
+ "github.com/spiral/endure"
+ "github.com/spiral/errors"
+ "github.com/spiral/roadrunner/v2/interfaces/log"
+ "github.com/spiral/roadrunner/v2/interfaces/status"
+ "github.com/spiral/roadrunner/v2/plugins/config"
+)
+
+const (
+ // PluginName declares public plugin name.
+ PluginName = "status"
+)
+
+type Plugin struct {
+ registry map[string]status.Checker
+ server *fiber.App
+ log log.Logger
+ cfg *Config
+}
+
+func (c *Plugin) Init(log log.Logger, cfg config.Configurer) error {
+ const op = errors.Op("status plugin init")
+ err := cfg.UnmarshalKey(PluginName, &c.cfg)
+ if err != nil {
+ return errors.E(op, err)
+ }
+ c.registry = make(map[string]status.Checker)
+ c.log = log
+ return nil
+}
+
+// localhost:88294/status/all
+func (c *Plugin) Serve() chan error {
+ errCh := make(chan error, 1)
+ c.server = fiber.New()
+ c.server.Group("/v1", c.healthHandler)
+ c.server.Use(logger.New())
+ c.server.Use("/health", c.healthHandler)
+
+ go func() {
+ err := c.server.Listen(c.cfg.Address)
+ if err != nil {
+ errCh <- err
+ }
+ }()
+
+ return errCh
+}
+
+func (c *Plugin) Stop() error {
+ return c.server.Shutdown()
+}
+
+// Reset named service.
+func (c *Plugin) Status(name string) (status.Status, error) {
+ const op = errors.Op("get status")
+ svc, ok := c.registry[name]
+ if !ok {
+ return status.Status{}, errors.E(op, errors.Errorf("no such service: %s", name))
+ }
+
+ return svc.Status(), nil
+}
+
+// CollectTarget collecting services which can provide Status.
+func (c *Plugin) CollectTarget(name endure.Named, r status.Checker) error {
+ c.registry[name.Name()] = r
+ return nil
+}
+
+// Collects declares services to be collected.
+func (c *Plugin) Collects() []interface{} {
+ return []interface{}{
+ c.CollectTarget,
+ }
+}
+
+// Name of the service.
+func (c *Plugin) Name() string {
+ return PluginName
+}
+
+// RPCService returns associated rpc service.
+func (c *Plugin) RPC() interface{} {
+ return &rpc{srv: c, log: c.log}
+}
+
+type Plugins struct {
+ Plugins []string `query:"service"`
+}
+
+const template string = "Service: %s: Status: %d\n"
+
+func (c *Plugin) healthHandler(ctx *fiber.Ctx) error {
+ const op = errors.Op("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: /v1/health?plugin=plugin1&plugin=plugin2 \n")
+ return nil
+ }
+
+ failed := false
+ // iterate over all provided plugins
+ for i := 0; i < len(plugins.Plugins); i++ {
+ // check if the plugin exists
+ if plugin, ok := c.registry[plugins.Plugins[i]]; ok {
+ st := plugin.Status()
+ if st.Code >= 500 {
+ failed = true
+ continue
+ } 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]))
+ }
+ }
+ if failed {
+ ctx.Status(http.StatusInternalServerError)
+ return nil
+ }
+
+ ctx.Status(http.StatusOK)
+ return nil
+}
diff --git a/plugins/checker/rpc.go b/plugins/checker/rpc.go
new file mode 100644
index 00000000..d03d1638
--- /dev/null
+++ b/plugins/checker/rpc.go
@@ -0,0 +1,28 @@
+package checker
+
+import (
+ "github.com/spiral/errors"
+ "github.com/spiral/roadrunner/v2/interfaces/log"
+ "github.com/spiral/roadrunner/v2/interfaces/status"
+)
+
+type rpc struct {
+ srv *Plugin
+ log log.Logger
+}
+
+// Status return current status of the provided plugin
+func (rpc *rpc) Status(service string, status *status.Status) error {
+ const op = errors.Op("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 Status method")
+ return nil
+}
diff --git a/plugins/checker/tests/configs/.rr-checker-init.yaml b/plugins/checker/tests/configs/.rr-checker-init.yaml
new file mode 100755
index 00000000..ba008853
--- /dev/null
+++ b/plugins/checker/tests/configs/.rr-checker-init.yaml
@@ -0,0 +1,29 @@
+rpc:
+ listen: tcp://127.0.0.1:6001
+ disabled: false
+
+server:
+ command: "php ../../../tests/http/client.php echo pipes"
+ user: ""
+ group: ""
+ env:
+ "RR_HTTP": "true"
+ relay: "pipes"
+ relayTimeout: "20s"
+
+status:
+ address: "127.0.0.1:34333"
+
+http:
+ debug: true
+ address: 127.0.0.1:18903
+ maxRequestSize: 1024
+ middleware: [ "" ]
+ uploads:
+ forbid: [ ".php", ".exe", ".bat" ]
+ trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ]
+ pool:
+ numWorkers: 2
+ maxJobs: 0
+ allocateTimeout: 60s
+ destroyTimeout: 60s \ No newline at end of file
diff --git a/plugins/checker/tests/plugin_test.go b/plugins/checker/tests/plugin_test.go
new file mode 100644
index 00000000..58cb45a0
--- /dev/null
+++ b/plugins/checker/tests/plugin_test.go
@@ -0,0 +1,82 @@
+package tests
+
+import (
+ "os"
+ "os/signal"
+ "sync"
+ "syscall"
+ "testing"
+ "time"
+
+ "github.com/spiral/endure"
+ "github.com/spiral/roadrunner/v2/plugins/checker"
+ "github.com/spiral/roadrunner/v2/plugins/config"
+ httpPlugin "github.com/spiral/roadrunner/v2/plugins/http"
+ "github.com/spiral/roadrunner/v2/plugins/logger"
+ "github.com/spiral/roadrunner/v2/plugins/server"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestStatusInit(t *testing.T) {
+ cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.DebugLevel))
+ assert.NoError(t, err)
+
+ cfg := &config.Viper{
+ Path: "configs/.rr-checker-init.yaml",
+ Prefix: "rr",
+ }
+
+ err = cont.RegisterAll(
+ cfg,
+ &logger.ZapLogger{},
+ &server.Plugin{},
+ &httpPlugin.Plugin{},
+ &checker.Plugin{},
+ )
+ assert.NoError(t, err)
+
+ err = cont.Init()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ch, err := cont.Serve()
+ assert.NoError(t, err)
+
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
+
+ wg := &sync.WaitGroup{}
+ wg.Add(1)
+
+ tt := time.NewTimer(time.Second * 5)
+
+ go func() {
+ defer wg.Done()
+ for {
+ select {
+ case e := <-ch:
+ assert.Fail(t, "error", e.Error.Error())
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ case <-sig:
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ case <-tt.C:
+ // timeout
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ }
+ }
+ }()
+
+ wg.Wait()
+}
diff --git a/plugins/http/plugin.go b/plugins/http/plugin.go
index 79e8aa94..371cdb91 100644
--- a/plugins/http/plugin.go
+++ b/plugins/http/plugin.go
@@ -18,6 +18,7 @@ import (
"github.com/spiral/roadrunner/v2"
"github.com/spiral/roadrunner/v2/interfaces/log"
factory "github.com/spiral/roadrunner/v2/interfaces/server"
+ "github.com/spiral/roadrunner/v2/interfaces/status"
"github.com/spiral/roadrunner/v2/plugins/config"
"github.com/spiral/roadrunner/v2/plugins/http/attributes"
"github.com/spiral/roadrunner/v2/util"
@@ -341,6 +342,22 @@ func (s *Plugin) AddMiddleware(name endure.Named, m Middleware) {
s.mdwr[name.Name()] = m
}
+// Status return status of the particular plugin
+func (s *Plugin) Status() status.Status {
+ workers := s.Workers()
+ for i := 0; i < len(workers); i++ {
+ if workers[i].State().IsActive() {
+ return status.Status{
+ Code: http.StatusOK,
+ }
+ }
+ }
+ // if there are no workers, threat this as error
+ return status.Status{
+ Code: http.StatusInternalServerError,
+ }
+}
+
func (s *Plugin) redirect(w http.ResponseWriter, r *http.Request) bool {
if s.https != nil && r.TLS == nil && s.cfg.SSL.Redirect {
target := &url.URL{
diff --git a/plugins/informer/plugin.go b/plugins/informer/plugin.go
index 09d933fd..f3013394 100644
--- a/plugins/informer/plugin.go
+++ b/plugins/informer/plugin.go
@@ -21,7 +21,7 @@ func (p *Plugin) Init(log log.Logger) error {
return nil
}
-// Reset named service.
+// Workers provides WorkerBase slice with workers for the requested plugin
func (p *Plugin) Workers(name string) ([]roadrunner.WorkerBase, error) {
const op = errors.Op("get workers")
svc, ok := p.registry[name]