Skip to content

Instantly share code, notes, and snippets.

@Harsimran1
Last active February 4, 2024 03:45
Show Gist options
  • Save Harsimran1/657166f32bc63c0c3994f88d6a935fb6 to your computer and use it in GitHub Desktop.
Save Harsimran1/657166f32bc63c0c3994f88d6a935fb6 to your computer and use it in GitHub Desktop.
Gracefully shutdown go api server connected to database
package main
import (
"context"
"database/sql"
"fmt"
"os/signal"
"syscall"
"time"
"log"
"net/http"
"os"
// pq is postgres driver for database/sql
_ "github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", fmt.Sprintf(
"user=%s password=%s dbname=%s host=%s sslmode=%s port=%d",
"postgres", "postgres", "postgres", "localhost", "disable", 5432),
)
if err != nil {
log.Fatal(err)
}
defer closeDB(db)
router := http.NewServeMux()
router.HandleFunc("/probes/readiness", func(res http.ResponseWriter, req *http.Request) {
if err := db.PingContext(req.Context()); err != nil {
res.WriteHeader(503)
}
})
srv := &http.Server{
Handler: router,
Addr: fmt.Sprintf(":%s", "8081"),
}
go func() {
panic(srv.ListenAndServe())
}()
// Create channel for shutdown signals.
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
signal.Notify(stop, syscall.SIGTERM)
//Recieve shutdown signals.
<-stop
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Printf("error shutting down server %s", err)
} else {
log.Println("Server gracefully stopped")
}
}
func closeDB(db io.Closer) {
if err := db.Close(); err != nil {
_ = log.Println(errors.Wrap(err, "err closing db connection"))
} else {
_ = log.Println("db connection gracefully closed")
}
}
@mateusfmello
Copy link

Hello, this way the connection to the database is terminated only after closing all operations on the database?

In short, just wait for the shutdown signal and run the "db.Close()" method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment