@@ -7,6 +7,7 @@ package openfeature
77
88import (
99 "bytes"
10+ "cmp"
1011 "context"
1112 "encoding/json"
1213 "fmt"
@@ -100,55 +101,40 @@ type exposureWriter struct {
100101
101102// newExposureWriter creates a new exposure writer with the given configuration
102103func newExposureWriter (config ProviderConfig ) * exposureWriter {
103- flushInterval := config .ExposureFlushInterval
104- if flushInterval == 0 {
105- flushInterval = defaultExposureFlushInterval
106- }
107-
108- // Get agent URL from environment or default
109- agentURL := internal .AgentURLFromEnv ()
110-
111104 // Build service context from environment variables
112- serviceName := globalconfig .ServiceName ()
113- if serviceName == "" {
114- serviceName = env .Get ("DD_SERVICE" )
115- }
105+ serviceName := cmp .Or (env .Get ("DD_SERVICE" ), globalconfig .ServiceName ())
116106 if serviceName == "" {
117107 serviceName = "unknown"
118108 }
119109
120110 context := exposureContext {
121111 ServiceName : serviceName ,
122- }
123-
124- // Only include version and env if they are defined
125- if version := env .Get ("DD_VERSION" ); version != "" {
126- context .Version = version
127- }
128-
129- if envName := env .Get ("DD_ENV" ); envName != "" {
130- context .Env = envName
131- }
132-
133- // Create HTTP client with timeout
134- httpClient := & http.Client {
135- Timeout : defaultHTTPTimeout ,
112+ Version : env .Get ("DD_VERSION" ),
113+ Env : env .Get ("DD_ENV" ),
136114 }
137115
138116 return & exposureWriter {
139117 buffer : make ([]exposureEvent , 0 ),
140- flushInterval : flushInterval ,
141- httpClient : httpClient ,
142- agentURL : agentURL ,
143- context : context ,
144- stopChan : make (chan struct {}),
118+ flushInterval : cmp .Or (config .ExposureFlushInterval , defaultExposureFlushInterval ),
119+ httpClient : & http.Client {
120+ Timeout : defaultHTTPTimeout ,
121+ },
122+ agentURL : internal .AgentURLFromEnv (),
123+ context : context ,
124+ stopChan : make (chan struct {}),
145125 }
146126}
147127
148128// start begins the periodic flushing of exposure events
149129func (w * exposureWriter ) start () {
150130 w .ticker = time .NewTicker (w .flushInterval )
151131 go func () {
132+ defer func () {
133+ if r := recover (); r != nil {
134+ log .Error ("openfeature: exposure writer recovered panic: %v" , r )
135+ }
136+ }()
137+
152138 for {
153139 select {
154140 case <- w .ticker .C :
@@ -184,7 +170,7 @@ func (w *exposureWriter) flush() {
184170
185171 // Move buffer to local variable and create new buffer
186172 events := w .buffer
187- w .buffer = make ([]exposureEvent , 0 )
173+ w .buffer = make ([]exposureEvent , len ( events ) / 2 )
188174 w .mu .Unlock ()
189175
190176 // Build payload
@@ -257,6 +243,8 @@ func (w *exposureWriter) buildRequestURL() string {
257243
258244// stop stops the exposure writer and flushes any remaining events
259245func (w * exposureWriter ) stop () {
246+ w .flush ()
247+
260248 w .mu .Lock ()
261249 if w .stopped {
262250 w .mu .Unlock ()
@@ -265,16 +253,13 @@ func (w *exposureWriter) stop() {
265253 w .stopped = true
266254 w .mu .Unlock ()
267255
256+ // Signal the goroutine to stop
257+ close (w .stopChan )
258+
268259 // Stop the ticker
269260 if w .ticker != nil {
270261 w .ticker .Stop ()
271262 }
272263
273- // Signal the goroutine to stop
274- close (w .stopChan )
275-
276- // Final flush
277- w .flush ()
278-
279264 log .Debug ("openfeature: exposure writer stopped" )
280265}
0 commit comments