Add base setup
This commit is contained in:
commit
b8fcd14ebe
7
closers.go
Normal file
7
closers.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package curre
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Closer interface {
|
||||||
|
Close(ctx context.Context) error
|
||||||
|
}
|
7
component.go
Normal file
7
component.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package curre
|
||||||
|
|
||||||
|
type Component interface {
|
||||||
|
Initer
|
||||||
|
Starter
|
||||||
|
Closer
|
||||||
|
}
|
15
default_logger.go
Normal file
15
default_logger.go
Normal 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...)
|
||||||
|
}
|
7
initer.go
Normal file
7
initer.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package curre
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Initer interface {
|
||||||
|
Init(ctx context.Context) error
|
||||||
|
}
|
18
lifetime.go
Normal file
18
lifetime.go
Normal 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
6
logger.go
Normal 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
121
manager.go
Normal 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
7
starter.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package curre
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Starter interface {
|
||||||
|
Start(ctx context.Context) error
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user