Skip to content

Instantly share code, notes, and snippets.

@stevehobbsdev
Created September 2, 2025 09:31
Show Gist options
  • Save stevehobbsdev/d34d8363871d6e11d1841fd7d82193c3 to your computer and use it in GitHub Desktop.
Save stevehobbsdev/d34d8363871d6e11d1841fd7d82193c3 to your computer and use it in GitHub Desktop.
Minimal multi-http server example with cancellation
package main
import (
"context"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"syscall"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
cancelChannel := make(chan os.Signal, 1)
signal.Notify(cancelChannel, os.Interrupt, os.Signal(syscall.SIGTERM))
go func() {
<-cancelChannel
cancel()
}()
mux := http.NewServeMux()
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello, World!"))
}))
mux2 := http.NewServeMux()
mux2.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello from server 2"))
}))
server := &http.Server{
Addr: ":8080",
Handler: mux,
BaseContext: func(listener net.Listener) context.Context {
return ctx
},
}
server2 := &http.Server{
Addr: ":8081",
Handler: mux2,
BaseContext: func(listener net.Listener) context.Context {
return ctx
},
}
serverChannel := make(chan error, 1)
go func() {
fmt.Println("starting server 1")
serverChannel <- server.ListenAndServe()
}()
server2Channel := make(chan error, 1)
go func() {
fmt.Println("starting server 2")
server2Channel <- server2.ListenAndServe()
}()
select {
case <-ctx.Done():
fmt.Println("shutting down server")
server.Shutdown(ctx)
server2.Shutdown(ctx)
case err := <-serverChannel:
fmt.Printf("server stopped: %v\n", err)
case err := <-server2Channel:
fmt.Printf("server2 stopped: %v\n", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment