posthog-ruby 2.5.1 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78a70730ff0365203bb5af28ae5fadbb938950bb8980d048e3167878a1dc6645
4
- data.tar.gz: e0a73f36a251b3280a21950c960c0a3f89172511a03f1c076898b769eb91ebbf
3
+ metadata.gz: 8209dce25858ff907c8149de2bf7a5b3643af4375ea1591e7483164834a2e8a1
4
+ data.tar.gz: c41124a33fdf865b8d7b2c02a78f8df1fec2b033ba2a3d3ab1373a046d9c2c6b
5
5
  SHA512:
6
- metadata.gz: 6f1b69643da1ed3dccfb38de8979436f9f0236676a2858931bea97215e617e6e97282e1b719bf1c811453731fe8e4873e7ac5a0fa021f9785899712b4ef43828
7
- data.tar.gz: 7f016c7d172072f837f0780994d8018352356e19ae872578fd5befe2f657aab417c2aec350c357162d44fab52e59a3883236888e4a28a004b35e44b0e0a7bcf7
6
+ metadata.gz: 6ef6116e6d7748f09433ddd6da1a9e9da03c89240bdd9946467da6dde00d23469f2a7954e448ea9a283d57b8724cf101a0adbe8b5a7e7f78e7eb887776edc88e
7
+ data.tar.gz: 6d24488c317dd31bfcd834a0922264e5379dd1f377e78905e52825d7c97e033feaa6a0eaf8b120724d85156e9a977f8dc603efae9d2e7944a39c26b6bfefac76
@@ -155,6 +155,12 @@ class PostHog
155
155
  !!response
156
156
  end
157
157
 
158
+ # @param [String] flag_key The unique flag key of the feature flag
159
+ # @return [String] The decrypted value of the feature flag payload
160
+ def get_remote_config_payload(flag_key)
161
+ return @feature_flags_poller.get_remote_config_payload(flag_key)
162
+ end
163
+
158
164
  # Returns whether the given feature flag is enabled for the given user or not
159
165
  #
160
166
  # @param [String] key The key of the feature flag
@@ -25,7 +25,7 @@ class PostHog
25
25
  @feature_flags_by_key = nil
26
26
  @feature_flag_request_timeout_seconds = feature_flag_request_timeout_seconds
27
27
  @on_error = on_error || proc { |status, error| }
28
-
28
+ @quota_limited = Concurrent::AtomicBoolean.new(false)
29
29
  @task =
30
30
  Concurrent::TimerTask.new(
31
31
  execution_interval: polling_interval,
@@ -80,6 +80,10 @@ class PostHog
80
80
  decide_data = _request_feature_flag_evaluation(request_data)
81
81
  end
82
82
 
83
+ def get_remote_config_payload(flag_key)
84
+ return _request_remote_config_payload(flag_key)
85
+ end
86
+
83
87
  def get_feature_flag(key, distinct_id, groups = {}, person_properties = {}, group_properties = {}, only_evaluate_locally = false)
84
88
  # make sure they're loaded on first run
85
89
  load_feature_flags
@@ -132,6 +136,10 @@ class PostHog
132
136
  end
133
137
 
134
138
  def get_all_flags(distinct_id, groups = {}, person_properties = {}, group_properties = {}, only_evaluate_locally = false)
139
+ if @quota_limited.true?
140
+ logger.debug "Not fetching flags from decide - quota limited"
141
+ return {}
142
+ end
135
143
  # returns a string hash of all flags
136
144
  response = get_all_flags_and_payloads(distinct_id, groups, person_properties, group_properties, only_evaluate_locally)
137
145
  flags = response[:featureFlags]
@@ -166,8 +174,16 @@ class PostHog
166
174
  unless flags_and_payloads.key?(:featureFlags)
167
175
  raise StandardError.new("Error flags response: #{flags_and_payloads}")
168
176
  end
169
- flags = stringify_keys(flags_and_payloads[:featureFlags] || {})
170
- payloads = stringify_keys(flags_and_payloads[:featureFlagPayloads] || {})
177
+
178
+ # Check if feature_flags are quota limited
179
+ if flags_and_payloads[:quotaLimited]&.include?("feature_flags")
180
+ logger.warn "[FEATURE FLAGS] Quota limited for feature flags"
181
+ flags = {}
182
+ payloads = {}
183
+ else
184
+ flags = stringify_keys(flags_and_payloads[:featureFlags] || {})
185
+ payloads = stringify_keys(flags_and_payloads[:featureFlagPayloads] || {})
186
+ end
171
187
  rescue StandardError => e
172
188
  @on_error.call(-1, "Error computing flag remotely: #{e}")
173
189
  raise if raise_on_error
@@ -479,6 +495,17 @@ class PostHog
479
495
  return
480
496
  end
481
497
 
498
+ # Handle quota limits with 402 status
499
+ if res.is_a?(Hash) && res[:status] == 402
500
+ logger.warn "[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all local flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts"
501
+ @feature_flags = Concurrent::Array.new
502
+ @feature_flags_by_key = {}
503
+ @group_type_mapping = Concurrent::Hash.new
504
+ @loaded_flags_successfully_once.make_false
505
+ @quota_limited.make_true
506
+ return
507
+ end
508
+
482
509
  if !res.key?(:flags)
483
510
  logger.debug "Failed to load feature flags: #{res}"
484
511
  else
@@ -516,17 +543,33 @@ class PostHog
516
543
  _request(uri, req, @feature_flag_request_timeout_seconds)
517
544
  end
518
545
 
519
- def _request(uri, request_object, timeout = nil)
546
+ def _request_remote_config_payload(flag_key)
547
+ uri = URI("#{@host}/api/projects/@current/feature_flags/#{flag_key}/remote_config/")
548
+ req = Net::HTTP::Get.new(uri)
549
+ req['Content-Type'] = 'application/json'
550
+ req['Authorization'] = "Bearer #{@personal_api_key}"
520
551
 
521
- request_object['User-Agent'] = "posthog-ruby#{PostHog::VERSION}"
552
+ _request(uri, req, @feature_flag_request_timeout_seconds)
553
+ end
522
554
 
555
+ def _request(uri, request_object, timeout = nil)
556
+ request_object['User-Agent'] = `"posthog-ruby#{PostHog::VERSION}"`
523
557
  request_timeout = timeout || 10
524
558
 
525
559
  begin
526
- res_body = nil
527
560
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https', :read_timeout => request_timeout) do |http|
528
561
  res = http.request(request_object)
529
- JSON.parse(res.body, {symbolize_names: true})
562
+
563
+ # Parse response body to hash
564
+ begin
565
+ response = JSON.parse(res.body, {symbolize_names: true})
566
+ # Only add status if response is a hash
567
+ response = response.is_a?(Hash) ? response.merge({status: res.code.to_i}) : response
568
+ return response
569
+ rescue JSON::ParserError
570
+ # Handle case when response isn't valid JSON
571
+ return {error: "Invalid JSON response", body: res.body, status: res.code.to_i}
572
+ end
530
573
  end
531
574
  rescue Timeout::Error,
532
575
  Errno::EINVAL,
@@ -1,3 +1,3 @@
1
1
  class PostHog
2
- VERSION = '2.5.1'
2
+ VERSION = '2.7.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posthog-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-19 00:00:00.000000000 Z
11
+ date: 2025-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -178,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0'
180
180
  requirements: []
181
- rubygems_version: 3.4.10
181
+ rubygems_version: 3.5.10
182
182
  signing_key:
183
183
  specification_version: 4
184
184
  summary: PostHog library