Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,48 @@ func RegisterInstrumentation(router *mux.Router) {
router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
}

// Run the server; blocks until SIGTERM is received.
func (s *Server) Run() {
go s.httpServer.Serve(s.httpListener)
// Run the server; blocks until SIGTERM or an error is received.
func (s *Server) Run() error {
errChan := make(chan error)

// Wait for a signal
go func() {
s.handler.Loop()
select {
case errChan <- nil:
default:
}
}()

go func() {
err := s.httpServer.Serve(s.httpListener)
if err == http.ErrServerClosed {
err = nil
}

select {
case errChan <- err:
default:
}
}()

// Setup gRPC server
// for HTTP over gRPC, ensure we don't double-count the middleware
httpgrpc.RegisterHTTPServer(s.GRPC, httpgrpc_server.NewServer(s.HTTP))
go s.GRPC.Serve(s.grpcListener)

// Wait for a signal
s.handler.Loop()
go func() {
err := s.GRPC.Serve(s.grpcListener)
if err == grpc.ErrServerStopped {
err = nil
}

select {
case errChan <- err:
default:
}
}()

return <-errChan
}

// Stop unblocks Run().
Expand Down
37 changes: 37 additions & 0 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,40 @@ func TestErrorInstrumentationMiddleware(t *testing.T) {
"/server.FakeServer/Succeed": "success",
}, statuses)
}

func TestRunReturnsError(t *testing.T) {
cfg := Config{
HTTPListenPort: 9190,
GRPCListenPort: 9191,
}
t.Run("http", func(t *testing.T) {
cfg.MetricsNamespace = "testing_http"
srv, err := New(cfg)
require.NoError(t, err)

errChan := make(chan error, 1)
go func() {
errChan <- srv.Run()
}()

require.NoError(t, srv.httpListener.Close())
require.NotNil(t, <-errChan)

// So that address is freed for further tests.
srv.GRPC.Stop()
})

t.Run("grpc", func(t *testing.T) {
cfg.MetricsNamespace = "testing_grpc"
srv, err := New(cfg)
require.NoError(t, err)

errChan := make(chan error, 1)
go func() {
errChan <- srv.Run()
}()

require.NoError(t, srv.grpcListener.Close())
require.NotNil(t, <-errChan)
})
}