From b8fcd14ebe39441a5450eac71a4612f0ee34fb15 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 10 Sep 2022 01:19:29 +0200 Subject: [PATCH] Add base setup --- closers.go | 7 +++ component.go | 7 +++ default_logger.go | 15 ++++++ go.mod | 3 ++ initer.go | 7 +++ lifetime.go | 18 +++++++ logger.go | 6 +++ manager.go | 121 ++++++++++++++++++++++++++++++++++++++++++++++ starter.go | 7 +++ 9 files changed, 191 insertions(+) create mode 100644 closers.go create mode 100644 component.go create mode 100644 default_logger.go create mode 100644 go.mod create mode 100644 initer.go create mode 100644 lifetime.go create mode 100644 logger.go create mode 100644 manager.go create mode 100644 starter.go diff --git a/closers.go b/closers.go new file mode 100644 index 0000000..a9d84a3 --- /dev/null +++ b/closers.go @@ -0,0 +1,7 @@ +package curre + +import "context" + +type Closer interface { + Close(ctx context.Context) error +} diff --git a/component.go b/component.go new file mode 100644 index 0000000..d7b4843 --- /dev/null +++ b/component.go @@ -0,0 +1,7 @@ +package curre + +type Component interface { + Initer + Starter + Closer +} diff --git a/default_logger.go b/default_logger.go new file mode 100644 index 0000000..aacd3de --- /dev/null +++ b/default_logger.go @@ -0,0 +1,15 @@ +package curre + +import "fmt" + +type DefaultLogger struct{} + +var _ Logger = &DefaultLogger{} + +func (dl *DefaultLogger) Info(msg string, args ...any) { + fmt.Printf(msg, args...) +} + +func (dl *DefaultLogger) Error(msg string, args ...any) { + fmt.Printf(msg, args...) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..246e4d6 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.front.kjuulh.io/kjuulh/curre + +go 1.19 diff --git a/initer.go b/initer.go new file mode 100644 index 0000000..6fac353 --- /dev/null +++ b/initer.go @@ -0,0 +1,7 @@ +package curre + +import "context" + +type Initer interface { + Init(ctx context.Context) error +} diff --git a/lifetime.go b/lifetime.go new file mode 100644 index 0000000..c8082b5 --- /dev/null +++ b/lifetime.go @@ -0,0 +1,18 @@ +package curre + +import ( + "os" + "os/signal" + "syscall" +) + +type Lifetime func() int + +func ConsoleLifetime() int { + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + + <-signals + + return OK +} diff --git a/logger.go b/logger.go new file mode 100644 index 0000000..fd4761b --- /dev/null +++ b/logger.go @@ -0,0 +1,6 @@ +package curre + +type Logger interface { + Info(msg string, args ...any) + Error(msg string, args ...any) +} diff --git a/manager.go b/manager.go new file mode 100644 index 0000000..a217a80 --- /dev/null +++ b/manager.go @@ -0,0 +1,121 @@ +package curre + +import ( + "context" + "sync" +) + +const ( + OK = 0 + Internal = 1 +) + +type Manager struct { + components []Component + logger Logger + startStopLock sync.Mutex + started bool + exitChan chan int + exitCode int + lifetime Lifetime +} + +func NewManager() *Manager { + return &Manager{ + logger: &DefaultLogger{}, exitChan: make(chan int, 1), + exitCode: OK, + } +} + +func (m *Manager) Register(components ...Component) *Manager { + if m.started { + panic("cannot register to a started manager") + } + + m.components = append(m.components, components...) + + return m +} + +func (m *Manager) Init(ctx context.Context) error { + if m.started { + panic("cannot reinit a started manager") + } + + for _, c := range m.components { + err := c.Init(ctx) + if err != nil { + return err + } + + m.logger.Info("Manager: Init: %T", c) + } + + return nil +} + +func (m *Manager) Start(ctx context.Context) error { + for _, c := range m.components { + go m.startComponent(ctx, c) + } + + return nil +} + +func (m *Manager) startComponent(ctx context.Context, component Component) { + defer func() { + err := recover() + if err != nil { + m.logger.Error("Panic occurred in component: %T, error: %s", component, err) + } + + m.exitChan <- Internal + }() + + m.logger.Info("Starting %T", component) + err := component.Start(ctx) + if err != nil { + m.logger.Error("Component: %T encountered an error: ", component, err) + m.exitChan <- Internal + return + } + + m.logger.Info("Component %T, done running", component) + +} + +func (m *Manager) initLifetime() { + go func() { + exitCode := m.lifetime() + m.logger.Info("Exit signal received: %d", exitCode) + m.exitChan <- exitCode + }() +} + +func (m *Manager) Wait(ctx context.Context) error { + exitCode := <-m.exitChan + m.exitCode = exitCode + return nil +} + +func (m *Manager) Shutdown(ctx context.Context) error { + shutdownChan := make(chan struct{}, 1) + closers := m.getClosers(ctx) + + go func(ctx context.Context) { + for _, c := range closers { + c.Close(ctx) + } + + shutdownChan <- struct{}{} + }(ctx) + + <-shutdownChan + m.logger.Info("Shutting down of components complete") + + return nil +} + +func (m *Manager) getClosers(ctx context.Context) []Component { + return m.components +} diff --git a/starter.go b/starter.go new file mode 100644 index 0000000..5083701 --- /dev/null +++ b/starter.go @@ -0,0 +1,7 @@ +package curre + +import "context" + +type Starter interface { + Start(ctx context.Context) error +}