package main import ( "context" "os" "os/signal" "syscall" "git.intra.yksa.space/gsn/predictor/internal/jobs/grib/updater" "git.intra.yksa.space/gsn/predictor/internal/pkg/grib" "git.intra.yksa.space/gsn/predictor/internal/pkg/log" "git.intra.yksa.space/gsn/predictor/internal/service" "git.intra.yksa.space/gsn/predictor/internal/transport/rest" "git.intra.yksa.space/gsn/predictor/internal/transport/rest/handler" "git.intra.yksa.space/gsn/predictor/pkg/scheduler" "go.uber.org/zap" ) const servicePrefix = "GSN_PREDICTOR" func main() { lg, err := zap.NewProduction() if err != nil { panic(err) } defer lg.Sync() ctx := log.ToCtx(context.Background(), lg) schedulerConfig, err := scheduler.NewConfig() if err != nil { log.Ctx(ctx).Fatal("failed to load scheduler configuration", zap.Error(err)) } gribUpdaterConfig, err := updater.NewConfig() if err != nil { log.Ctx(ctx).Fatal("failed to load GRIB updater configuration", zap.Error(err)) } gribCfg, err := grib.NewConfig() if err != nil { log.Ctx(ctx).Fatal("failed to load GRIB configuration", zap.Error(err)) } gribService, err := grib.New(gribCfg) if err != nil { log.Ctx(ctx).Fatal("failed to initialize GRIB service", zap.Error(err)) } defer gribService.Close() // Force GRIB update on startup in a goroutine go func() { log.Ctx(ctx).Info("Performing initial GRIB update (async)...") if err := gribService.Update(ctx); err != nil { log.Ctx(ctx).Error("initial GRIB update failed", zap.Error(err)) } else { log.Ctx(ctx).Info("initial GRIB update complete") } }() svc, err := service.New(gribService) if err != nil { log.Ctx(ctx).Fatal("failed to initialize service", zap.Error(err)) } defer svc.Close() var sched *scheduler.Scheduler if schedulerConfig.Enabled { sched = scheduler.New() gribJob := updater.New(gribService, gribUpdaterConfig) if err := sched.AddJob(gribJob); err != nil { log.Ctx(ctx).Error("failed to add GRIB update job to scheduler", zap.Error(err)) } log.Ctx(ctx).Info("scheduler initialized with jobs") } handler := handler.New(svc) restConfig, err := rest.NewConfig() if err != nil { lg.Fatal("failed to init transport config", zap.Error(err)) } transport, err := rest.New(handler, restConfig) if err != nil { lg.Fatal("failed to init transport", zap.Error(err)) } svc.Start() if sched != nil { sched.Start() lg.Info("scheduler started") } lg.Info("service started successfully") sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) go func() { lg.Info("starting HTTP server on port", zap.Int("port", restConfig.Port)) transport.Run() }() <-sigChan lg.Info("received shutdown signal, stopping service") if sched != nil { sched.Stop() lg.Info("scheduler stopped") } }