Skip to content

Commit

Permalink
fix: default to a noop listener to avoid hanging on channel messages (#…
Browse files Browse the repository at this point in the history
…143)

* fix: default to a noop listener to avoid hanging on channel messages

* feat: test that NoopListener gets added

* docs: add a description about overriding unleash sdk repo to a local path
  • Loading branch information
daveleek authored Oct 16, 2023
1 parent 6b4b49b commit b8afa6e
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 13 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ unleash.IsEnabled("someToggle", unleash.WithContext(ctx), unleash.WithResolver(r

## Development

To override dependency on unleash-client-go github repository to a local development folder (for instance when building a local test-app for the SDK),
you can add the following to your apps `go.mod`:

```mod
replace github.com/Unleash/unleash-client-go/v3 => ../unleash-client-go/
```



## Steps to release

- Update the clientVersion in `client.go`
Expand Down
28 changes: 15 additions & 13 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,22 @@ func NewClient(options ...ConfigOption) (*Client, error) {
AppName: uc.options.appName,
}

if uc.options.listener != nil {
if eListener, ok := uc.options.listener.(ErrorListener); ok {
uc.errorListener = eListener
}
if rListener, ok := uc.options.listener.(RepositoryListener); ok {
uc.repositoryListener = rListener
}
if mListener, ok := uc.options.listener.(MetricListener); ok {
uc.metricsListener = mListener
}
defer func() {
go uc.sync()
}()
if uc.options.listener == nil {
uc.options.listener = &NoopListener{}
}

if eListener, ok := uc.options.listener.(ErrorListener); ok {
uc.errorListener = eListener
}
if rListener, ok := uc.options.listener.(RepositoryListener); ok {
uc.repositoryListener = rListener
}
if mListener, ok := uc.options.listener.(MetricListener); ok {
uc.metricsListener = mListener
}
defer func() {
go uc.sync()
}()

if uc.options.url == "" {
return nil, fmt.Errorf("Unleash server URL missing")
Expand Down
28 changes: 28 additions & 0 deletions nooplistener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package unleash

// NoopListener is an implementation of all of the listener interfaces that discards
// all messages. It's added if no other listener is added to drain the channels and as
// an example of implementing the listener interfaces.
type NoopListener struct{}

func (l NoopListener) OnError(err error) {
}

func (l NoopListener) OnWarning(warning error) {
}

// The repository is ready.
func (l NoopListener) OnReady() {
}

// The feature is queried.
func (l NoopListener) OnCount(name string, enabled bool) {
}

// The server has uploaded metrics.
func (l NoopListener) OnSent(payload MetricsData) {
}

// The client has registered.
func (l NoopListener) OnRegistered(payload ClientData) {
}
24 changes: 24 additions & 0 deletions nooplistener_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package unleash

import (
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_defaultsToNoopListener(t *testing.T) {
result := Initialize(
WithAppName("my-application"),
WithUrl("http://localhost:4242"),
WithCustomHeaders(http.Header{"Authorization": {"*:development.code"}}),
)

if result != nil {
t.Fail()
}
res := IsEnabled("test", WithFallback(false))
assert.Equal(t, false, res)

assert.IsType(t, &NoopListener{}, defaultClient.errorListener)
}

0 comments on commit b8afa6e

Please sign in to comment.