From b480fc09b0afc2ab19be4cd28178174897e2169c Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Tue, 18 Jul 2023 12:29:08 +0200 Subject: [PATCH] Bump reva, for 'graceful_shutdown_timeout' setting --- go.mod | 2 +- go.sum | 4 +- .../reva/v2/cmd/revad/internal/grace/grace.go | 117 +++++++++++------- .../reva/v2/cmd/revad/runtime/runtime.go | 18 +-- .../storage/utils/decomposedfs/node/xattrs.go | 10 ++ .../pkg/storage/utils/decomposedfs/spaces.go | 3 + vendor/modules.txt | 2 +- 7 files changed, 98 insertions(+), 58 deletions(-) diff --git a/go.mod b/go.mod index da9d71f61d..425b38eb71 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.6.0 github.com/cs3org/go-cs3apis v0.0.0-20230516150832-730ac860c71d - github.com/cs3org/reva/v2 v2.15.0 + github.com/cs3org/reva/v2 v2.15.1-0.20230718140539-0af2a07c7fd9 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e github.com/egirna/icap-client v0.1.1 diff --git a/go.sum b/go.sum index a023b23656..525a672a52 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4= github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc= github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA= -github.com/cs3org/reva/v2 v2.15.0 h1:saU2Heig/HswkNdDHh2Jttmhsn0nfTkvaYbXUspcNOM= -github.com/cs3org/reva/v2 v2.15.0/go.mod h1:4z5EQghS2LhSWZWocH51Dw9VAs16No1zSFvFgQtgS7w= +github.com/cs3org/reva/v2 v2.15.1-0.20230718140539-0af2a07c7fd9 h1:ycV7H1siLmMiRmc9kaS0WonysHYUT7irvH4FDDAghqQ= +github.com/cs3org/reva/v2 v2.15.1-0.20230718140539-0af2a07c7fd9/go.mod h1:4z5EQghS2LhSWZWocH51Dw9VAs16No1zSFvFgQtgS7w= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= diff --git a/vendor/github.com/cs3org/reva/v2/cmd/revad/internal/grace/grace.go b/vendor/github.com/cs3org/reva/v2/cmd/revad/internal/grace/grace.go index 339a8c5c1e..8aaf18aaf5 100644 --- a/vendor/github.com/cs3org/reva/v2/cmd/revad/internal/grace/grace.go +++ b/vendor/github.com/cs3org/reva/v2/cmd/revad/internal/grace/grace.go @@ -36,13 +36,14 @@ import ( // Watcher watches a process for a graceful restart // preserving open network sockets to avoid packet loss. type Watcher struct { - log zerolog.Logger - graceful bool - ppid int - lns map[string]net.Listener - ss map[string]Server - pidFile string - childPIDs []int + log zerolog.Logger + graceful bool + ppid int + lns map[string]net.Listener + ss map[string]Server + pidFile string + childPIDs []int + gracefulShutdownTimeout int } // Option represent an option. @@ -62,6 +63,12 @@ func WithPIDFile(fn string) Option { } } +func WithGracefuleShutdownTimeout(seconds int) Option { + return func(w *Watcher) { + w.gracefulShutdownTimeout = seconds + } +} + // NewWatcher creates a Watcher. func NewWatcher(opts ...Option) *Watcher { w := &Watcher{ @@ -279,51 +286,69 @@ func (w *Watcher) TrapSignals() { } case syscall.SIGQUIT: - w.log.Info().Msg("preparing for a graceful shutdown with deadline of 10 seconds") - go func() { - count := 10 - ticker := time.NewTicker(time.Second) - for ; true; <-ticker.C { - w.log.Info().Msgf("shutting down in %d seconds", count-1) - count-- - if count <= 0 { - w.log.Info().Msg("deadline reached before draining active conns, hard stopping ...") - for _, s := range w.ss { - err := s.Stop() - if err != nil { - w.log.Error().Err(err).Msg("error stopping server") - } - w.log.Info().Msgf("fd to %s:%s abruptly closed", s.Network(), s.Address()) - } - w.Exit(1) - } - } - }() - for _, s := range w.ss { - w.log.Info().Msgf("fd to %s:%s gracefully closed ", s.Network(), s.Address()) - err := s.GracefulStop() - if err != nil { - w.log.Error().Err(err).Msg("error stopping server") - w.log.Info().Msg("exit with error code 1") - w.Exit(1) - } - } - w.log.Info().Msg("exit with error code 0") - w.Exit(0) + gracefulShutdown(w) case syscall.SIGINT, syscall.SIGTERM: - w.log.Info().Msg("preparing for hard shutdown, aborting all conns") - for _, s := range w.ss { - w.log.Info().Msgf("fd to %s:%s abruptly closed", s.Network(), s.Address()) - err := s.Stop() - if err != nil { - w.log.Error().Err(err).Msg("error stopping server") - } + if w.gracefulShutdownTimeout == 0 { + hardShutdown(w) } - w.Exit(0) + gracefulShutdown(w) } } } +// TODO: Ideally this would call exit() but properly return an error. The +// exit() is problematic (i.e. racey) especiaily when orchestrating multiple +// reva services from some external runtime (like in the "ocis server" case +func gracefulShutdown(w *Watcher) { + w.log.Info().Int("Timeout", w.gracefulShutdownTimeout).Msg("preparing for a graceful shutdown with deadline") + go func() { + count := w.gracefulShutdownTimeout + ticker := time.NewTicker(time.Second) + for ; true; <-ticker.C { + w.log.Info().Msgf("shutting down in %d seconds", count-1) + count-- + if count <= 0 { + w.log.Info().Msg("deadline reached before draining active conns, hard stopping ...") + for _, s := range w.ss { + err := s.Stop() + if err != nil { + w.log.Error().Err(err).Msg("error stopping server") + } + w.log.Info().Msgf("fd to %s:%s abruptly closed", s.Network(), s.Address()) + } + w.Exit(1) + } + } + }() + for _, s := range w.ss { + w.log.Info().Msgf("fd to %s:%s gracefully closed ", s.Network(), s.Address()) + err := s.GracefulStop() + if err != nil { + w.log.Error().Err(err).Msg("error stopping server") + w.log.Info().Msg("exit with error code 1") + + w.Exit(1) + } + } + w.log.Info().Msg("exit with error code 0") + w.Exit(0) +} + +// TODO: Ideally this would call exit() but properly return an error. The +// exit() is problematic (i.e. racey) especiaily when orchestrating multiple +// reva services from some external runtime (like in the "ocis server" case +func hardShutdown(w *Watcher) { + w.log.Info().Msg("preparing for hard shutdown, aborting all conns") + for _, s := range w.ss { + w.log.Info().Msgf("fd to %s:%s abruptly closed", s.Network(), s.Address()) + err := s.Stop() + if err != nil { + w.log.Error().Err(err).Msg("error stopping server") + } + } + w.Exit(0) +} + func getListenerFile(ln net.Listener) (*os.File, error) { switch t := ln.(type) { case *net.TCPListener: diff --git a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go index 948397b7fe..cc908d3e22 100644 --- a/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go +++ b/vendor/github.com/cs3org/reva/v2/cmd/revad/runtime/runtime.go @@ -72,6 +72,8 @@ type coreConf struct { // TracingService specifies the service. i.e OpenCensus, OpenTelemetry, OpenTracing... TracingService string `mapstructure:"tracing_service"` + + GracefulShutdownTimeout int `mapstructure:"graceful_shutdown_timeout"` } func run( @@ -92,7 +94,7 @@ func run( initCPUCount(coreConf, logger) servers := initServers(mainConf, logger, tp) - watcher, err := initWatcher(logger, filename) + watcher, err := initWatcher(logger, filename, coreConf.GracefulShutdownTimeout) if err != nil { log.Panic(err) } @@ -110,8 +112,8 @@ func initListeners(watcher *grace.Watcher, servers map[string]grace.Server, log return listeners } -func initWatcher(log *zerolog.Logger, filename string) (*grace.Watcher, error) { - watcher, err := handlePIDFlag(log, filename) +func initWatcher(log *zerolog.Logger, filename string, gracefulShutdownTimeout int) (*grace.Watcher, error) { + watcher, err := handlePIDFlag(log, filename, gracefulShutdownTimeout) // TODO(labkode): maybe pidfile can be created later on? like once a server is going to be created? if err != nil { log.Error().Err(err).Msg("error creating grace watcher") @@ -187,11 +189,11 @@ func initLogger(conf *logConf) *zerolog.Logger { return log } -func handlePIDFlag(l *zerolog.Logger, pidFile string) (*grace.Watcher, error) { - var opts []grace.Option - opts = append(opts, grace.WithPIDFile(pidFile)) - opts = append(opts, grace.WithLogger(l.With().Str("pkg", "grace").Logger())) - w := grace.NewWatcher(opts...) +func handlePIDFlag(l *zerolog.Logger, pidFile string, gracefulShutdownTimeout int) (*grace.Watcher, error) { + w := grace.NewWatcher(grace.WithPIDFile(pidFile), + grace.WithLogger(l.With().Str("pkg", "grace").Logger()), + grace.WithGracefuleShutdownTimeout(gracefulShutdownTimeout), + ) err := w.WritePID() if err != nil { return nil, err diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/xattrs.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/xattrs.go index 5545f29271..39e1725476 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/xattrs.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/xattrs.go @@ -49,6 +49,16 @@ func (md Attributes) SetInt64(key string, val int64) { md[key] = []byte(strconv.FormatInt(val, 10)) } +// UInt64 reads an uint64 value +func (md Attributes) UInt64(key string) (uint64, error) { + return strconv.ParseUint(string(md[key]), 10, 64) +} + +// SetInt64 sets an uint64 value +func (md Attributes) SetUInt64(key string, val uint64) { + md[key] = []byte(strconv.FormatUint(val, 10)) +} + // SetXattrs sets multiple extended attributes on the write-through cache/node func (n *Node) SetXattrsWithContext(ctx context.Context, attribs map[string][]byte, acquireLock bool) (err error) { if n.xattrsCache != nil { diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spaces.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spaces.go index e04927e2a2..cc72cced20 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spaces.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/spaces.go @@ -122,6 +122,9 @@ func (fs *Decomposedfs) CreateStorageSpace(ctx context.Context, req *provider.Cr metadata.SetString(prefixes.NameAttr, req.Name) metadata.SetString(prefixes.SpaceNameAttr, req.Name) + // This space is empty so set initial treesize to 0 + metadata.SetUInt64(prefixes.TreesizeAttr, 0) + if req.Type != "" { metadata.SetString(prefixes.SpaceTypeAttr, req.Type) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3bdf891d84..2c0054fa3c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -352,7 +352,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.15.0 +# github.com/cs3org/reva/v2 v2.15.1-0.20230718140539-0af2a07c7fd9 ## explicit; go 1.20 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime