Skip to content

Instantly share code, notes, and snippets.

@kirugan
Created August 9, 2023 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirugan/168c7e1f7d4e046cf3ec53974740ff21 to your computer and use it in GitHub Desktop.
Save kirugan/168c7e1f7d4e046cf3ec53974740ff21 to your computer and use it in GitHub Desktop.
HTTP server shutdown example
package server
import (
"context"
"fmt"
"io"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestShutdown(t *testing.T) {
server := http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("handler: request is made")
select {
case <-r.Context().Done():
fmt.Println("handler: context is done")
case <-time.After(time.Second * 5):
fmt.Println("handler: long operation is done")
}
}),
}
go server.ListenAndServe()
go func() {
var reader io.Reader = slowReader(5 * time.Second)
timeout := 30 * time.Second
if false {
// ^ make it true if you want to test the client connection closed
timeout = time.Second
reader = nil
}
client := http.Client{
Transport: nil,
CheckRedirect: nil,
Jar: nil,
Timeout: timeout,
}
fmt.Println("client: making http request")
_, err := client.Post("http://localhost:8080", "", reader)
assert.NoError(t, err)
fmt.Println("client: http request is done")
}()
time.Sleep(2 * time.Second)
fmt.Println("starting server shutdown")
err := server.Shutdown(context.Background())
assert.NoError(t, err)
// to wait output from all goroutines
time.Sleep(time.Second)
}
type slowReader time.Duration
func (sr slowReader) Read(_ []byte) (int, error) {
time.Sleep(time.Duration(sr))
return 0, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment