diff --git a/.changeset/polling-interval-default.md b/.changeset/polling-interval-default.md new file mode 100644 index 0000000..85dd020 --- /dev/null +++ b/.changeset/polling-interval-default.md @@ -0,0 +1,5 @@ +--- +"posthog-ruby": patch +--- + +Honor the documented 30s default for `feature_flags_polling_interval`. The resolved default was computed but never passed to the polling timer, so when the option was unset the effective interval was concurrent-ruby's 60s TimerTask default. Definitions now poll every 30s by default as documented; set `feature_flags_polling_interval: 60` to keep the previous effective cadence. diff --git a/lib/posthog/defaults.rb b/lib/posthog/defaults.rb index eea7666..d152ec4 100644 --- a/lib/posthog/defaults.rb +++ b/lib/posthog/defaults.rb @@ -19,6 +19,7 @@ module Request module FeatureFlags FLAG_REQUEST_TIMEOUT_SECONDS = 3 + POLLING_INTERVAL_SECONDS = 30 # Number of retries for a flag request after a transient network error. # Flag requests are stateless and cause no server-side mutation, so # retrying is safe. diff --git a/lib/posthog/feature_flags.rb b/lib/posthog/feature_flags.rb index dde847c..159035c 100644 --- a/lib/posthog/feature_flags.rb +++ b/lib/posthog/feature_flags.rb @@ -30,6 +30,7 @@ class FeatureFlagsPoller include PostHog::Utils # @param polling_interval [Integer, nil] Seconds between local feature flag definition polls. + # Defaults to {Defaults::FeatureFlags::POLLING_INTERVAL_SECONDS}. # @param secret_key [String, nil] Credential used to fetch local evaluation definitions. Accepts either a # Personal API Key (`phx_...`) or a Project Secret API Key (`phs_...`). # @param project_api_key [String] Project API key. @@ -50,7 +51,7 @@ def initialize( flag_definition_cache_provider: nil, feature_flag_request_max_retries: nil ) - @polling_interval = polling_interval || 30 + @polling_interval = polling_interval || Defaults::FeatureFlags::POLLING_INTERVAL_SECONDS @secret_key = secret_key @project_api_key = project_api_key @host = host @@ -72,7 +73,7 @@ def initialize( @task = Concurrent::TimerTask.new( - execution_interval: polling_interval + execution_interval: @polling_interval ) { _load_feature_flags } # If no secret_key, disable local evaluation & thus polling for definitions diff --git a/public_api_snapshot.txt b/public_api_snapshot.txt index fb26974..3fb6568 100644 --- a/public_api_snapshot.txt +++ b/public_api_snapshot.txt @@ -36,6 +36,7 @@ constant PostHog::Defaults::BackoffPolicy::RANDOMIZATION_FACTOR: Float module PostHog::Defaults::FeatureFlags constant PostHog::Defaults::FeatureFlags::FLAG_REQUEST_MAX_RETRIES: Integer constant PostHog::Defaults::FeatureFlags::FLAG_REQUEST_TIMEOUT_SECONDS: Integer +constant PostHog::Defaults::FeatureFlags::POLLING_INTERVAL_SECONDS: Integer constant PostHog::Defaults::MAX_HASH_SIZE: Integer module PostHog::Defaults::Message constant PostHog::Defaults::Message::MAX_BYTES: Integer diff --git a/spec/posthog/feature_flag_spec.rb b/spec/posthog/feature_flag_spec.rb index 287183c..db188e9 100644 --- a/spec/posthog/feature_flag_spec.rb +++ b/spec/posthog/feature_flag_spec.rb @@ -5349,4 +5349,33 @@ def flag_called_properties(client, key) end end end + + describe 'definitions polling interval' do + before do + stub_request( + :get, + 'https://us.i.posthog.com/flags/definitions?token=testsecret&send_cohorts=true' + ).to_return(status: 200, body: { flags: [] }.to_json) + end + + def timer_task_interval(client) + poller = client.instance_variable_get(:@feature_flags_poller) + poller.instance_variable_get(:@task).execution_interval + end + + it 'defaults to the documented 30 seconds' do + client = Client.new(api_key: API_KEY, secret_key: API_KEY, test_mode: true) + + expect(timer_task_interval(client)).to eq(30) + end + + it 'uses feature_flags_polling_interval when provided' do + client = Client.new( + api_key: API_KEY, secret_key: API_KEY, test_mode: true, + feature_flags_polling_interval: 15 + ) + + expect(timer_task_interval(client)).to eq(15) + end + end end