Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security VideosIBM Technology: Why Did The AI Race Just Change? 🏁(25.09.2026 um 18:00 Uhr)
••
YouTube Security VideosIBM Technology: Prompt to Production: The Future of AI Code Workflows(28.09.2026 um 13:00 Uhr)
•
YouTube Security VideosVisual Studio Code: 5 Shortcuts You Need in VS Code ⚡(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMeteomatics doubles weather forecast output with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMindwalk cuts drug discovery compute time with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosVDURA advances AI data infrastructure performance with AMD(28.09.2026 um 16:00 Uhr)
•
YouTube Security VideosThe Hated One: IT'S HAPPENING...(25.09.2026 um 17:15 Uhr)
•
YouTube Security VideosTechquickie: Every Intel Chip Name in 7 minutes(25.09.2026 um 21:34 Uhr)
•
Podcasts & Audio BriefingsTechLinked: Anyway,(26.09.2026 um 02:40 Uhr)
•
YouTube Security VideosIBM Technology: Why Did The AI Race Just Change? 🏁(25.09.2026 um 18:00 Uhr)
••
YouTube Security VideosIBM Technology: Prompt to Production: The Future of AI Code Workflows(28.09.2026 um 13:00 Uhr)
•
YouTube Security VideosVisual Studio Code: 5 Shortcuts You Need in VS Code ⚡(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMeteomatics doubles weather forecast output with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMindwalk cuts drug discovery compute time with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosVDURA advances AI data infrastructure performance with AMD(28.09.2026 um 16:00 Uhr)
•
YouTube Security VideosThe Hated One: IT'S HAPPENING...(25.09.2026 um 17:15 Uhr)
•
YouTube Security VideosTechquickie: Every Intel Chip Name in 7 minutes(25.09.2026 um 21:34 Uhr)
•
Podcasts & Audio BriefingsTechLinked: Anyway,(26.09.2026 um 02:40 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

Graceful Server In Golang

In this post, we'll walk through how to set up a graceful HTTP server in Golang that handles three crucial life cycle stages: Prestart, Start, and Shutdown. We'll also discuss why handling these life cycles gracefully is…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

In this post, we'll walk through how to set up a graceful HTTP server in Golang that handles three crucial life cycle stages: Prestart, Start, and Shutdown. We'll also discuss why handling these life cycles gracefully is important.



Introduction

When building servers, it's vital to manage the server lifecycle effectively to ensure reliability and uptime. Graceful shutdowns, in particular, allow your server to finish processing ongoing requests before shutting down, which is critical in production environments.



Server life cycle diagram



We will focus on the "Start" step first.





  • Start




package main

import (
"fmt"
"io"
"net"
"net/http"
)

var port = "8080"

type gracefulServer struct {
httpServer *http.Server
listener net.Listener
}

func (server *gracefulServer) start() error {
listener, err := net.Listen("tcp", server.httpServer.Addr)
if err != nil {
return err
}

server.listener = listener
go server.httpServer.Serve(server.listener)
fmt.Println("Server now listening on " + server.httpServer.Addr)
return nil
}

func handle(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello student!\n")
}

// Initialize a new server instance and return reference.
func newServer(port string) *gracefulServer {
mux := http.NewServeMux()
mux.HandleFunc("/", handle)
httpServer := &http.Server{Addr: ":" + port, Handler: mux}
return &gracefulServer{httpServer: httpServer}
}

func main() {
server := newServer(port)
server.start()
}






We’ve added a start() method on our server type. This allows the instance of gracefulServer returned by our newServer method to have a start life cycle method called on it. We essentially create a listener that can receive TCP communication, and then we spawn a goroutine to monitor incoming requests and serve our response to them. If we run the code given above, we should see that the server starts on port 8080 and prints the same to the output console.



Well, our listening is happening in a goroutine! The listener has been detached from the main thread. So, technically, when we run start() in our main function, the execution ends and the program quits, closing all open subprocesses.



To solve this we will need to implement a wait and shutdown properly.





  • Shutdown




package main

import (
"flag"
"io"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
)

type gracefulServer struct {
httpServer *http.Server
listener net.Listener
}

func (server *gracefulServer) start() error {
listener, err := net.Listen(
"tcp",
server.httpServer.Addr,
)
if err != nil {
return err
}

server.listener = listener
go server.httpServer.Serve(server.listener)
log.Default().Printf("Server now listening on %s\n", server.httpServer.Addr)
return nil
}

func (s *gracefulServer) shutdown() error {
if s.listener != nil {
err := s.listener.Close()
s.listener = nil
if err != nil {
return err
}
}

log.Default().Println("Shutting down server")
return nil
}

func handle(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello student!\n")
}

func newServer(port string) *gracefulServer {
mux := http.NewServeMux()
mux.HandleFunc("/", handle)
httpServer := &http.Server{Addr: ":" + port, Handler: mux}
return &gracefulServer{httpServer: httpServer}
}

func main() {

// This is how you would get command line arguments
// passed to your binary at runtime.
// The last parameter in StringVar is actually a
// usage help text in case someone messes up.
var port string
flag.StringVar(&port, "port", "8080", "./server -port 8080")
flag.Parse()

done := make(chan bool, 1)

// New channel for OS signals
interrupts := make(chan os.Signal, 1)
// Set up the channel to be notified on the following signals
signal.Notify(interrupts, syscall.SIGINT, syscall.SIGTERM)

server := newServer(port)
err := server.start()
if err != nil {
log.Fatalf("Error starting server - %v\n", err)
}

// Goroutine to set up the shutdown flow
go func() {
sig := <-interrupts
log.Default().Printf("Signal intercepted - %v\n", sig)
server.shutdown()
done <- true
}()

// Wait for the shutdown flow to send true
<-done
}






As you can see we added a new channel to receive one OS signal called interrupts. Next we set up the channel to be notified whenever our OS emits SIGTERM or SIGINT. We created a goroutine to listen to the interrupts channel and gracefully call shutdown. After the shutdown is completed, we emit a boolean to our done channel, allowing the main thread to proceed with the execution, therefore bringing our server life cycle to an elegant close.





  • Prestart




package main

import (
"io"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
)

var welcomeMsg = "Welcome to the graceful server! 💃🏼\n"

type gracefulServer struct {
httpServer *http.Server
listener net.Listener
}

func withSimpleLogger(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Default().Printf("Incoming traffic on route %s", r.URL.Path)
handler.ServeHTTP(w, r)
})
}

func (server *gracefulServer) preStart() {
server.httpServer.Handler = withSimpleLogger(server.httpServer.Handler)
}

func (server *gracefulServer) start() error {
listener, err := net.Listen(
"tcp",
server.httpServer.Addr,
)
if err != nil {
return err
}

server.listener = listener
go server.httpServer.Serve(server.listener)
log.Default().Printf("Server now listening on %s\n", server.httpServer.Addr)
return nil
}

func (s *gracefulServer) shutdown() error {
if s.listener != nil {
err := s.listener.Close()
s.listener = nil
if err != nil {
return err
}
}

log.Default().Println("Shutting down server")
return nil
}

func handle(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello student!\n")
}

func greetingHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, welcomeMsg)
}

