From 77b310464c9adbb6a970b5313b324469fb14ea49 Mon Sep 17 00:00:00 2001 From: Cyril Galibern Date: Fri, 22 Sep 2023 16:55:21 +0200 Subject: [PATCH] drop package daemon/subdaemon --- daemon/subdaemon/action.go | 157 --------------------------------- daemon/subdaemon/funcopts.go | 21 ----- daemon/subdaemon/interfaces.go | 20 ----- daemon/subdaemon/main.go | 84 ------------------ 4 files changed, 282 deletions(-) delete mode 100644 daemon/subdaemon/action.go delete mode 100644 daemon/subdaemon/funcopts.go delete mode 100644 daemon/subdaemon/interfaces.go delete mode 100644 daemon/subdaemon/main.go diff --git a/daemon/subdaemon/action.go b/daemon/subdaemon/action.go deleted file mode 100644 index 861ce98e5..000000000 --- a/daemon/subdaemon/action.go +++ /dev/null @@ -1,157 +0,0 @@ -package subdaemon - -import ( - "context" - "fmt" - "sort" -) - -// Start starts the control loop, the main loop and sub daemons -func (t *T) Start(ctx context.Context) error { - t.ctx, t.cancel = context.WithCancel(ctx) - if err := t.startControl(); err != nil { - return err - } - if err := t.do("start"); err != nil { - return err - } - return nil -} - -// Stop stops the sub daemons, then the main loop, and the control loop -func (t *T) Stop() error { - if !t.enabled.Enabled() { - t.log.Debug().Msg("already stopped") - return nil - } - if err := t.do("stop"); err != nil { - t.log.Error().Err(err).Msg("stop") - return err - } - t.Wait() - return nil -} - -// Restart chains stop and start -func (t *T) Restart(ctx context.Context) error { - if err := t.Stop(); err != nil { - return err - } - t.log.Debug().Msg("restart reached the bottom") - if err := t.Start(ctx); err != nil { - return err - } - return nil -} - -func (t *T) startControl() error { - if t.enabled.Enabled() { - // for ex: restart, start-start - return nil - } - running := make(chan bool) - t.Add(1) - go func() { - defer t.Done() - running <- true - t.controlLoop() - }() - <-running - t.log.Debug().Msg("enable control") - t.enabled.Enable() - return nil -} - -func (t *T) controlLoop() { - for { - select { - case <-t.ctx.Done(): - // stop receiving new commands, but don't exit the loop - // so the stop handler exits with a last result. - t.enabled.Disable() - case a := <-t.controlChan: - switch a.name { - case "start": - a.done <- t.start() - case "stop": - if err := t.stop(); err != nil { - a.done <- err - return - } - t.disable() - a.done <- nil - return // exit control routine - default: - a.done <- fmt.Errorf("unknown action: %s", a.name) - } - } - } -} - -// call via do() only for serialization -func (t *T) stop() error { - if !t.Running() { - t.log.Debug().Msgf("already stopped") - return nil - } - newChildren := make([]Manager, 0) - for i := len(t.children) - 1; i >= 0; i -= 1 { - sub := t.children[i] - name := sub.Name() - if err := sub.Stop(); err != nil { - // prevent sub unregistering - newChildren = append(newChildren, sub) - t.log.Error().Err(err).Msgf("stop %s failed", name) - } - } - sort.SliceStable(newChildren, func(i, j int) bool { - return i > j - }) - t.children = newChildren - if err := t.main.MainStop(); err != nil { - t.log.Error().Err(err).Msg("main stop failed") - return err - } - t.running.Disable() - t.cancel() // exits the control loop - t.log.Info().Msgf("stopped children and main") - return nil -} - -// call via do() only for serialization -func (t *T) start() error { - if t.Running() { - t.log.Debug().Msg("already started") - return nil - } - t.log.Debug().Msg("start") - if err := t.main.MainStart(t.ctx); err != nil { - t.log.Error().Err(err).Msg("start") - return err - } - t.running.Enable() - t.log.Info().Msgf("started") - return nil -} - -// call via do() only for serialization -func (t *T) Register(sub Manager) error { - t.children = append(t.children, sub) - return nil -} - -// do is a synchronous controlAction submitter -func (t *T) do(what string) error { - if !t.enabled.Enabled() { - err := fmt.Errorf("disabled sub") - t.log.Error().Err(err).Msgf("%s", what) - return err - } - t.log.Debug().Msgf("queue %s", what) - resChan := make(chan error) - t.controlChan <- controlAction{what, resChan} - if err := <-resChan; err != nil { - return err - } - return nil -} diff --git a/daemon/subdaemon/funcopts.go b/daemon/subdaemon/funcopts.go deleted file mode 100644 index 4cafd7e86..000000000 --- a/daemon/subdaemon/funcopts.go +++ /dev/null @@ -1,21 +0,0 @@ -package subdaemon - -import ( - "github.com/opensvc/om3/util/funcopt" -) - -func WithName(name string) funcopt.O { - return funcopt.F(func(i interface{}) error { - t := i.(*T) - t.name = name - return nil - }) -} - -func WithMainManager(mgr Manager) funcopt.O { - return funcopt.F(func(i interface{}) error { - t := i.(*T) - t.main = mgr - return nil - }) -} diff --git a/daemon/subdaemon/interfaces.go b/daemon/subdaemon/interfaces.go deleted file mode 100644 index 38c3eb1ed..000000000 --- a/daemon/subdaemon/interfaces.go +++ /dev/null @@ -1,20 +0,0 @@ -package subdaemon - -import "context" - -type ( - Manager interface { - Running() bool - Start(context.Context) error - Stop() error - MainStart(context.Context) error - MainStop() error - Name() string - Register(Manager) error - } - - RootManager interface { - Running() bool - Stop() error - } -) diff --git a/daemon/subdaemon/main.go b/daemon/subdaemon/main.go deleted file mode 100644 index baee97498..000000000 --- a/daemon/subdaemon/main.go +++ /dev/null @@ -1,84 +0,0 @@ -/* - Package subDaemon provides main and sub daemon management features - - Start, Stop, Restart - - 1 go routines is used to serialize Start/Stop/Restart - - A subdaemon can have subdaemons -*/ -package subdaemon - -import ( - "context" - "sync" - - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - - "github.com/opensvc/om3/daemon/enable" - "github.com/opensvc/om3/util/funcopt" - "github.com/opensvc/om3/util/hostname" -) - -type ( - T struct { - sync.WaitGroup - ctx context.Context - cancel context.CancelFunc - name string - log zerolog.Logger - children []Manager - main Manager - controlChan chan controlAction - enabled *enable.T - running *enable.T - } - - controlAction struct { - name string - done chan error - } -) - -func (t *T) Log() zerolog.Logger { - return t.log -} - -func (t *T) Name() string { - if t == nil { - return "" - } - return t.name -} - -// Enabled() returns true is daemon control actions are handled -func (t T) Enabled() bool { - return t.enabled.Enabled() -} - -// no more register or control action are then possible -func (t *T) disable() { - t.log.Debug().Msg("disable") - t.enabled.Disable() -} - -// Running() returns true when MainManager daemon has been started -func (t *T) Running() bool { - return t.running.Enabled() -} - -func New(opts ...funcopt.O) *T { - t := &T{ - enabled: enable.New(), - running: enable.New(), - controlChan: make(chan controlAction), - children: make([]Manager, 0), - } - if err := funcopt.Apply(t, opts...); err != nil { - t.log.Error().Err(err).Msg("subdaemon funcopt.Apply") - return nil - } - t.log = log.Logger.With().Str("sub", t.name).Str("n", hostname.Hostname()).Logger() - return t -}