@@ -3,10 +3,12 @@ package toxiproxy
33import (
44 "context"
55 "encoding/json"
6+ "errors"
67 "fmt"
78 "net/http"
89 "os"
910 "strings"
11+ "sync"
1012 "time"
1113
1214 "github.com/gorilla/mux"
@@ -34,7 +36,9 @@ type ApiServer struct {
3436 Collection * ProxyCollection
3537 Metrics * metricsContainer
3638 Logger * zerolog.Logger
37- http * http.Server
39+
40+ initOnce sync.Once // guards shutdown
41+ shutdown func (ctx context.Context ) error
3842}
3943
4044const (
@@ -50,42 +54,45 @@ func NewServer(m *metricsContainer, logger zerolog.Logger) *ApiServer {
5054 }
5155}
5256
53- func (server * ApiServer ) Listen (addr string ) error {
54- server .Logger .
55- Info ().
56- Str ("address" , addr ).
57- Msg ("Starting Toxiproxy HTTP server" )
57+ var errServerStarted = errors .New ("server already started" )
5858
59- server .http = & http.Server {
60- Addr : addr ,
61- Handler : server .Routes (),
62- WriteTimeout : wait_timeout ,
63- ReadTimeout : read_timeout ,
64- IdleTimeout : 60 * time .Second ,
59+ func (server * ApiServer ) Listen (addr string ) error {
60+ var s * http.Server
61+ server .initOnce .Do (func () {
62+ server .Logger .
63+ Info ().
64+ Str ("address" , addr ).
65+ Msg ("Starting Toxiproxy HTTP server" )
66+
67+ s = & http.Server {
68+ Addr : addr ,
69+ Handler : server .Routes (),
70+ WriteTimeout : wait_timeout ,
71+ ReadTimeout : read_timeout ,
72+ IdleTimeout : 60 * time .Second ,
73+ }
74+ })
75+ if s == nil {
76+ return errServerStarted
6577 }
6678
67- err := server .http .ListenAndServe ()
68- if err == http .ErrServerClosed {
69- err = nil
79+ server .shutdown = s .Shutdown
80+ err := s .ListenAndServe ()
81+ if errors .Is (err , http .ErrServerClosed ) {
82+ return nil
7083 }
71-
7284 return err
7385}
7486
7587func (server * ApiServer ) Shutdown () error {
76- if server .http == nil {
77- return nil
88+ server .initOnce .Do (func () {})
89+ if server .shutdown == nil {
90+ return nil // in desire state
7891 }
7992
8093 ctx , cancel := context .WithTimeout (context .Background (), wait_timeout )
8194 defer cancel ()
82-
83- err := server .http .Shutdown (ctx )
84- if err != nil {
85- return err
86- }
87-
88- return nil
95+ return server .shutdown (ctx )
8996}
9097
9198func (server * ApiServer ) Routes () * mux.Router {
0 commit comments