Add base setup

This commit is contained in:
Kasper Juul Hermansen 2022-09-10 01:19:29 +02:00
commit b8fcd14ebe
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
9 changed files with 191 additions and 0 deletions

7
closers.go Normal file
View File

@ -0,0 +1,7 @@
package curre
import "context"
type Closer interface {
Close(ctx context.Context) error
}

7
component.go Normal file
View File

@ -0,0 +1,7 @@
package curre
type Component interface {
Initer
Starter
Closer
}

15
default_logger.go Normal file
View File

@ -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...)
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.front.kjuulh.io/kjuulh/curre
go 1.19

7
initer.go Normal file
View File

@ -0,0 +1,7 @@
package curre
import "context"
type Initer interface {
Init(ctx context.Context) error
}

18
lifetime.go Normal file
View File

@ -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
}

6
logger.go Normal file
View File

@ -0,0 +1,6 @@
package curre
type Logger interface {
Info(msg string, args ...any)
Error(msg string, args ...any)
}

121
manager.go Normal file
View File

@ -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
}

7
starter.go Normal file
View File

@ -0,0 +1,7 @@
package curre
import "context"
type Starter interface {
Start(ctx context.Context) error
}