func newServer(port string) *gracefulServer {
mux := http.NewServeMux()
mux.HandleFunc("/", handle)
mux.HandleFunc("/greeting", greetingHandler)

httpServer := &http.Server{Addr: ":" + port, Handler: mux}
return &gracefulServer{httpServer: httpServer}
}

func main() {

port := "8080"
done := make(chan bool, 1)
interrupts := make(chan os.Signal, 1)
signal.Notify(interrupts, syscall.SIGINT, syscall.SIGTERM)

server := newServer(port)
server.preStart()
err := server.start()
if err != nil {
log.Fatalf("Error starting server - %v\n", err)
}

go func() {
sig := <-interrupts
log.Default().Printf("Signal intercepted - %v\n", sig)
server.shutdown()
done <- true
}()

<-done
}






We added a preStart() method to gracefulServer, just like our other life cycle methods. This one modifies the server’s handler to add another middleware that logs the path of all incoming traffic. Then we invoke this method in our main function before we invoke start(). And there we go! We have successfully added a prestart hook to our server and learned how to add middleware to our routes.



A graceful server is not just about elegant shutdowns—it's about building reliable, maintainable, and production-ready applications. The patterns we've implemented provide a solid foundation that scales with your application's growth.




A graceful server doesn't just shut down elegantly—it lives elegantly, handling every phase of its lifecycle with purpose and reliability.




Found this helpful? Share it with your fellow Go developers!

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Graceful Server In Golang

Thematisch verwandte Begriffe: Graceful, Server, Golang · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-101901 | Axios is a promise-based HTTP client for the browser and Node.js. From …
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag