diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 87 |
1 files changed, 68 insertions, 19 deletions
@@ -3,7 +3,10 @@ package main import ( "flag" "log/slog" + "os" + "os/signal" "sync" + "syscall" "github.com/SayaAndy/saya-today-thumbnail-generator/config" "github.com/SayaAndy/saya-today-thumbnail-generator/internal/client/input" @@ -12,33 +15,47 @@ import ( ) var ( - configPath = flag.String("c", "config.json", "Path to the configuration file") + configPath = flag.String("c", "config.json", "Path to the configuration file") + sigTermChan = make(chan os.Signal, 1) ) func main() { - flag.Parse() + signal.Notify(sigTermChan, os.Interrupt, syscall.SIGTERM) - slog.Info("starting thumbnail generator...") - // slog.SetLogLoggerLevel(slog.LevelDebug) + flag.Parse() cfg := &config.Config{} if err := config.LoadConfig(*configPath, cfg); err != nil { - panic(err) + slog.Error("fail to load configuration", slog.String("error", err.Error())) + os.Exit(1) + } + + slog.SetLogLoggerLevel(cfg.LogLevel) + slog.Info("starting thumbnail generator...") + + select { + case <-sigTermChan: + slog.Info("exiting due to termination signal") + os.Exit(130) + default: } inputClient, err := input.NewB2InputClient(&cfg.Input) if err != nil { - panic(err) + slog.Error("fail to initialize input client", slog.String("error", err.Error())) + os.Exit(1) } outputClient, err := output.NewB2OutputClient(&cfg.Output) if err != nil { - panic(err) + slog.Error("fail to initialize output client", slog.String("error", err.Error())) + os.Exit(1) } converter, err := processor.NewWebpProcessor(&cfg.Processor) if err != nil { - panic(err) + slog.Error("fail to initialize converter", slog.String("error", err.Error())) + os.Exit(1) } generalLogger := slog.With( @@ -48,35 +65,59 @@ func main() { ) generalLogger.Info("initialized clients and processor") + select { + case <-sigTermChan: + generalLogger.Info("exiting due to termination signal") + os.Exit(130) + default: + } + files, err := inputClient.Scan() if err != nil { - panic(err) + generalLogger.Error("fail to scan input files", slog.String("error", err.Error())) + os.Exit(1) } generalLogger.Info("scanned files", slog.Int("file_count", len(files))) + select { + case <-sigTermChan: + generalLogger.Info("exiting due to termination signal") + os.Exit(130) + default: + } + semaphore := make(chan struct{}, cfg.MaxConcurrentJobs) var wg sync.WaitGroup wg.Add(len(files)) for i, file := range files { go func(index int, inputName string) { - semaphore <- struct{}{} - defer func() { <-semaphore }() - defer wg.Done() - outputName := converter.DeductOutputPath(inputName) fileLogger := generalLogger.With(slog.String("input_path", inputName), slog.String("output_path", outputName), slog.Int("file_index", index)) + threadSigTermChannel := make(chan os.Signal, 1) + signal.Notify(threadSigTermChannel, os.Interrupt, syscall.SIGTERM) + + defer func() { <-semaphore }() + defer wg.Done() + semaphore <- struct{}{} + select { + case <-threadSigTermChannel: + fileLogger.Info("exiting due to termination signal") + return + default: + } + inputMetadata, err := inputClient.ReadMetadata(inputName) if err != nil { - fileLogger.Error("fail to read metadata of (supposedly existing) input file", slog.String("error", err.Error())) + fileLogger.Warn("fail to read metadata of (supposedly existing) input file", slog.String("error", err.Error())) return } if !cfg.ForceRewrite && !outputClient.IsMissing(outputName) { outputMetadata, err := outputClient.ReadMetadata(outputName) if err != nil { - fileLogger.Error("fail to read metadata of (supposedly existing) output file", slog.String("error", err.Error())) + fileLogger.Warn("fail to read metadata of (supposedly existing) output file", slog.String("error", err.Error())) return } if inputMetadata.Hash == outputMetadata.HashOriginal { @@ -88,18 +129,18 @@ func main() { fileLogger.Info("start to process file") reader, err := inputClient.GetReader(inputName) if err != nil { - fileLogger.Error("fail to get reader for input file", slog.String("error", err.Error())) + fileLogger.Warn("fail to get reader for input file", slog.String("error", err.Error())) return } writer, err := outputClient.GetWriter(outputName, inputMetadata) if err != nil { - fileLogger.Error("fail to get writer for output file", slog.String("error", err.Error())) + fileLogger.Warn("fail to get writer for output file", slog.String("error", err.Error())) return } if err := converter.Process(inputMetadata.ContentType, reader, writer); err != nil { - fileLogger.Error("fail to convert file", slog.String("error", err.Error())) + fileLogger.Warn("fail to convert file", slog.String("error", err.Error())) return } @@ -108,5 +149,13 @@ func main() { } wg.Wait() - generalLogger.Info("all files processed successfully, exiting") + + select { + case <-sigTermChan: + generalLogger.Info("exiting due to termination signal") + os.Exit(130) + default: + generalLogger.Info("all files processed successfully, exiting") + os.Exit(0) + } } |