@@ -3,6 +3,7 @@ package client
3
3
import (
4
4
"context"
5
5
"encoding/json"
6
+ "errors"
6
7
"fmt"
7
8
"net/http"
8
9
"strings"
@@ -46,7 +47,6 @@ type CfClient struct {
46
47
config * config
47
48
environmentID string
48
49
token string
49
- cancelFunc context.CancelFunc
50
50
streamConnected bool
51
51
streamConnectedLock sync.RWMutex
52
52
authenticated chan struct {}
@@ -55,17 +55,14 @@ type CfClient struct {
55
55
initializedLock sync.RWMutex
56
56
analyticsService * analyticsservice.AnalyticsService
57
57
clusterIdentifier string
58
+ stop chan struct {}
59
+ stopped bool
58
60
}
59
61
60
62
// NewCfClient creates a new client instance that connects to CF with the default configuration.
61
63
// For advanced configuration options use ConfigOptions functions
62
64
func NewCfClient (sdkKey string , options ... ConfigOption ) (* CfClient , error ) {
63
65
64
- var (
65
- ctx context.Context
66
- err error
67
- )
68
-
69
66
// functional options for config
70
67
config := newDefaultConfig ()
71
68
for _ , opt := range options {
@@ -81,8 +78,8 @@ func NewCfClient(sdkKey string, options ...ConfigOption) (*CfClient, error) {
81
78
analyticsService : analyticsService ,
82
79
clusterIdentifier : "1" ,
83
80
postEvalChan : make (chan evaluation.PostEvalData ),
81
+ stop : make (chan struct {}),
84
82
}
85
- ctx , client .cancelFunc = context .WithCancel (context .Background ())
86
83
87
84
if sdkKey == "" {
88
85
return client , types .ErrSdkCantBeEmpty
@@ -97,13 +94,20 @@ func NewCfClient(sdkKey string, options ...ConfigOption) (*CfClient, error) {
97
94
return nil , err
98
95
}
99
96
100
- go client .initAuthentication ( ctx )
101
-
102
- go client . setAnalyticsServiceClient ( ctx )
97
+ client .start ( )
98
+ return client , nil
99
+ }
103
100
104
- go client .pullCronJob (ctx )
101
+ func (c * CfClient ) start () {
102
+ ctx , cancel := context .WithCancel (context .Background ())
103
+ go func () {
104
+ <- c .stop
105
+ cancel ()
106
+ }()
105
107
106
- return client , nil
108
+ go c .initAuthentication (ctx )
109
+ go c .setAnalyticsServiceClient (ctx )
110
+ go c .pullCronJob (ctx )
107
111
}
108
112
109
113
// PostEvaluateProcessor push the data to the analytics service
@@ -432,7 +436,14 @@ func (c *CfClient) JSONVariation(key string, target *evaluation.Target, defaultV
432
436
// Close shuts down the Feature Flag client. After calling this, the client
433
437
// should no longer be used
434
438
func (c * CfClient ) Close () error {
435
- c .cancelFunc ()
439
+ c .mux .Lock ()
440
+ defer c .mux .Unlock ()
441
+ if c .stopped {
442
+ return errors .New ("client already closed" )
443
+ }
444
+ close (c .stop )
445
+
446
+ c .stopped = true
436
447
return nil
437
448
}
438
449
0 commit comments