package main import ( "log" "net/http" "os" "os/signal" "syscall" "time" apiv1 "git.ar21.de/yolokube/country-geo-locations/api/v1" "git.ar21.de/yolokube/country-geo-locations/internal/cache" "git.ar21.de/yolokube/country-geo-locations/internal/cmd" csvimporter "git.ar21.de/yolokube/country-geo-locations/internal/csv_importer" "git.ar21.de/yolokube/country-geo-locations/internal/database" "git.ar21.de/yolokube/country-geo-locations/internal/downloader" "git.ar21.de/yolokube/country-geo-locations/internal/exporter" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/go-chi/render" ) func main() { cli := cmd.CLI{} config, err := cli.Parse() if err != nil { log.Fatal(err) } handleGracefulShutdown() r := chi.NewRouter() r.Use(middleware.RequestID) r.Use(middleware.Logger) r.Use(middleware.Recoverer) r.Use(render.SetContentType(render.ContentTypeJSON)) ctx := downloader.NewContext(config.DataFile, config.DataURL) if !ctx.FileExists() { if downloadErr := ctx.Download(); downloadErr != nil { log.Fatal(downloadErr) } log.Printf("saved file to %s\n", ctx.Filename) } cache := cache.NewCache(config.CacheTTL) db, err := database.NewDatabase(config) if err != nil { log.Fatal("database creation failed", err) } if config.EnableExporter { exporter := exporter.NewExporter(config, cache, db) r.Use(exporter.Middleware()) ticker := time.NewTicker(config.ExporterInterval) exit := make(chan struct{}) go func() { for { select { case <-ticker.C: exporter.Collect() case <-exit: ticker.Stop() return } } }() log.Println("prometheus exporter refreshes metric data every", config.ExporterInterval) go func() { err = exporter.Start() if err != nil { log.Panic(err) } }() log.Println("prometheus exporter started at", config.ExporterAddress) } log.Println("importing data from file", config.DataFile) err = csvimporter.ImportCSV(config.DataFile, db) if err != nil { log.Fatal("data Import from file failed", err) } log.Println("imported data from file successful") lh := apiv1.NewLocationHandler(cache, db) r.Mount("/api/v1", apiv1.NewRouter(lh)) server := &http.Server{ Addr: config.ServerAddress, Handler: r, ReadHeaderTimeout: config.ReadHeaderTimeout, } log.Println("starting server at", server.Addr) if err = server.ListenAndServe(); err != nil { log.Panic(err) } } func handleGracefulShutdown() { var signals = make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) go func() { sig := <-signals log.Printf("caught signal: %+v", sig) os.Exit(0) }() }