Skip to content

Commit b38875c

Browse files
committed
more logs + pass EnvironmentContext structs and not pointers
1 parent 1966d3c commit b38875c

File tree

4 files changed

+44
-37
lines changed

4 files changed

+44
-37
lines changed

client.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,20 +173,21 @@ func (c *Client) UpdateEnvironment(ctx context.Context) error {
173173
e := &FlagsmithAPIError{Msg: msg, Err: nil, ResponseStatusCode: resp.StatusCode(), ResponseStatus: resp.Status()}
174174
return c.handleError(e)
175175
}
176-
c.environment.SetEnvironment(&env)
176+
c.environment.SetEnvironment(env)
177177

178178
c.log.Info("environment updated", "environment", env.APIKey)
179179
return nil
180180
}
181181

182182
// GetIdentitySegments returns the segments that this evaluation context is a part of. It requires a local environment
183183
// provided by [WithLocalEvaluation] and/or [WithOfflineHandler].
184-
func (c *Client) GetIdentitySegments(ec EvaluationContext) ([]*segments.SegmentModel, error) {
185-
if env := c.environment.GetEnvironment(); env != nil {
186-
identity := c.getIdentityModel(ec.identifier, env.APIKey, ec.traits)
187-
return flagengine.GetIdentitySegments(env, &identity), nil
184+
func (c *Client) GetIdentitySegments(ec EvaluationContext) (s []*segments.SegmentModel, err error) {
185+
env, ok := c.environment.GetEnvironment()
186+
if !ok {
187+
return s, errors.New("GetIdentitySegments called with no local environment available")
188188
}
189-
return nil, &FlagsmithClientError{msg: "no local environment available to calculate identity segments"}
189+
identity := c.getIdentityModel(ec.identifier, env.APIKey, ec.traits)
190+
return flagengine.GetIdentitySegments(env, &identity), nil
190191
}
191192

192193
// BulkIdentify can be used to create/overwrite identities(with traits) in bulk
@@ -283,8 +284,8 @@ func (c *Client) getIdentityFlagsFromAPI(ctx context.Context, identifier string,
283284
}
284285

285286
func (c *Client) getEnvironmentFlagsFromEnvironment() (Flags, error) {
286-
env := c.environment.GetEnvironment()
287-
if env == nil {
287+
env, ok := c.environment.GetEnvironment()
288+
if !ok {
288289
return Flags{}, fmt.Errorf("getEnvironmentFlagsFromEnvironment: no local environment is available")
289290
}
290291
return makeFlagsFromFeatureStates(
@@ -296,8 +297,8 @@ func (c *Client) getEnvironmentFlagsFromEnvironment() (Flags, error) {
296297
}
297298

298299
func (c *Client) getIdentityFlagsFromEnvironment(identifier string, traits map[string]interface{}) (Flags, error) {
299-
env := c.environment.GetEnvironment()
300-
if env := c.environment.GetEnvironment(); env == nil {
300+
env, ok := c.environment.GetEnvironment()
301+
if !ok {
301302
return Flags{}, fmt.Errorf("getIdentityFlagsFromDocument: no local environment is available")
302303
}
303304
identity := c.getIdentityModel(identifier, env.APIKey, traits)
@@ -360,14 +361,14 @@ func (c *Client) handleError(err *FlagsmithAPIError) *FlagsmithAPIError {
360361

361362
type state struct {
362363
mu sync.RWMutex
363-
environment *environments.EnvironmentModel
364+
environment environments.EnvironmentModel
364365
identityOverrides sync.Map
365366
}
366367

367-
func (es *state) GetEnvironment() *environments.EnvironmentModel {
368+
func (es *state) GetEnvironment() (environments.EnvironmentModel, bool) {
368369
es.mu.RLock()
369370
defer es.mu.RUnlock()
370-
return es.environment
371+
return es.environment, es.environment.APIKey != ""
371372
}
372373

373374
func (es *state) GetIdentityOverride(identifier string) (identities.IdentityModel, bool) {
@@ -378,7 +379,7 @@ func (es *state) GetIdentityOverride(identifier string) (identities.IdentityMode
378379
return identities.IdentityModel{}, ok
379380
}
380381

381-
func (es *state) SetEnvironment(env *environments.EnvironmentModel) {
382+
func (es *state) SetEnvironment(env environments.EnvironmentModel) {
382383
es.mu.Lock()
383384
defer es.mu.Unlock()
384385
es.environment = env

flagengine/engine.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func GetEnvironmentFeatureState(environment *environments.EnvironmentModel, feat
3434

3535
// GetIdentityFeatureStates returns a list of feature states for a given identity in a given environment.
3636
func GetIdentityFeatureStates(
37-
environment *environments.EnvironmentModel,
37+
environment environments.EnvironmentModel,
3838
identity *identities.IdentityModel,
3939
overrideTraits ...*traits.TraitModel,
4040
) []*features.FeatureStateModel {
@@ -52,7 +52,7 @@ func GetIdentityFeatureStates(
5252
}
5353

5454
func GetIdentityFeatureState(
55-
environment *environments.EnvironmentModel,
55+
environment environments.EnvironmentModel,
5656
identity *identities.IdentityModel,
5757
featureName string,
5858
overrideTraits ...*traits.TraitModel,
@@ -68,7 +68,7 @@ func GetIdentityFeatureState(
6868
}
6969

7070
func GetIdentitySegments(
71-
environment *environments.EnvironmentModel,
71+
environment environments.EnvironmentModel,
7272
identity *identities.IdentityModel,
7373
overrideTraits ...*traits.TraitModel,
7474
) []*segments.SegmentModel {
@@ -84,7 +84,7 @@ func GetIdentitySegments(
8484
}
8585

8686
func getIdentityFeatureStatesMap(
87-
environment *environments.EnvironmentModel,
87+
environment environments.EnvironmentModel,
8888
identity *identities.IdentityModel,
8989
overrideTraits ...*traits.TraitModel,
9090
) map[int]*features.FeatureStateModel {

offline_handler.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import (
88
)
99

1010
type OfflineHandler interface {
11-
GetEnvironment() *environments.EnvironmentModel
11+
GetEnvironment() environments.EnvironmentModel
1212
}
1313

1414
type LocalFileHandler struct {
15-
environment *environments.EnvironmentModel
15+
environment environments.EnvironmentModel
1616
}
1717

1818
// NewLocalFileHandler creates a new LocalFileHandler with the given path.
@@ -29,12 +29,12 @@ func NewLocalFileHandler(environmentDocumentPath string) (*LocalFileHandler, err
2929

3030
// Create and initialise the LocalFileHandler
3131
handler := &LocalFileHandler{
32-
environment: &environment,
32+
environment: environment,
3333
}
3434

3535
return handler, nil
3636
}
3737

38-
func (handler *LocalFileHandler) GetEnvironment() *environments.EnvironmentModel {
38+
func (handler *LocalFileHandler) GetEnvironment() environments.EnvironmentModel {
3939
return handler.environment
4040
}

realtime.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (c *Client) startRealtimeUpdates(ctx context.Context) {
1818
panic("Failed to fetch the environment while configuring real-time updates")
1919
}
2020

21-
env := c.environment.GetEnvironment()
21+
env, _ := c.environment.GetEnvironment()
2222
envUpdatedAt := env.UpdatedAt
2323
log := c.log.With("environment", env.APIKey, "current_updated_at", &envUpdatedAt)
2424

@@ -40,37 +40,43 @@ func (c *Client) startRealtimeUpdates(ctx context.Context) {
4040
}
4141
defer resp.Body.Close()
4242

43+
log.Info("connected to realtime")
44+
4345
scanner := bufio.NewScanner(resp.Body)
4446
for scanner.Scan() {
4547
line := scanner.Text()
46-
if strings.HasPrefix(line, "data: ") {
47-
parsedTime, err := parseUpdatedAtFromSSE(line)
48-
if err != nil {
49-
log.Error("failed to parse realtime update event", "error", err, "raw_event", line)
50-
continue
51-
}
52-
if parsedTime.After(envUpdatedAt) {
53-
log.WithGroup("event").Info("received update event",
48+
parsedTime, err := parseUpdatedAtFromSSE(line)
49+
if err != nil {
50+
log.Error("failed to parse realtime update event", "error", err, "raw_event", line)
51+
continue
52+
}
53+
if parsedTime.After(envUpdatedAt) {
54+
log.WithGroup("event").
55+
Info("received update event",
5456
slog.Duration("update_delay", parsedTime.Sub(envUpdatedAt)),
5557
slog.Time("updated_at", parsedTime),
5658
slog.String("environment", env.APIKey),
5759
)
58-
err = c.UpdateEnvironment(ctx)
59-
if err != nil {
60-
continue
61-
}
62-
envUpdatedAt = parsedTime
60+
err = c.UpdateEnvironment(ctx)
61+
if err != nil {
62+
log.Error("realtime update failed", "error", err)
63+
continue
6364
}
65+
envUpdatedAt = parsedTime
6466
}
6567
}
6668
if err := scanner.Err(); err != nil {
67-
c.log.Error("failed to read from realtime stream", "error", err, "stream_url", &resp.Request.URL)
69+
log.Error("failed to read from realtime stream", "error", err)
6870
}
6971
}
7072
}
7173
}
7274

7375
func parseUpdatedAtFromSSE(line string) (time.Time, error) {
76+
if !strings.HasPrefix(line, "data: ") {
77+
return time.Time{}, nil
78+
}
79+
7480
var eventData struct {
7581
UpdatedAt float64 `json:"updated_at"`
7682
}

0 commit comments

Comments
 (0)