Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Oct 16, 2023
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
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)
}
Loading