diff --git a/main.go b/main.go index 5de4557..ac45528 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,17 @@ package main import ( + "context" "fmt" "html/template" "log" + "net/http" "os" + "os/signal" "path/filepath" "strings" + "syscall" + "time" "github.com/gin-gonic/gin" @@ -54,7 +59,11 @@ func main() { } // Use the relative path as template name (e.g. "layouts/base.html") name := strings.TrimPrefix(path, "templates/") - tmpl, _ = tmpl.New(name).Parse(string(data)) + t, parseErr := tmpl.New(name).Parse(string(data)) + if parseErr != nil { + log.Fatalf("failed to parse template %s: %v", name, parseErr) + } + tmpl = t return nil }) r.SetHTMLTemplate(tmpl) @@ -95,8 +104,28 @@ func main() { r.GET("/api/repos/:id/review/notes", review.GetNotes) r.POST("/api/repos/:id/review/pdf", review.GeneratePDF) - log.Printf("PR-Helper starting on :%s", cfg.Port) - if err := r.Run(":" + cfg.Port); err != nil { - log.Fatalf("failed to start server: %v", err) + // Graceful shutdown with signal handling + srv := &http.Server{ + Addr: ":" + cfg.Port, + Handler: r, } + + go func() { + log.Printf("PR-Helper starting on :%s", cfg.Port) + if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Fatalf("failed to start server: %v", err) + } + }() + + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + log.Println("shutting down server...") + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + log.Fatalf("server forced to shutdown: %v", err) + } + log.Println("server exited") }