mirror of
https://github.com/hanzo-fi/stack.git
synced 2026-10-30 20:34:43 +00:00
81 lines
1.9 KiB
Go
81 lines
1.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/formancehq/stack/libs/go-libs/logging"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
const DebugFlag = "debug"
|
|
const JsonFormattingLoggerFlag = "json-formatting-logger"
|
|
|
|
type App struct {
|
|
options []fx.Option
|
|
output io.Writer
|
|
}
|
|
|
|
func (a *App) Run(ctx context.Context) error {
|
|
logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag))
|
|
app := a.newFxApp(logger)
|
|
if err := app.Start(logging.ContextWithLogger(ctx, logger)); err != nil {
|
|
return err
|
|
}
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
case <-app.Done():
|
|
// <-app.Done() is a signals channel, it means we have to call the
|
|
// app.Stop in order to gracefully shutdown the app
|
|
}
|
|
|
|
logger.Infof("Stopping app...")
|
|
|
|
return app.Stop(logging.ContextWithLogger(contextWithLifecycle(
|
|
context.Background(), // Don't reuse original context as it can have been cancelled, and we really need to properly stop the app
|
|
lifecycleFromContext(ctx),
|
|
), logger))
|
|
}
|
|
|
|
func (a *App) Start(ctx context.Context) error {
|
|
logger := GetDefaultLogger(a.output, viper.GetBool(DebugFlag), viper.GetBool(JsonFormattingLoggerFlag))
|
|
return a.newFxApp(logger).Start(ctx)
|
|
}
|
|
|
|
func (a *App) newFxApp(logger logging.Logger) *fx.App {
|
|
options := append(a.options,
|
|
fx.NopLogger,
|
|
fx.Supply(fx.Annotate(logger, fx.As(new(logging.Logger)))),
|
|
fx.Invoke(func(lc fx.Lifecycle) {
|
|
lc.Append(fx.Hook{
|
|
OnStart: func(ctx context.Context) error {
|
|
markAsAppReady(ctx)
|
|
|
|
return nil
|
|
},
|
|
})
|
|
}),
|
|
)
|
|
options = append([]fx.Option{
|
|
fx.Invoke(func(lc fx.Lifecycle) {
|
|
lc.Append(fx.Hook{
|
|
OnStop: func(ctx context.Context) error {
|
|
markAsAppStopped(ctx)
|
|
|
|
return nil
|
|
},
|
|
})
|
|
}),
|
|
}, options...)
|
|
return fx.New(options...)
|
|
}
|
|
|
|
func New(output io.Writer, options ...fx.Option) *App {
|
|
return &App{
|
|
options: options,
|
|
output: output,
|
|
}
|
|
}
|