From cf8ed7bd725b476c84e3b4ac2b821b4751a7133e Mon Sep 17 00:00:00 2001
From: Ophestra Umiker <cat@ophivana.moe>
Date: Fri, 11 Oct 2024 20:48:56 +0900
Subject: [PATCH] fix: clean shutdown via signal

The `app.Listen` method only returns when `app.Shutdown` is called.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
---
 app.go      | 13 ++++++++++++-
 main.go     | 13 ++++++++-----
 register.go | 14 +++++++++-----
 3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/app.go b/app.go
index 76e48a9..403e270 100644
--- a/app.go
+++ b/app.go
@@ -1,7 +1,9 @@
 package main
 
 import (
+	"fmt"
 	"log"
+	"os"
 	"time"
 
 	"github.com/gofiber/fiber/v2"
@@ -9,7 +11,7 @@ import (
 	"github.com/gofiber/fiber/v2/middleware/limiter"
 )
 
-func serve() error {
+func serve(sig chan os.Signal) error {
 	app := fiber.New()
 
 	// cors
@@ -38,5 +40,14 @@ func serve() error {
 		return c.Next()
 	})
 
+	// graceful shutdown
+	go func() {
+		<-sig
+		log.Println("shutting down")
+		if err := app.Shutdown(); err != nil {
+			fmt.Printf("cannot shutdown: %v", err)
+		}
+	}()
+
 	return app.Listen(conf[listenAddr])
 }
diff --git a/main.go b/main.go
index 64f6fd7..71568b3 100644
--- a/main.go
+++ b/main.go
@@ -2,11 +2,11 @@ package main
 
 import (
 	"log"
-	"regexp"
+	"os"
+	"os/signal"
+	"syscall"
 )
 
-var emailRegex = regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
-
 func main() {
 
 	if err := InitDB(conf[dbPath]); err != nil {
@@ -15,8 +15,11 @@ func main() {
 
 	defer CloseDB()
 
-	if err := serve(); err != nil {
-		log.Printf("cannot serve: %s", err)
+	sig := make(chan os.Signal, 1)
+	signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
+
+	if err := serve(sig); err != nil {
+		log.Printf("cannot serve: %v", err)
 	}
 
 	log.Println("application exit")
diff --git a/register.go b/register.go
index de99ce9..afe37f5 100644
--- a/register.go
+++ b/register.go
@@ -2,17 +2,21 @@ package main
 
 import (
 	"log"
+	"regexp"
 
 	"github.com/gofiber/fiber/v2"
 )
 
+var emailRegexp = regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
+
+type registration struct {
+	Email string `json:"email"`
+}
+
 // Waitlist registration route
 func routeRegister(app *fiber.App) {
 	app.Post("/register", func(c *fiber.Ctx) error {
-		type Request struct {
-			Email string `json:"email"`
-		}
-		req := new(Request)
+		req := new(registration)
 
 		if err := c.BodyParser(req); err != nil {
 			log.Printf("Invalid request body: %v", err)
@@ -22,7 +26,7 @@ func routeRegister(app *fiber.App) {
 		}
 
 		// Validate email format
-		if !emailRegex.MatchString(req.Email) {
+		if !emailRegexp.MatchString(req.Email) {
 			log.Printf("Invalid email format: %s", req.Email)
 			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
 				"message": "Invalid email format",
-- 
GitLab