Skip to content
Draft
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
313 changes: 256 additions & 57 deletions client.go

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestClientRaw(t *testing.T) {
s.SetConcurrency(1)

s.ConnContext = func(ctx context.Context, c *Async) context.Context {
return context.WithValue(ctx, clientConnContextKey, c)
return context.WithValue(ctx, clientConnContextKey, c) //nolint:staticcheck
}

serverConn, clientConn, err := pair.New()
Expand All @@ -81,7 +81,7 @@ func TestClientRaw(t *testing.T) {
c, err := NewClient(clientHandlerTable, context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
require.NoError(t, err)
Expand Down Expand Up @@ -124,7 +124,9 @@ func TestClientRaw(t *testing.T) {
assert.Equal(t, clientBytes, serverBuffer)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
err = rawClientConn.Close()
assert.NoError(t, err)

Expand Down Expand Up @@ -172,7 +174,7 @@ func TestClientStaleClose(t *testing.T) {
c, err := NewClient(clientHandlerTable, context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
require.NoError(t, err)
Expand All @@ -197,7 +199,9 @@ func TestClientStaleClose(t *testing.T) {
assert.ErrorIs(t, err, ConnectionClosed)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}

err = s.Shutdown()
assert.NoError(t, err)
Expand Down
15 changes: 7 additions & 8 deletions frisbee.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ import (

// These are various frisbee errors that can be returned by the client or server:
var (
InvalidContentLength = errors.New("invalid content length")
ConnectionClosed = errors.New("connection closed")
StreamClosed = errors.New("stream closed")
InvalidStreamPacket = errors.New("invalid stream packet")
ConnectionNotInitialized = errors.New("connection not initialized")
InvalidBufferLength = errors.New("invalid buffer length")
InvalidHandlerTable = errors.New("invalid handler table configuration, a reserved value may have been used")
InvalidOperation = errors.New("invalid operation in packet, a reserved value may have been used")
InvalidContentLength = errors.New("invalid content length")
ConnectionClosed = errors.New("connection closed")
StreamClosed = errors.New("stream closed")
InvalidStreamPacket = errors.New("invalid stream packet")
InvalidBufferLength = errors.New("invalid buffer length")
InvalidHandlerTable = errors.New("invalid handler table configuration, a reserved value may have been used")
InvalidOperation = errors.New("invalid operation in packet, a reserved value may have been used")
)

// Action is an ENUM used to modify the state of the client or server from a Handler function
Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ go 1.18

require (
github.com/loopholelabs/common v0.4.9
github.com/loopholelabs/polyglot v1.1.2
github.com/loopholelabs/polyglot v1.1.3
github.com/loopholelabs/testing v0.2.3
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.30.0
github.com/rs/zerolog v1.31.0
github.com/stretchr/testify v1.8.4
go.uber.org/atomic v1.11.0
go.uber.org/goleak v1.2.1
Expand All @@ -16,9 +16,9 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/sys v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
25 changes: 13 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,32 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/loopholelabs/common v0.4.9 h1:9MPUYlZZ/qx3Kt8LXgXxcSXthrM91od8026c4DlGpAU=
github.com/loopholelabs/common v0.4.9/go.mod h1:Wop5srN1wYT+mdQ9gZ+kn2I9qKAyVd0FB48pThwIa9M=
github.com/loopholelabs/polyglot v1.1.2 h1:9JE1m/IL8rgWIlykvebz98i4tjOGNOpgGIB3CqbfvrE=
github.com/loopholelabs/polyglot v1.1.2/go.mod h1:EA88BEkIluKHAWxhyOV88xXz68YkRdo9IzZ+1dj+7Ao=
github.com/loopholelabs/polyglot v1.1.3 h1:WUTcSZ2TQ1lv7CZ4I9nHFBUjf0hKJN+Yfz1rZZJuTP0=
github.com/loopholelabs/polyglot v1.1.3/go.mod h1:EA88BEkIluKHAWxhyOV88xXz68YkRdo9IzZ+1dj+7Ao=
github.com/loopholelabs/testing v0.2.3 h1:4nVuK5ctaE6ua5Z0dYk2l7xTFmcpCYLUeGjRBp8keOA=
github.com/loopholelabs/testing v0.2.3/go.mod h1:gqtGY91soYD1fQoKQt/6kP14OYpS7gcbcIgq5mc9m8Q=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
9 changes: 9 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var DefaultLogger = zerolog.New(io.Discard)
type Options struct {
KeepAlive time.Duration
Logger *zerolog.Logger
Reconnect bool
TLSConfig *tls.Config
}

Expand Down Expand Up @@ -89,3 +90,11 @@ func WithTLS(tlsConfig *tls.Config) Option {
opts.TLSConfig = tlsConfig
}
}

// WithReconnect allows users to define whether the frisbee client should attempt to reconnect to the server
// if the connection is lost. By default, this is set to false.
func WithReconnect(reconnect bool) Option {
return func(opts *Options) {
opts.Reconnect = reconnect
}
}
4 changes: 3 additions & 1 deletion options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ func TestIndividualOptions(t *testing.T) {
keepAliveOption := WithKeepAlive(time.Minute * 6)
loggerOption := WithLogger(&logger)
TLSOption := WithTLS(tlsConfig)
ReconnectOption := WithReconnect(true)

options := loadOptions(keepAliveOption, loggerOption, TLSOption)
options := loadOptions(keepAliveOption, loggerOption, TLSOption, ReconnectOption)

assert.Equal(t, time.Minute*6, options.KeepAlive)
assert.Equal(t, &logger, options.Logger)
assert.Equal(t, tlsConfig, options.TLSConfig)
assert.Equal(t, true, options.Reconnect)
}
61 changes: 40 additions & 21 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestServerRawSingle(t *testing.T) {
s.SetConcurrency(1)

s.ConnContext = func(ctx context.Context, c *Async) context.Context {
return context.WithValue(ctx, serverConnContextKey, c)
return context.WithValue(ctx, serverConnContextKey, c) //nolint:staticcheck
}

serverConn, clientConn, err := pair.New()
Expand All @@ -86,7 +86,7 @@ func TestServerRawSingle(t *testing.T) {
assert.NoError(t, err)

_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
assert.NoError(t, err)
Expand Down Expand Up @@ -133,7 +133,9 @@ func TestServerRawSingle(t *testing.T) {
assert.Equal(t, serverBytes, clientBuffer[:read])

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
err = rawClientConn.Close()
assert.NoError(t, err)

Expand Down Expand Up @@ -180,7 +182,7 @@ func TestServerStaleCloseSingle(t *testing.T) {
c, err := NewClient(clientHandlerTable, context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
require.NoError(t, err)
Expand All @@ -205,7 +207,9 @@ func TestServerStaleCloseSingle(t *testing.T) {
assert.ErrorIs(t, err, ConnectionClosed)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}

err = s.Shutdown()
assert.NoError(t, err)
Expand Down Expand Up @@ -261,7 +265,7 @@ func TestServerMultipleConnectionsSingle(t *testing.T) {
clients[i], err = NewClient(clientTables[i], context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = clients[i].Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = clients[i].Connect(listenAddr)
require.NoError(t, err)
Expand All @@ -288,7 +292,9 @@ func TestServerMultipleConnectionsSingle(t *testing.T) {
}
<-finished[idx]
err := clients[idx].Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
clientWg.Done()
packet.Put(p)
}()
Expand Down Expand Up @@ -343,7 +349,7 @@ func TestServerRawUnlimited(t *testing.T) {
s.SetConcurrency(0)

s.ConnContext = func(ctx context.Context, c *Async) context.Context {
return context.WithValue(ctx, serverConnContextKey, c)
return context.WithValue(ctx, serverConnContextKey, c) //nolint:staticcheck
}

serverConn, clientConn, err := pair.New()
Expand All @@ -355,7 +361,7 @@ func TestServerRawUnlimited(t *testing.T) {
assert.NoError(t, err)

_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
assert.NoError(t, err)
Expand Down Expand Up @@ -402,7 +408,9 @@ func TestServerRawUnlimited(t *testing.T) {
assert.Equal(t, serverBytes, clientBuffer)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
err = rawClientConn.Close()
assert.NoError(t, err)

Expand Down Expand Up @@ -451,7 +459,7 @@ func TestServerStaleCloseUnlimited(t *testing.T) {
c, err := NewClient(clientHandlerTable, context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
require.NoError(t, err)
Expand All @@ -476,7 +484,9 @@ func TestServerStaleCloseUnlimited(t *testing.T) {
assert.ErrorIs(t, err, ConnectionClosed)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}

err = s.Shutdown()
assert.NoError(t, err)
Expand Down Expand Up @@ -538,7 +548,7 @@ func TestServerMultipleConnectionsUnlimited(t *testing.T) {
clients[i], err = NewClient(clientTables[i], context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = clients[i].Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = clients[i].Connect(listenAddr)
require.NoError(t, err)
Expand All @@ -565,7 +575,9 @@ func TestServerMultipleConnectionsUnlimited(t *testing.T) {
}
<-finished[idx]
err := clients[idx].Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
clientWg.Done()
packet.Put(p)
}()
Expand Down Expand Up @@ -620,7 +632,7 @@ func TestServerRawLimited(t *testing.T) {
s.SetConcurrency(10)

s.ConnContext = func(ctx context.Context, c *Async) context.Context {
return context.WithValue(ctx, serverConnContextKey, c)
return context.WithValue(ctx, serverConnContextKey, c) //nolint:staticcheck
}

serverConn, clientConn, err := pair.New()
Expand All @@ -632,7 +644,7 @@ func TestServerRawLimited(t *testing.T) {
assert.NoError(t, err)

_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
assert.NoError(t, err)
Expand Down Expand Up @@ -679,7 +691,10 @@ func TestServerRawLimited(t *testing.T) {
assert.Equal(t, serverBytes, clientBuffer)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}

err = rawClientConn.Close()
assert.NoError(t, err)

Expand Down Expand Up @@ -728,7 +743,7 @@ func TestServerStaleCloseLimited(t *testing.T) {
c, err := NewClient(clientHandlerTable, context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = c.Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = c.FromConn(clientConn)
require.NoError(t, err)
Expand All @@ -753,7 +768,9 @@ func TestServerStaleCloseLimited(t *testing.T) {
assert.ErrorIs(t, err, ConnectionClosed)

err = c.Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}

err = s.Shutdown()
assert.NoError(t, err)
Expand Down Expand Up @@ -816,7 +833,7 @@ func TestServerMultipleConnectionsLimited(t *testing.T) {
clients[i], err = NewClient(clientTables[i], context.Background(), WithLogger(&emptyLogger))
assert.NoError(t, err)
_, err = clients[i].Raw()
assert.ErrorIs(t, ConnectionNotInitialized, err)
assert.ErrorIs(t, ErrNotInitialized, err)

err = clients[i].Connect(listenAddr)
require.NoError(t, err)
Expand All @@ -843,7 +860,9 @@ func TestServerMultipleConnectionsLimited(t *testing.T) {
}
<-finished[idx]
err := clients[idx].Close()
assert.NoError(t, err)
if err != nil {
assert.ErrorIs(t, err, ErrAlreadyClosed)
}
clientWg.Done()
packet.Put(p)
}()
Expand Down