Skip to content

Commit

Permalink
Allow to configure when next flags polling happens
Browse files Browse the repository at this point in the history
We want to poll at the same time from all instances.
  • Loading branch information
zaynetro committed Mar 7, 2024
1 parent 4944045 commit 41953ee
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
4 changes: 4 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type Config struct {
// Interval at which to fetch new feature flags, 5min by default
DefaultFeatureFlagsPollingInterval time.Duration

// Calculate when feature flags should be polled next. Setting this property
// will override DefaultFeatureFlagsPollingInterval.
NextFeatureFlagsPollingTick func() time.Duration

// The HTTP transport used by the client, this allows an application to
// redefine how requests are being sent at the HTTP level (for example,
// to change the connection pooling policy).
Expand Down
25 changes: 20 additions & 5 deletions featureflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
const LONG_SCALE = 0xfffffffffffffff

type FeatureFlagsPoller struct {
ticker *time.Ticker // periodic ticker
loaded chan bool
shutdown chan bool
forceReload chan bool
Expand All @@ -34,6 +33,7 @@ type FeatureFlagsPoller struct {
http http.Client
mutex sync.RWMutex
fetchedFlagsSuccessfullyOnce bool
nextPollTick func() time.Duration
}

type FeatureFlag struct {
Expand Down Expand Up @@ -113,9 +113,21 @@ func (e *InconclusiveMatchError) Error() string {
return e.msg
}

func newFeatureFlagsPoller(projectApiKey string, personalApiKey string, errorf func(format string, args ...interface{}), endpoint string, httpClient http.Client, pollingInterval time.Duration) *FeatureFlagsPoller {
func newFeatureFlagsPoller(
projectApiKey string,
personalApiKey string,
errorf func(format string, args ...interface{}),
endpoint string,
httpClient http.Client,
pollingInterval time.Duration,
nextPollTick func() time.Duration,
) *FeatureFlagsPoller {

if nextPollTick == nil {
nextPollTick = func() time.Duration { return pollingInterval }
}

poller := FeatureFlagsPoller{
ticker: time.NewTicker(pollingInterval),
loaded: make(chan bool),
shutdown: make(chan bool),
forceReload: make(chan bool),
Expand All @@ -126,6 +138,7 @@ func newFeatureFlagsPoller(projectApiKey string, personalApiKey string, errorf f
http: httpClient,
mutex: sync.RWMutex{},
fetchedFlagsSuccessfullyOnce: false,
nextPollTick: nextPollTick,
}

go poller.run()
Expand All @@ -136,16 +149,18 @@ func (poller *FeatureFlagsPoller) run() {
poller.fetchNewFeatureFlags()

for {
timer := time.NewTimer(poller.nextPollTick())
select {
case <-poller.shutdown:
close(poller.shutdown)
close(poller.forceReload)
close(poller.loaded)
poller.ticker.Stop()
timer.Stop()
return
case <-poller.forceReload:
timer.Stop()
poller.fetchNewFeatureFlags()
case <-poller.ticker.C:
case <-timer.C:
poller.fetchNewFeatureFlags()
}
}
Expand Down
10 changes: 9 additions & 1 deletion posthog.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,15 @@ func NewWithConfig(apiKey string, config Config) (cli Client, err error) {
}

if len(c.PersonalApiKey) > 0 {
c.featureFlagsPoller = newFeatureFlagsPoller(c.key, c.Config.PersonalApiKey, c.Errorf, c.Endpoint, c.http, c.DefaultFeatureFlagsPollingInterval)
c.featureFlagsPoller = newFeatureFlagsPoller(
c.key,
c.Config.PersonalApiKey,
c.Errorf,
c.Endpoint,
c.http,
c.DefaultFeatureFlagsPollingInterval,
c.NextFeatureFlagsPollingTick,
)
}

go c.loop()
Expand Down

0 comments on commit 41953ee

Please sign in to comment.