From 98dd9a970f679636f2f5dd25082f2401ae1aec9a Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 3 Mar 2021 15:05:21 +0100 Subject: [PATCH] suture runtime v1 --- ocis/go.mod | 2 +- ocis/pkg/runtime/runtime.go | 40 +++++++++++++++++++++++++-------- settings/cmd/settings/main.go | 3 ++- settings/pkg/command/root.go | 33 ++++++++++++++++++++++++--- settings/pkg/command/server.go | 3 +-- settings/pkg/config/config.go | 4 ++++ settings/pkg/flagset/flagset.go | 9 +++----- 7 files changed, 72 insertions(+), 22 deletions(-) diff --git a/ocis/go.mod b/ocis/go.mod index 22423d7fb..424238825 100644 --- a/ocis/go.mod +++ b/ocis/go.mod @@ -32,7 +32,7 @@ require ( github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.7.0 - github.com/thejerf/suture v4.0.0+incompatible // indirect + github.com/thejerf/suture v4.0.0+incompatible go.opencensus.io v0.23.0 golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b ) diff --git a/ocis/pkg/runtime/runtime.go b/ocis/pkg/runtime/runtime.go index 502e48e4f..fe8adb2c1 100644 --- a/ocis/pkg/runtime/runtime.go +++ b/ocis/pkg/runtime/runtime.go @@ -1,12 +1,16 @@ package runtime import ( + "context" "fmt" golog "log" "net/rpc" "os" + "os/signal" "time" + "github.com/thejerf/suture" + "github.com/rs/zerolog" mzlog "github.com/asim/go-micro/plugins/logger/zerolog/v3" @@ -15,7 +19,7 @@ import ( "github.com/owncloud/ocis/ocis/pkg/config" "github.com/owncloud/ocis/ocis/pkg/runtime/process" - "github.com/owncloud/ocis/ocis/pkg/runtime/service" + settings "github.com/owncloud/ocis/settings/pkg/command" ) var ( @@ -72,13 +76,35 @@ func New(cfg *config.Config) Runtime { } } +// serviceTokens keeps in memory a set of [service name] = []suture.ServiceToken that is used to shutdown services. +// Shutting down a service implies removing it from the supervisor AND cancelling its context, this should be done +// within the service Stop() method. Services should cancel their context. +type serviceTokens map[string][]suture.ServiceToken + // Start rpc runtime func (r *Runtime) Start() error { setMicroLogger(r.c.Log) - go r.Launch() - return service.Start( - service.WithLogPretty(r.c.Log.Pretty), - ) + halt := make(chan os.Signal, 1) + signal.Notify(halt, os.Interrupt) + + // tokens are used to keep track of the services + tokens := serviceTokens{} + supervisor := suture.NewSimple("ocis") + globalCtx, globalCancel := context.WithCancel(context.Background()) + + // TODO(refs + jfd) + // - to avoid this getting out of hands, a supervisor would need to be injected on each supervised service. + // - each service would then add its execute func to the supervisor, and return its token (?) + // - this runtime should only care about start / stop services, for that we use serviceTokens. + + tokens["settings"] = append(tokens["settings"], supervisor.Add(settings.NewSutureService(globalCtx, r.c.Settings))) + + go supervisor.ServeBackground() + + <-halt + globalCancel() + close(halt) + return nil } // for logging reasons we don't want the same logging level on both oCIS and micro. As a framework builder we do not @@ -116,10 +142,6 @@ func (r *Runtime) Launch() { } OUT: - //for _, v := range MicroServices { - // RunService(client, v) - //} - for _, v := range Extensions { RunService(client, v) } diff --git a/settings/cmd/settings/main.go b/settings/cmd/settings/main.go index 03449298b..56ced7764 100644 --- a/settings/cmd/settings/main.go +++ b/settings/cmd/settings/main.go @@ -4,10 +4,11 @@ import ( "os" "github.com/owncloud/ocis/settings/pkg/command" + "github.com/owncloud/ocis/settings/pkg/config" ) func main() { - if err := command.Execute(); err != nil { + if err := command.Execute(config.New()); err != nil { os.Exit(1) } } diff --git a/settings/pkg/command/root.go b/settings/pkg/command/root.go index 6998566a3..b0c6de1b3 100644 --- a/settings/pkg/command/root.go +++ b/settings/pkg/command/root.go @@ -1,6 +1,7 @@ package command import ( + "context" "os" "strings" @@ -13,9 +14,7 @@ import ( ) // Execute is the entry point for the ocis-settings command. -func Execute() error { - cfg := config.New() - +func Execute(cfg *config.Config) error { app := &cli.App{ Name: "ocis-settings", Version: version.String, @@ -108,3 +107,31 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error { return nil } + +// SutureService allows for the settings command to be embedded and supervised by a suture supervisor tree. +type SutureService struct { + ctx context.Context + cancel context.CancelFunc // used to cancel the context go-micro services used to shutdown a service. + cfg *config.Config +} + +// NewSutureService creates a new settings.SutureService +func NewSutureService(ctx context.Context, cfg *config.Config) SutureService { + sctx, scancel := context.WithCancel(ctx) + cfg.Context = sctx // propagate the context down to the go-micro services. + return SutureService{ + ctx: sctx, + cancel: scancel, + cfg: cfg, + } +} + +func (s SutureService) Serve() { + if err := Execute(s.cfg); err != nil { + panic(err) + } +} + +func (s SutureService) Stop() { + s.cancel() +} diff --git a/settings/pkg/command/server.go b/settings/pkg/command/server.go index bba330480..e2880970c 100644 --- a/settings/pkg/command/server.go +++ b/settings/pkg/command/server.go @@ -146,8 +146,7 @@ func Server(cfg *config.Config) *cli.Command { http.Context(ctx), http.Config(cfg), http.Metrics(mtrcs), - http.Flags(flagset.RootWithConfig(config.New())), - http.Flags(flagset.ServerWithConfig(config.New())), + http.Context(cfg.Context), ) gr.Add(server.Run, func(_ error) { diff --git a/settings/pkg/config/config.go b/settings/pkg/config/config.go index 3b8a20201..7e9a512f6 100644 --- a/settings/pkg/config/config.go +++ b/settings/pkg/config/config.go @@ -1,5 +1,7 @@ package config +import "context" + // Log defines the available logging configuration. type Log struct { Level string @@ -66,6 +68,8 @@ type Config struct { Tracing Tracing Asset Asset TokenManager TokenManager + + Context context.Context } // New initializes a new configuration with or without defaults. diff --git a/settings/pkg/flagset/flagset.go b/settings/pkg/flagset/flagset.go index a84964c89..9ae640d7f 100644 --- a/settings/pkg/flagset/flagset.go +++ b/settings/pkg/flagset/flagset.go @@ -10,23 +10,20 @@ func RootWithConfig(cfg *config.Config) []cli.Flag { return []cli.Flag{ &cli.StringFlag{ Name: "log-level", - Value: "info", Usage: "Set logging level", - EnvVars: []string{"SETTINGS_LOG_LEVEL"}, + EnvVars: []string{"OCIS_LOG_LEVEL"}, Destination: &cfg.Log.Level, }, &cli.BoolFlag{ Name: "log-pretty", - Value: true, Usage: "Enable pretty logging", - EnvVars: []string{"SETTINGS_LOG_PRETTY"}, + EnvVars: []string{"OCIS_LOG_PRETTY"}, Destination: &cfg.Log.Pretty, }, &cli.BoolFlag{ Name: "log-color", - Value: true, Usage: "Enable colored logging", - EnvVars: []string{"SETTINGS_LOG_COLOR"}, + EnvVars: []string{"OCIS_LOG_COLOR"}, Destination: &cfg.Log.Color, }, }