From 1143246816b8c148e26283e4bd5f8cf1836e0d90 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Mon, 3 Oct 2022 15:43:36 -0800 Subject: [PATCH] refactor server to support variable options --- backend/app/api/main.go | 6 +++- backend/pkgs/server/response.go | 2 +- backend/pkgs/server/server.go | 49 +++++++++++++++++---------- backend/pkgs/server/server_options.go | 47 +++++++++++++++++++++++++ backend/pkgs/server/server_test.go | 4 +-- backend/pkgs/server/worker.go | 2 ++ 6 files changed, 89 insertions(+), 21 deletions(-) create mode 100644 backend/pkgs/server/server_options.go diff --git a/backend/app/api/main.go b/backend/app/api/main.go index 23d3813..c159158 100644 --- a/backend/app/api/main.go +++ b/backend/app/api/main.go @@ -119,7 +119,11 @@ func run(cfg *config.Config) error { // ========================================================================= // Start Server - app.server = server.NewServer(app.conf.Web.Host, app.conf.Web.Port) + app.server = server.NewServer( + server.WithHost(app.conf.Web.Host), + server.WithPort(app.conf.Web.Port), + ) + routes := app.newRouter(app.repos) if app.conf.Mode != config.ModeDevelopment { diff --git a/backend/pkgs/server/response.go b/backend/pkgs/server/response.go index 61cebf6..cf14dd2 100644 --- a/backend/pkgs/server/response.go +++ b/backend/pkgs/server/response.go @@ -21,7 +21,7 @@ func Respond(w http.ResponseWriter, statusCode int, data interface{}) { } // Set the content type and headers once we know marshaling has succeeded. - w.Header().Set("Content-Type", "application/json") + w.Header().Set("Content-Type", ContentJSON) // Write the status code to the response. w.WriteHeader(statusCode) diff --git a/backend/pkgs/server/server.go b/backend/pkgs/server/server.go index 628f234..1cc7cf1 100644 --- a/backend/pkgs/server/server.go +++ b/backend/pkgs/server/server.go @@ -12,29 +12,44 @@ import ( "time" ) -// TODO: #2 Implement Go routine pool/job queue - -var ErrServerNotStarted = errors.New("server not started") -var ErrServerAlreadyStarted = errors.New("server already started") +var ( + ErrServerNotStarted = errors.New("server not started") + ErrServerAlreadyStarted = errors.New("server already started") +) type Server struct { - Host string - Port string - + Host string + Port string Worker Worker - wg sync.WaitGroup + + wg sync.WaitGroup started bool activeServer *http.Server + + idleTimeout time.Duration + readTimeout time.Duration + writeTimeout time.Duration } -func NewServer(host, port string) *Server { - return &Server{ - Host: host, - Port: port, - wg: sync.WaitGroup{}, - Worker: NewSimpleWorker(), +func NewServer(opts ...Option) *Server { + s := &Server{ + Host: "localhost", + Port: "8080", + Worker: NewSimpleWorker(), + idleTimeout: 30 * time.Second, + readTimeout: 10 * time.Second, + writeTimeout: 10 * time.Second, } + + for _, opt := range opts { + err := opt(s) + if err != nil { + panic(err) + } + } + + return s } func (s *Server) Shutdown(sig string) error { @@ -68,9 +83,9 @@ func (s *Server) Start(router http.Handler) error { s.activeServer = &http.Server{ Addr: s.Host + ":" + s.Port, Handler: router, - IdleTimeout: time.Minute, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, + IdleTimeout: s.idleTimeout, + ReadTimeout: s.readTimeout, + WriteTimeout: s.writeTimeout, } shutdownError := make(chan error) diff --git a/backend/pkgs/server/server_options.go b/backend/pkgs/server/server_options.go new file mode 100644 index 0000000..1029b1f --- /dev/null +++ b/backend/pkgs/server/server_options.go @@ -0,0 +1,47 @@ +package server + +import "time" + +type Option = func(s *Server) error + +func WithWorker(w Worker) Option { + return func(s *Server) error { + s.Worker = w + return nil + } +} + +func WithHost(host string) Option { + return func(s *Server) error { + s.Host = host + return nil + } +} + +func WithPort(port string) Option { + return func(s *Server) error { + s.Port = port + return nil + } +} + +func WithReadTimeout(seconds int) Option { + return func(s *Server) error { + s.readTimeout = time.Duration(seconds) * time.Second + return nil + } +} + +func WithWriteTimeout(seconds int) Option { + return func(s *Server) error { + s.writeTimeout = time.Duration(seconds) * time.Second + return nil + } +} + +func WithIdleTimeout(seconds int) Option { + return func(s *Server) error { + s.idleTimeout = time.Duration(seconds) * time.Second + return nil + } +} diff --git a/backend/pkgs/server/server_test.go b/backend/pkgs/server/server_test.go index 669182b..1d8b105 100644 --- a/backend/pkgs/server/server_test.go +++ b/backend/pkgs/server/server_test.go @@ -10,7 +10,7 @@ import ( ) func testServer(t *testing.T, r http.Handler) *Server { - svr := NewServer("127.0.0.1", "19245") + svr := NewServer(WithHost("127.0.0.1"), WithPort("19245")) go func() { err := svr.Start(r) @@ -33,7 +33,7 @@ func testServer(t *testing.T, r http.Handler) *Server { } func Test_ServerShutdown_Error(t *testing.T) { - svr := NewServer("127.0.0.1", "19245") + svr := NewServer(WithHost("127.0.0.1"), WithPort("19245")) err := svr.Shutdown("test") assert.ErrorIs(t, err, ErrServerNotStarted) diff --git a/backend/pkgs/server/worker.go b/backend/pkgs/server/worker.go index 682d5d6..acd6e25 100644 --- a/backend/pkgs/server/worker.go +++ b/backend/pkgs/server/worker.go @@ -1,5 +1,7 @@ package server +// TODO: #2 Implement Go routine pool/job queue + type Worker interface { Add(func()) }