package main import ( "context" "errors" "log" "net/http" "os" "os/signal" "syscall" "time" ) func main() { config, err := LoadConfig() if err != nil { log.Fatalf("configuration: %v", err) } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() store, err := OpenStore(ctx, config.DatabaseURL) if err != nil { log.Fatalf("database: %v", err) } defer store.Close() if err = store.Bootstrap(ctx, config); err != nil { log.Fatalf("bootstrap: %v", err) } agent := NewAgentClient(config.CredentialsDir) app, err := NewApp(store, agent, config) if err != nil { log.Fatalf("application: %v", err) } server := &http.Server{ Addr: config.ListenAddress, Handler: app, ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 10 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 16 << 10, } poller := &Poller{store: store, agent: agent, metricRetention: config.MetricsRetention, logRetention: config.LogsRetention} go poller.Run(ctx) go func() { <-ctx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() _ = server.Shutdown(shutdownCtx) }() log.Printf("control-plane API listening on %s", config.ListenAddress) if err = server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("HTTP server: %v", err) } }