package importer import ( "context" "os" "os/signal" "syscall" "time" "github.com/rs/zerolog" "go.uber.org/fx" "sneak.berlin/go/directory/internal/config" "sneak.berlin/go/directory/internal/globals" "sneak.berlin/go/directory/internal/logger" "sneak.berlin/go/directory/internal/store" ) type ImporterParams struct { fx.In Logger *logger.Logger Globals *globals.Globals Config *config.Config Store *store.Store } type Importer struct { startupTime time.Time exitCode int log *zerolog.Logger params ImporterParams ctx context.Context cancelFunc context.CancelFunc } func New(lc fx.Lifecycle, params ImporterParams) (*Importer, error) { i := new(Importer) i.params = params i.log = params.Logger.Get() lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { i.startupTime = time.Now() go i.Run(ctx) return nil }, OnStop: func(ctx context.Context) error { i.cleanShutdown(ctx) return nil }, }) return i, nil } func (i *Importer) Run(ctx context.Context) { i.ctx, i.cancelFunc = context.WithCancel(ctx) rootCmd := setupCommands(i) go func() { c := make(chan os.Signal, 1) signal.Ignore(syscall.SIGPIPE) signal.Notify(c, os.Interrupt, syscall.SIGTERM) sig := <-c i.log.Info().Msgf("signal received: %+v", sig) if i.cancelFunc != nil { i.cancelFunc() } }() if err := rootCmd.ExecuteContext(i.ctx); err != nil { i.log.Error().Err(err).Msg("command execution failed") i.exitCode = 1 } <-i.ctx.Done() i.exitCode = 0 i.cleanShutdown(ctx) } func (i *Importer) cleanShutdown(ctx context.Context) { i.log.Info().Msgf("shutting down") os.Exit(i.exitCode) }