Skip to content

Commit

Permalink
change server listening pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
fredcarle committed Aug 5, 2022
1 parent bda3cc4 commit 51c4026
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 13 deletions.
6 changes: 6 additions & 0 deletions api/http/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package http

import (
"context"
"errors"
"fmt"
"net/http"
"os"
Expand All @@ -20,6 +21,11 @@ import (

var env = os.Getenv("DEFRA_ENV")

var (
errNoListener = errors.New("cannot serve with no listener")
errSchema = errors.New("base must start with the http or https scheme")
)

type errorResponse struct {
Errors []errorItem `json:"errors"`
}
Expand Down
4 changes: 1 addition & 3 deletions api/http/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ const (
PeerIDPath string = versionedAPIPath + "/peerid"
)

var schemeError = errors.New("base must start with the http or https scheme")

func setRoutes(h *handler) *handler {
h.Mux = chi.NewRouter()

Expand Down Expand Up @@ -70,7 +68,7 @@ func setRoutes(h *handler) *handler {
// The base must start with a http or https.
func JoinPaths(base string, paths ...string) (*url.URL, error) {
if !strings.HasPrefix(base, "http") {
return nil, schemeError
return nil, errSchema
}

u, err := url.Parse(base)
Expand Down
4 changes: 2 additions & 2 deletions api/http/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ func TestJoinPathsWithBase(t *testing.T) {

func TestJoinPathsWithNoBase(t *testing.T) {
_, err := JoinPaths("", BlocksPath, "cid_of_some_sort")
assert.ErrorIs(t, schemeError, err)
assert.ErrorIs(t, errSchema, err)
}

func TestJoinPathsWithBaseWithoutHttpPrefix(t *testing.T) {
_, err := JoinPaths("localhost:9181", BlocksPath, "cid_of_some_sort")
assert.ErrorIs(t, schemeError, err)
assert.ErrorIs(t, errSchema, err)
}

func TestJoinPathsWithNoPaths(t *testing.T) {
Expand Down
26 changes: 22 additions & 4 deletions api/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
package http

import (
"context"
"net"
"net/http"

"github.com/sourcenetwork/defradb/client"
)

// Server struct holds the Handler for the HTTP API.
type Server struct {
options serverOptions
options serverOptions
listener net.Listener

http.Server
}

Expand Down Expand Up @@ -66,7 +70,21 @@ func WithPeerID(id string) func(*Server) {
}
}

// Listen calls ListenAndServe with our router.
func (s *Server) Listen() error {
return s.ListenAndServe()
// Listen creates a new net.Listener and saves it on the receiver.
func (s *Server) Listen(ctx context.Context) error {
lc := net.ListenConfig{}
l, err := lc.Listen(ctx, "tcp", s.Addr)
if err != nil {
return err
}
s.listener = l
return nil
}

// Run calls Serve with the reveiver's listener
func (s *Server) Run() error {
if s.listener == nil {
return errNoListener
}
return s.Serve(s.listener)
}
21 changes: 17 additions & 4 deletions api/http/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,31 @@ import (
"github.com/stretchr/testify/assert"
)

func TestNewServerAndListen(t *testing.T) {
func TestNewServerAndRunWithoutListener(t *testing.T) {
s := NewServer(nil, WithAddress(":3131"))
if ok := assert.NotNil(t, s); ok {
assert.Equal(t, errNoListener, s.Run())
}
}

func TestNewServerAndRunWithListenerAndInvalidPort(t *testing.T) {
ctx := context.Background()
s := NewServer(nil, WithAddress(":303000"))
if ok := assert.NotNil(t, s); ok {
assert.Error(t, s.Listen())
assert.Error(t, s.Listen(ctx))
}
}

func TestNewServerAndRunWithListenerAndValidPort(t *testing.T) {
ctx := context.Background()
serverRunning := make(chan struct{})
serverDone := make(chan struct{})
s = NewServer(nil, WithAddress(":3131"))
s := NewServer(nil, WithAddress(":3131"))
go func() {
close(serverRunning)
err := s.Listen()
err := s.Listen(ctx)
assert.NoError(t, err)
err = s.Run()
assert.ErrorIs(t, http.ErrServerClosed, err)
defer close(serverDone)
}()
Expand Down

0 comments on commit 51c4026

Please sign in to comment.