posthog-ruby 3.9.0 → 3.9.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: 3f033107e265e546dca78bfbf8f6adb3552e5803ac7dec0bf822afb814e7658d
4
- data.tar.gz: efe43054d73bfce034973fc12a01301f3b935cfacb1e7e86358332a9879f8911
3
+ metadata.gz: 1388daa77d143c2822f15642b375b1e833a893d86677337d0d8bfc88875b364c
4
+ data.tar.gz: 2e71adb4fdc958bd8793515dbb3317652d9e811166678e7e38c57e57a85f3a08
5
5
  SHA512:
6
- metadata.gz: e1e3e4e0e5712ab73c8c0c11ce5a5869df0dc95f293b151f81d7fc715844e36867d3aeed393427494789bf8b35f2d96f42c703085d6be405fe1168feaa7daa82
7
- data.tar.gz: 1347919dcaeda0b7ad237964ae00acc34d4b6e4b9273d3335ce6e4666f09471d8d8fefb53c13d51e345cf3b7c8e467b813b14cbbdad74062dbabbc12fbeadc26
6
+ metadata.gz: a3ab6ee23fabf6375facb994ed3a16de3ec21ec53c88da0121fe3158d9b6552127d081124bb02870ca0b04d47bd2df4a79b7a95c45d8991095e2a4cbdfc63d09
7
+ data.tar.gz: ae04e209088f84ccb2760f0dc5fc3760cfb25e2ecd452201cf16b5432e4761acd63ef9471fc87cf88e21a1d16ce744191ea7ed6a445b2544fcf3e3a0f2f1040a
@@ -3,10 +3,13 @@
3
3
  require 'posthog/defaults'
4
4
 
5
5
  module PostHog
6
+ # Retry backoff policy used by the SDK transport.
7
+ #
8
+ # @api private
6
9
  class BackoffPolicy
7
10
  include PostHog::Defaults::BackoffPolicy
8
11
 
9
- # @param [Hash] opts
12
+ # @param opts [Hash]
10
13
  # @option opts [Numeric] :min_timeout_ms The minimum backoff timeout
11
14
  # @option opts [Numeric] :max_timeout_ms The maximum backoff timeout
12
15
  # @option opts [Numeric] :multiplier The value to multiply the current
@@ -50,29 +50,28 @@ module PostHog
50
50
  end
51
51
  end
52
52
 
53
- # @param [Hash] opts
54
- # @option opts [String] :api_key Your project's api_key
55
- # @option opts [String] :personal_api_key Your personal API key
56
- # @option opts [FixNum] :max_queue_size Maximum number of calls to be
57
- # remain queued. Defaults to 10_000.
58
- # @option opts [Bool] :test_mode +true+ if messages should remain
59
- # queued for testing. Defaults to +false+.
60
- # @option opts [Bool] :sync_mode +true+ to send events synchronously
61
- # on the calling thread. Useful in forking environments like Sidekiq
62
- # and Resque. Defaults to +false+.
63
- # @option opts [Proc] :on_error Handles error calls from the API.
64
- # @option opts [String] :host Fully qualified hostname of the PostHog server. Defaults to `https://us.i.posthog.com`
65
- # @option opts [Integer] :feature_flags_polling_interval How often to poll for feature flag definition changes.
66
- # Measured in seconds, defaults to 30.
67
- # @option opts [Integer] :feature_flag_request_timeout_seconds How long to wait for feature flag evaluation.
68
- # Measured in seconds, defaults to 3.
69
- # @option opts [Proc] :before_send A block that receives the event hash and should return either a modified hash
70
- # to be sent to PostHog or nil to prevent the event from being sent. e.g. `before_send: ->(event) { event }`
71
- # @option opts [Bool] :disable_singleton_warning +true+ to suppress the warning when multiple clients
72
- # share the same API key. Use only when you intentionally need multiple clients. Defaults to +false+.
73
- # @option opts [Object] :flag_definition_cache_provider An object implementing the
74
- # {FlagDefinitionCacheProvider} interface for distributed flag definition caching.
75
- # EXPERIMENTAL: This API may change in future minor version bumps.
53
+ # @param opts [Hash] Client configuration.
54
+ # @option opts [String] :api_key Your project's API key. Required.
55
+ # @option opts [String, nil] :personal_api_key Your personal API key. Required for local feature flag evaluation.
56
+ # @option opts [String] :host Fully qualified hostname of the PostHog server. Defaults to `https://us.i.posthog.com`.
57
+ # @option opts [Integer] :max_queue_size Maximum number of calls to remain queued. Defaults to 10_000.
58
+ # @option opts [Integer] :batch_size Maximum number of events to send in one async batch.
59
+ # @option opts [Boolean] :test_mode +true+ if messages should remain queued for testing. Defaults to +false+.
60
+ # @option opts [Boolean] :sync_mode +true+ to send events synchronously on the calling thread. Useful in
61
+ # forking environments like Sidekiq and Resque. Defaults to +false+.
62
+ # @option opts [Proc] :on_error Callback invoked as `on_error.call(status, error)` for API or serialization errors.
63
+ # @option opts [Integer] :feature_flags_polling_interval How often to poll for feature flag definition changes,
64
+ # in seconds. Defaults to 30.
65
+ # @option opts [Integer] :feature_flag_request_timeout_seconds How long to wait for feature flag evaluation,
66
+ # in seconds. Defaults to 3.
67
+ # @option opts [Proc] :before_send A callback that receives the event hash and should return either a modified
68
+ # hash to be sent to PostHog or nil to prevent the event from being sent. e.g. `before_send: ->(event) { event }`.
69
+ # @option opts [Boolean] :disable_singleton_warning +true+ to suppress the warning when multiple clients share
70
+ # the same API key. Use only when you intentionally need multiple clients. Defaults to +false+.
71
+ # @option opts [Boolean] :skip_ssl_verification +true+ to disable SSL certificate verification for requests.
72
+ # Intended only for local development or custom deployments.
73
+ # @option opts [Object] :flag_definition_cache_provider An object implementing the {FlagDefinitionCacheProvider}
74
+ # interface for distributed flag definition caching. EXPERIMENTAL: This API may change in future minor versions.
76
75
  def initialize(opts = {})
77
76
  symbolize_keys!(opts)
78
77
 
@@ -143,7 +142,9 @@ module PostHog
143
142
  # Synchronously waits until the worker has cleared the queue.
144
143
  #
145
144
  # Use only for scripts which are not long-running, and will specifically
146
- # exit
145
+ # exit.
146
+ #
147
+ # @return [void]
147
148
  def flush
148
149
  if @sync_mode
149
150
  # Wait for any in-flight sync send to complete
@@ -159,7 +160,9 @@ module PostHog
159
160
 
160
161
  # Clears the queue without waiting.
161
162
  #
162
- # Use only in test mode
163
+ # Use only in test mode.
164
+ #
165
+ # @return [void]
163
166
  def clear
164
167
  @queue.clear
165
168
  end
@@ -176,8 +179,10 @@ module PostHog
176
179
  #
177
180
  # @option attrs [String] :event Event name
178
181
  # @option attrs [Hash] :properties Event properties (optional)
179
- # @option attrs [Bool, Hash, SendFeatureFlagsOptions] :send_feature_flags
180
- # Whether to send feature flags with this event, or configuration for feature flag evaluation (optional)
182
+ # @option attrs [Hash] :groups Group analytics mapping from group type to group key (optional)
183
+ # @option attrs [Boolean, Hash, SendFeatureFlagsOptions] :send_feature_flags
184
+ # Deprecated. Whether to send feature flags with this event, or configuration for feature flag evaluation
185
+ # (optional)
181
186
  # @option attrs [PostHog::FeatureFlagEvaluations] :flags A snapshot returned by
182
187
  # {#evaluate_flags}. When present, `$feature/<key>` and `$active_feature_flags` are
183
188
  # attached from the snapshot without making an additional /flags request, and this
@@ -189,6 +194,7 @@ module PostHog
189
194
  # @note If `:distinct_id` is omitted, request/context distinct_id is used when
190
195
  # available; otherwise a UUID is generated and the event is marked personless
191
196
  # with `$process_person_profile: false`.
197
+ # @return [Boolean] Whether the event was queued or sent.
192
198
  # @macro common_attrs
193
199
  def capture(attrs)
194
200
  symbolize_keys! attrs
@@ -268,9 +274,10 @@ module PostHog
268
274
  # @param [String] distinct_id The ID for the user (optional, defaults to request/context distinct_id
269
275
  # or a generated UUID)
270
276
  # @param [Hash] additional_properties Additional properties to include with the exception event (optional)
271
- # @param [PostHog::FeatureFlagEvaluations] flags A snapshot returned by {#evaluate_flags}.
277
+ # @param flags [PostHog::FeatureFlagEvaluations, nil] A snapshot returned by {#evaluate_flags}.
272
278
  # Forwarded to the inner {#capture} call so the captured `$exception` event carries the
273
279
  # same `$feature/<key>` and `$active_feature_flags` properties as the snapshot.
280
+ # @return [Boolean, nil] Whether the exception event was queued or sent, or nil if the input could not be parsed.
274
281
  def capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil)
275
282
  exception_info = ExceptionCapture.build_parsed_exception(exception)
276
283
 
@@ -295,6 +302,7 @@ module PostHog
295
302
  # @param [Hash] attrs
296
303
  #
297
304
  # @option attrs [Hash] :properties User properties (optional)
305
+ # @return [Boolean] Whether the identify event was queued or sent.
298
306
  # @macro common_attrs
299
307
  def identify(attrs)
300
308
  symbolize_keys! attrs
@@ -309,6 +317,7 @@ module PostHog
309
317
  # @option attrs [String] :group_key Group key
310
318
  # @option attrs [Hash] :properties Group properties (optional)
311
319
  # @option attrs [String] :distinct_id Distinct ID (optional)
320
+ # @return [Boolean] Whether the group identify event was queued or sent.
312
321
  # @macro common_attrs
313
322
  def group_identify(attrs)
314
323
  symbolize_keys! attrs
@@ -320,23 +329,32 @@ module PostHog
320
329
  # @param [Hash] attrs
321
330
  #
322
331
  # @option attrs [String] :alias The alias to give the distinct id
332
+ # @return [Boolean] Whether the alias event was queued or sent.
323
333
  # @macro common_attrs
324
334
  def alias(attrs)
325
335
  symbolize_keys! attrs
326
336
  enqueue(FieldParser.parse_for_alias(attrs))
327
337
  end
328
338
 
329
- # @return [Hash] pops the last message from the queue
339
+ # @return [Hash] Pops the last message from the queue. Intended for test mode.
330
340
  def dequeue_last_message
331
341
  @queue.pop
332
342
  end
333
343
 
334
- # @return [Fixnum] number of messages in the queue
344
+ # @return [Integer] Number of messages in the queue. Intended for test mode.
335
345
  def queued_messages
336
346
  @queue.length
337
347
  end
338
348
 
339
- # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#is_enabled} instead.
349
+ # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#enabled?} instead.
350
+ # @param flag_key [String, Symbol] The unique key of the feature flag.
351
+ # @param distinct_id [String] The distinct id of the user.
352
+ # @param groups [Hash] Group analytics mapping from group type to group key.
353
+ # @param person_properties [Hash] Properties to use when evaluating the user locally or remotely.
354
+ # @param group_properties [Hash] Properties to use when evaluating groups locally or remotely.
355
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
356
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
357
+ # @return [Boolean, nil] Whether the flag is enabled, or nil when the flag could not be evaluated.
340
358
  # TODO: In future version, rename to `feature_flag_enabled?`
341
359
  def is_feature_enabled( # rubocop:disable Naming/PredicateName
342
360
  flag_key,
@@ -366,8 +384,8 @@ module PostHog
366
384
  !!response
367
385
  end
368
386
 
369
- # @param [String, Symbol] flag_key The unique flag key of the feature flag
370
- # @return [String] The decrypted value of the feature flag payload
387
+ # @param flag_key [String, Symbol] The unique flag key of the remote config feature flag.
388
+ # @return [Hash] The parsed remote config payload response.
371
389
  def get_remote_config_payload(flag_key)
372
390
  @feature_flags_poller.get_remote_config_payload(flag_key.to_s)
373
391
  end
@@ -379,8 +397,10 @@ module PostHog
379
397
  # @param [Hash] groups
380
398
  # @param [Hash] person_properties key-value pairs of properties to associate with the user.
381
399
  # @param [Hash] group_properties
400
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
401
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
382
402
  #
383
- # @return [String, nil] The value of the feature flag
403
+ # @return [String, Boolean, nil] The value of the feature flag
384
404
  #
385
405
  # The provided properties are used to calculate feature flags locally, if possible.
386
406
  #
@@ -420,6 +440,14 @@ module PostHog
420
440
 
421
441
  # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#get_flag} /
422
442
  # {FeatureFlagEvaluations#get_flag_payload} instead.
443
+ # @param key [String, Symbol] The unique key of the feature flag.
444
+ # @param distinct_id [String] The distinct id of the user.
445
+ # @param groups [Hash] Group analytics mapping from group type to group key.
446
+ # @param person_properties [Hash] Properties to use when evaluating the user locally or remotely.
447
+ # @param group_properties [Hash] Properties to use when evaluating groups locally or remotely.
448
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
449
+ # @param send_feature_flag_events [Boolean] Whether to capture `$feature_flag_called` for this access.
450
+ # @return [PostHog::FeatureFlagResult, nil]
423
451
  def get_feature_flag_result(
424
452
  key,
425
453
  distinct_id,
@@ -456,7 +484,8 @@ module PostHog
456
484
  # @param [Hash] person_properties key-value pairs of properties to associate with the user
457
485
  # @param [Hash] group_properties
458
486
  # @param [Boolean] only_evaluate_locally Skip the remote /flags call entirely
459
- # @param [Boolean] disable_geoip Stamped on captured access events
487
+ # @param [Boolean, nil] disable_geoip When true, disables GeoIP lookup for remote evaluation and stamps captured
488
+ # access events.
460
489
  # @param [Array<String, Symbol>] flag_keys When set, scopes the underlying /flags
461
490
  # request to only these flag keys (sent as `flag_keys_to_evaluate`).
462
491
  # Distinct from {FeatureFlagEvaluations#only}, which filters the
@@ -580,6 +609,7 @@ module PostHog
580
609
  # @param [Hash] groups
581
610
  # @param [Hash] person_properties key-value pairs of properties to associate with the user.
582
611
  # @param [Hash] group_properties
612
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
583
613
  #
584
614
  # @return [Hash] String (not symbol) key value pairs of flag and their values
585
615
  def get_all_flags(
@@ -602,11 +632,12 @@ module PostHog
602
632
  #
603
633
  # @param [String, Symbol] key The key of the feature flag
604
634
  # @param [String] distinct_id The distinct id of the user
605
- # @option [String or boolean] match_value The value of the feature flag to be matched
606
- # @option [Hash] groups
607
- # @option [Hash] person_properties key-value pairs of properties to associate with the user.
608
- # @option [Hash] group_properties
609
- # @option [Boolean] only_evaluate_locally
635
+ # @param match_value [String, Boolean, nil] The value of the feature flag to be matched
636
+ # @param groups [Hash]
637
+ # @param person_properties [Hash] key-value pairs of properties to associate with the user.
638
+ # @param group_properties [Hash]
639
+ # @param only_evaluate_locally [Boolean]
640
+ # @return [Object, nil] The parsed payload for the matched flag value.
610
641
  #
611
642
  # @deprecated Use {#evaluate_flags} and {FeatureFlagEvaluations#get_flag_payload} instead.
612
643
  def get_feature_flag_payload(
@@ -639,10 +670,10 @@ module PostHog
639
670
  # featureFlagPayloads: A hash of feature flag payloads
640
671
  #
641
672
  # @param [String] distinct_id The distinct id of the user
642
- # @option [Hash] groups
643
- # @option [Hash] person_properties key-value pairs of properties to associate with the user.
644
- # @option [Hash] group_properties
645
- # @option [Boolean] only_evaluate_locally
673
+ # @param groups [Hash]
674
+ # @param person_properties [Hash] key-value pairs of properties to associate with the user.
675
+ # @param group_properties [Hash]
676
+ # @param only_evaluate_locally [Boolean] Skip the remote /flags call.
646
677
  #
647
678
  def get_all_flags_and_payloads(
648
679
  distinct_id,
@@ -664,6 +695,9 @@ module PostHog
664
695
  response
665
696
  end
666
697
 
698
+ # Reload locally cached feature flag definitions.
699
+ #
700
+ # @return [void]
667
701
  def reload_feature_flags
668
702
  unless @personal_api_key
669
703
  logger.error(
@@ -674,6 +708,9 @@ module PostHog
674
708
  @feature_flags_poller.load_feature_flags(true)
675
709
  end
676
710
 
711
+ # Flush pending events and stop background resources.
712
+ #
713
+ # @return [void]
677
714
  def shutdown
678
715
  self.class._decrement_instance_count(@api_key) if @api_key
679
716
  @feature_flags_poller.shutdown_poller
@@ -11,6 +11,9 @@
11
11
  # 💖 open source (under MIT License)
12
12
 
13
13
  module PostHog
14
+ # Builds PostHog exception payloads from Ruby exception objects.
15
+ #
16
+ # @api private
14
17
  module ExceptionCapture
15
18
  RUBY_INPUT_FORMAT = /
16
19
  ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
@@ -18,6 +21,8 @@ module PostHog
18
21
  (?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$
19
22
  /x
20
23
 
24
+ # @param value [Exception, String, Object] Exception input to parse.
25
+ # @return [Hash, nil] Parsed exception payload, or nil when the input is unsupported.
21
26
  def self.build_parsed_exception(value)
22
27
  title, message, backtrace = coerce_exception_input(value)
23
28
  return nil if title.nil?
@@ -25,6 +30,10 @@ module PostHog
25
30
  build_single_exception_from_data(title, message, backtrace)
26
31
  end
27
32
 
33
+ # @param title [String]
34
+ # @param message [String, nil]
35
+ # @param backtrace [Array<String>, nil]
36
+ # @return [Hash]
28
37
  def self.build_single_exception_from_data(title, message, backtrace)
29
38
  {
30
39
  'type' => title,
@@ -37,6 +46,8 @@ module PostHog
37
46
  }
38
47
  end
39
48
 
49
+ # @param backtrace [Array<String>, nil]
50
+ # @return [Hash, nil]
40
51
  def self.build_stacktrace(backtrace)
41
52
  return nil unless backtrace && !backtrace.empty?
42
53
 
@@ -50,6 +61,8 @@ module PostHog
50
61
  }
51
62
  end
52
63
 
64
+ # @param line [String]
65
+ # @return [Hash, nil]
53
66
  def self.parse_backtrace_line(line)
54
67
  match = line.match(RUBY_INPUT_FORMAT)
55
68
  return nil unless match
@@ -72,6 +85,8 @@ module PostHog
72
85
  frame
73
86
  end
74
87
 
88
+ # @param path [String]
89
+ # @return [Boolean]
75
90
  def self.gem_path?(path)
76
91
  path.include?('/gems/') ||
77
92
  path.include?('/ruby/') ||
@@ -79,6 +94,11 @@ module PostHog
79
94
  path.include?('/.rvm/')
80
95
  end
81
96
 
97
+ # @param frame [Hash]
98
+ # @param file_path [String]
99
+ # @param lineno [Integer]
100
+ # @param context_size [Integer]
101
+ # @return [void]
82
102
  def self.add_context_lines(frame, file_path, lineno, context_size = 5)
83
103
  lines = File.readlines(file_path)
84
104
  return if lines.empty?
@@ -97,6 +117,8 @@ module PostHog
97
117
  # Silently ignore file read errors
98
118
  end
99
119
 
120
+ # @param value [Exception, String, Object]
121
+ # @return [Array] Three-item array of title, message, and backtrace.
100
122
  def self.coerce_exception_input(value)
101
123
  if value.is_a?(String)
102
124
  title = 'Error'
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Represents a feature flag returned by /flags v2
4
3
  module PostHog
4
+ # Represents a feature flag returned by /flags v2.
5
+ #
6
+ # @api private
5
7
  class FeatureFlag
6
8
  attr_reader :key, :enabled, :variant, :reason, :metadata, :failed
7
9
 
10
+ # @param json [Hash] Raw feature flag data returned by /flags.
8
11
  def initialize(json)
9
12
  json.transform_keys!(&:to_s)
10
13
  @key = json['key']
@@ -15,15 +18,21 @@ module PostHog
15
18
  @failed = json['failed']
16
19
  end
17
20
 
21
+ # @return [String, Boolean] The variant value when present, otherwise the enabled status.
18
22
  # TODO: Rename to `value` in future version
19
23
  def get_value # rubocop:disable Naming/AccessorMethodName
20
24
  @variant || @enabled
21
25
  end
22
26
 
27
+ # @return [Object, nil] The flag payload from metadata.
23
28
  def payload
24
29
  @metadata&.payload
25
30
  end
26
31
 
32
+ # @param key [String, Symbol] The feature flag key.
33
+ # @param value [String, Boolean] The feature flag value.
34
+ # @param payload [Object, nil] The feature flag payload.
35
+ # @return [PostHog::FeatureFlag]
27
36
  def self.from_value_and_payload(key, value, payload)
28
37
  new({
29
38
  'key' => key,
@@ -40,10 +49,13 @@ module PostHog
40
49
  end
41
50
  end
42
51
 
43
- # Represents the reason why a flag was enabled/disabled
52
+ # Represents the reason why a flag was enabled/disabled.
53
+ #
54
+ # @api private
44
55
  class EvaluationReason
45
56
  attr_reader :code, :description, :condition_index
46
57
 
58
+ # @param json [Hash] Raw reason data returned by /flags.
47
59
  def initialize(json)
48
60
  json.transform_keys!(&:to_s)
49
61
  @code = json['code']
@@ -52,10 +64,13 @@ module PostHog
52
64
  end
53
65
  end
54
66
 
55
- # Represents metadata about a feature flag
67
+ # Represents metadata about a feature flag.
68
+ #
69
+ # @api private
56
70
  class FeatureFlagMetadata
57
71
  attr_reader :id, :version, :payload, :description
58
72
 
73
+ # @param json [Hash] Raw metadata returned by /flags.
59
74
  def initialize(json)
60
75
  json.transform_keys!(&:to_s)
61
76
  @id = json['id']
@@ -17,6 +17,7 @@ module PostHog
17
17
  #
18
18
  # For API errors with status codes, use the api_error() method which returns
19
19
  # a string like "api_error_500".
20
+ # @api private
20
21
  class FeatureFlagError
21
22
  ERRORS_WHILE_COMPUTING = 'errors_while_computing_flags'
22
23
  FLAG_MISSING = 'flag_missing'
@@ -4,7 +4,7 @@ require 'set'
4
4
 
5
5
  module PostHog
6
6
  # A snapshot of feature flag evaluations for one distinct_id, returned by
7
- # PostHog::Client#evaluate_flags. Calls to {#is_enabled} / {#get_flag} fire the
7
+ # PostHog::Client#evaluate_flags. Calls to {#enabled?} / {#get_flag} fire the
8
8
  # `$feature_flag_called` event (deduped through the existing per-distinct_id
9
9
  # cache); {#get_flag_payload} does not. Pass the snapshot to `capture(flags:)`
10
10
  # to attach `$feature/<key>` and `$active_feature_flags` without a second
@@ -19,8 +19,32 @@ module PostHog
19
19
 
20
20
  Host = Struct.new(:capture_flag_called_event_if_needed, :log_warning, keyword_init: true)
21
21
 
22
- attr_reader :distinct_id, :groups, :request_id, :evaluated_at, :flag_definitions_loaded_at
22
+ # @return [String] The distinct id these evaluations belong to.
23
+ attr_reader :distinct_id
23
24
 
25
+ # @return [Hash, nil] Group analytics mapping used for evaluation.
26
+ attr_reader :groups
27
+
28
+ # @return [String, nil] Request id returned by the /flags endpoint.
29
+ attr_reader :request_id
30
+
31
+ # @return [String, nil] Evaluation timestamp returned by the /flags endpoint.
32
+ attr_reader :evaluated_at
33
+
34
+ # @return [Time, nil] When local flag definitions were loaded.
35
+ attr_reader :flag_definitions_loaded_at
36
+
37
+ # @param host [Host, nil] Internal host callbacks used to record flag access events.
38
+ # @param distinct_id [String, nil] The distinct id these evaluations belong to.
39
+ # @param flags [Hash] Evaluated flags keyed by flag key.
40
+ # @param groups [Hash, nil] Group analytics mapping from group type to group key.
41
+ # @param disable_geoip [Boolean, nil] Whether GeoIP was disabled during evaluation.
42
+ # @param request_id [String, nil] The request id returned by the /flags endpoint.
43
+ # @param evaluated_at [String, nil] The evaluation timestamp returned by the /flags endpoint.
44
+ # @param flag_definitions_loaded_at [Time, nil] When local flag definitions were loaded.
45
+ # @param errors_while_computing [Boolean] Whether the server reported errors while computing flags.
46
+ # @param quota_limited [Boolean] Whether feature flag evaluation was quota limited.
47
+ # @param accessed [Array<String>, Set<String>, nil] Flag keys already accessed by this snapshot.
24
48
  def initialize(
25
49
  host: nil,
26
50
  distinct_id: nil,
@@ -47,10 +71,13 @@ module PostHog
47
71
  @accessed = Set.new(accessed || [])
48
72
  end
49
73
 
74
+ # @return [Array<String>] The evaluated flag keys in this snapshot.
50
75
  def keys
51
76
  @flags.keys
52
77
  end
53
78
 
79
+ # @param key [String, Symbol] The feature flag key.
80
+ # @return [Boolean] true when the flag is enabled, false when disabled or missing.
54
81
  def enabled?(key)
55
82
  key = key.to_s
56
83
  flag = @flags[key]
@@ -58,6 +85,9 @@ module PostHog
58
85
  flag&.enabled ? true : false
59
86
  end
60
87
 
88
+ # @param key [String, Symbol] The feature flag key.
89
+ # @return [String, Boolean, nil] Variant string for multivariate flags, true/false for boolean flags,
90
+ # or nil when the flag was not returned by the evaluation.
61
91
  def get_flag(key)
62
92
  key = key.to_s
63
93
  flag = @flags[key]
@@ -65,6 +95,8 @@ module PostHog
65
95
  _flag_value(flag)
66
96
  end
67
97
 
98
+ # @param key [String, Symbol] The feature flag key.
99
+ # @return [Object, nil] The parsed payload for the flag, if any.
68
100
  def get_flag_payload(key)
69
101
  flag = @flags[key.to_s]
70
102
  flag&.payload
@@ -73,10 +105,14 @@ module PostHog
73
105
  # Order-dependent: if nothing has been accessed yet, the returned snapshot is
74
106
  # empty. The method honors its name — pre-access flags before calling this if
75
107
  # you want a populated result.
108
+ # @return [PostHog::FeatureFlagEvaluations] A snapshot containing only flags already accessed with
109
+ # {#enabled?} or {#get_flag}.
76
110
  def only_accessed
77
111
  _clone_with(@flags.slice(*@accessed))
78
112
  end
79
113
 
114
+ # @param keys [Array<String, Symbol>, String, Symbol] Flag keys to keep in the returned snapshot.
115
+ # @return [PostHog::FeatureFlagEvaluations] A snapshot containing only the requested keys that exist.
80
116
  def only(keys)
81
117
  keys = Array(keys).map(&:to_s)
82
118
  missing = keys.reject { |k| @flags.key?(k) }
@@ -92,6 +128,9 @@ module PostHog
92
128
 
93
129
  # Builds the `$feature/<key>` and `$active_feature_flags` properties for a
94
130
  # captured event. Called from PostHog::Client#capture when `flags:` is set.
131
+ #
132
+ # @api private
133
+ # @return [Hash]
95
134
  def _get_event_properties
96
135
  properties = {}
97
136
  active = []
@@ -6,8 +6,19 @@ module PostHog
6
6
  # Represents the result of a feature flag evaluation
7
7
  # containing both the flag value and payload
8
8
  class FeatureFlagResult
9
- attr_reader :key, :variant, :payload
9
+ # @return [String, Symbol] The feature flag key.
10
+ attr_reader :key
10
11
 
12
+ # @return [String, nil] The variant key for multivariate flags.
13
+ attr_reader :variant
14
+
15
+ # @return [Object, nil] The parsed feature flag payload.
16
+ attr_reader :payload
17
+
18
+ # @param key [String, Symbol] The feature flag key.
19
+ # @param enabled [Boolean] Whether the feature flag is enabled.
20
+ # @param variant [String, nil] The variant key for multivariate flags.
21
+ # @param payload [Object, nil] The parsed feature flag payload.
11
22
  def initialize(key:, enabled:, variant: nil, payload: nil)
12
23
  @key = key
13
24
  @enabled = enabled
@@ -15,18 +26,27 @@ module PostHog
15
26
  @payload = payload
16
27
  end
17
28
 
18
- # Returns the effective value of the feature flag
19
- # variant if present, otherwise enabled status
29
+ # Returns the effective value of the feature flag: variant if present,
30
+ # otherwise enabled status.
31
+ #
32
+ # @return [String, Boolean]
20
33
  def value
21
34
  @variant || @enabled
22
35
  end
23
36
 
24
- # Returns whether or not the feature flag evaluated as enabled
37
+ # Returns whether or not the feature flag evaluated as enabled.
38
+ #
39
+ # @return [Boolean]
25
40
  def enabled?
26
41
  @enabled
27
42
  end
28
43
 
29
- # Factory method to create from flag value and payload
44
+ # Factory method to create from flag value and payload.
45
+ #
46
+ # @param key [String, Symbol] The feature flag key.
47
+ # @param value [String, Boolean, nil] The raw feature flag value.
48
+ # @param payload [Object, String, nil] The raw or JSON-encoded feature flag payload.
49
+ # @return [PostHog::FeatureFlagResult, nil]
30
50
  def self.from_value_and_payload(key, value, payload)
31
51
  return nil if value.nil?
32
52
 
@@ -43,6 +63,9 @@ module PostHog
43
63
  # returned when the body is not valid JSON); already-deserialized values
44
64
  # pass through. Public so {FeatureFlagEvaluations} can normalize payloads
45
65
  # the same way {FeatureFlagResult} does.
66
+ #
67
+ # @param payload [Object, String, nil] The raw payload value.
68
+ # @return [Object, nil] The parsed payload.
46
69
  def self.parse_payload(payload)
47
70
  return nil if payload.nil?
48
71
  return payload unless payload.is_a?(String)
@@ -20,10 +20,20 @@ module PostHog
20
20
  class RequiresServerEvaluation < StandardError
21
21
  end
22
22
 
23
+ # Polls and evaluates feature flag definitions for {PostHog::Client}.
24
+ #
25
+ # @api private
23
26
  class FeatureFlagsPoller
24
27
  include PostHog::Logging
25
28
  include PostHog::Utils
26
29
 
30
+ # @param polling_interval [Integer, nil] Seconds between local feature flag definition polls.
31
+ # @param personal_api_key [String, nil] Personal API key used to fetch local evaluation definitions.
32
+ # @param project_api_key [String] Project API key.
33
+ # @param host [String] PostHog API host URL.
34
+ # @param feature_flag_request_timeout_seconds [Integer] Timeout for feature flag requests.
35
+ # @param on_error [Proc, nil] Callback invoked as `on_error.call(status, error)`.
36
+ # @param flag_definition_cache_provider [Object, nil] Optional {FlagDefinitionCacheProvider} implementation.
27
37
  def initialize(
28
38
  polling_interval,
29
39
  personal_api_key,
@@ -446,6 +456,16 @@ module PostHog
446
456
  parsed_dt
447
457
  end
448
458
 
459
+ # Parse a single semver numeric identifier, rejecting empty, non-digit, or
460
+ # leading-zero values per semver 2.0.0 §2.
461
+ def self.parse_semver_numeric(part)
462
+ raise InconclusiveMatchError, 'Invalid semver format' if part.nil? || part.empty? || part !~ /^\d+$/
463
+ # Semver 2.0.0 §2: numeric identifiers MUST NOT include leading zeros.
464
+ raise InconclusiveMatchError, 'Invalid semver format' if part.length > 1 && part[0] == '0'
465
+
466
+ part.to_i
467
+ end
468
+
449
469
  # Parse a semver string into a comparable [major, minor, patch] integer array.
450
470
  # Handles v-prefix, whitespace, pre-release suffixes. Defaults missing components to 0.
451
471
  def self.parse_semver(value)
@@ -461,14 +481,9 @@ module PostHog
461
481
 
462
482
  raise InconclusiveMatchError, 'Invalid semver format' if parts.empty? || parts[0].to_s.empty?
463
483
 
464
- # Check for leading dot or non-numeric parts
465
- parts.each do |part|
466
- raise InconclusiveMatchError, 'Invalid semver format' if part.empty? || part !~ /^\d+$/
467
- end
468
-
469
- major = parts[0].to_i
470
- minor = parts.length > 1 ? parts[1].to_i : 0
471
- patch = parts.length > 2 ? parts[2].to_i : 0
484
+ major = parse_semver_numeric(parts[0])
485
+ minor = parts.length > 1 ? parse_semver_numeric(parts[1]) : 0
486
+ patch = parts.length > 2 ? parse_semver_numeric(parts[2]) : 0
472
487
 
473
488
  [major, minor, patch]
474
489
  end
@@ -525,20 +540,22 @@ module PostHog
525
540
 
526
541
  raise InconclusiveMatchError, 'Invalid semver wildcard format' if parts.empty?
527
542
 
528
- parts.each do |part|
529
- raise InconclusiveMatchError, 'Invalid semver wildcard format' if part !~ /^\d+$/
543
+ numeric = parts.map do |part|
544
+ parse_semver_numeric(part)
545
+ rescue InconclusiveMatchError
546
+ raise InconclusiveMatchError, 'Invalid semver wildcard format'
530
547
  end
531
548
 
532
- major = parts[0].to_i
533
- case parts.length
549
+ major = numeric[0]
550
+ case numeric.length
534
551
  when 1
535
552
  [[major, 0, 0], [major + 1, 0, 0]]
536
553
  when 2
537
- minor = parts[1].to_i
554
+ minor = numeric[1]
538
555
  [[major, minor, 0], [major, minor + 1, 0]]
539
556
  else
540
- minor = parts[1].to_i
541
- patch = parts[2].to_i
557
+ minor = numeric[1]
558
+ patch = numeric[2]
542
559
  [[major, minor, patch], [major, minor, patch + 1]]
543
560
  end
544
561
  end
@@ -3,6 +3,9 @@
3
3
  require 'posthog/logging'
4
4
 
5
5
  module PostHog
6
+ # Converts public SDK method arguments into PostHog API event payloads.
7
+ #
8
+ # @api private
6
9
  class FieldParser
7
10
  class << self
8
11
  include PostHog::Utils
@@ -14,6 +17,8 @@ module PostHog
14
17
  # - "properties"
15
18
  # - "groups"
16
19
  # - "uuid"
20
+ # @param fields [Hash]
21
+ # @return [Hash]
17
22
  def parse_for_capture(fields)
18
23
  common = parse_common_fields(fields)
19
24
 
@@ -45,6 +50,8 @@ module PostHog
45
50
  # In addition to the common fields, identify accepts:
46
51
  #
47
52
  # - "properties"
53
+ # @param fields [Hash]
54
+ # @return [Hash]
48
55
  def parse_for_identify(fields)
49
56
  common = parse_common_fields(fields)
50
57
 
@@ -63,6 +70,8 @@ module PostHog
63
70
  )
64
71
  end
65
72
 
73
+ # @param fields [Hash]
74
+ # @return [Hash]
66
75
  def parse_for_group_identify(fields)
67
76
  properties = fields[:properties] || {}
68
77
  group_type = fields[:group_type]
@@ -92,6 +101,8 @@ module PostHog
92
101
  # In addition to the common fields, alias accepts:
93
102
  #
94
103
  # - "alias"
104
+ # @param fields [Hash]
105
+ # @return [Hash]
95
106
  def parse_for_alias(fields)
96
107
  common = parse_common_fields(fields)
97
108
 
@@ -14,26 +14,31 @@ module PostHog
14
14
  #
15
15
  # == Required Methods
16
16
  #
17
- # [+flag_definitions+]
17
+ # @!method flag_definitions
18
18
  # Retrieve cached flag definitions. Return a Hash with +:flags+,
19
19
  # +:group_type_mapping+, and +:cohorts+ keys, or +nil+ if the cache
20
20
  # is empty. Returning +nil+ triggers an API fetch when no flags are
21
21
  # loaded yet (emergency fallback).
22
+ # @return [Hash, nil]
22
23
  #
23
- # [+should_fetch_flag_definitions?+]
24
+ # @!method should_fetch_flag_definitions?
24
25
  # Return +true+ if this instance should fetch new definitions from the
25
26
  # API, +false+ to read from cache instead. Use for distributed lock
26
27
  # coordination so only one worker fetches at a time.
28
+ # @return [Boolean]
27
29
  #
28
- # [+on_flag_definitions_received(data)+]
30
+ # @!method on_flag_definitions_received(data)
29
31
  # Called after successfully fetching new definitions from the API.
30
32
  # +data+ is a Hash with +:flags+, +:group_type_mapping+, and +:cohorts+
31
33
  # keys (plain Ruby types, not Concurrent:: wrappers). Store it in your
32
34
  # external cache.
35
+ # @param data [Hash]
36
+ # @return [void]
33
37
  #
34
- # [+shutdown+]
38
+ # @!method shutdown
35
39
  # Called when the PostHog client shuts down. Release any distributed
36
40
  # locks and clean up resources.
41
+ # @return [void]
37
42
  #
38
43
  # == Error Handling
39
44
  #
@@ -66,6 +71,7 @@ module PostHog
66
71
  #
67
72
  # @param provider [Object] the cache provider to validate
68
73
  # @raise [ArgumentError] if any required methods are missing
74
+ # @return [void]
69
75
  def self.validate!(provider)
70
76
  missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
71
77
  return if missing.empty?
@@ -3,8 +3,12 @@
3
3
  require 'logger'
4
4
 
5
5
  module PostHog
6
- # Wraps an existing logger and adds a prefix to all messages
6
+ # Wraps an existing logger and adds a prefix to all messages.
7
+ #
8
+ # @api private
7
9
  class PrefixedLogger
10
+ # @param logger [Logger, #debug, #info, #warn, #error]
11
+ # @param prefix [String]
8
12
  def initialize(logger, prefix)
9
13
  @logger = logger
10
14
  @prefix = prefix
@@ -37,6 +41,7 @@ module PostHog
37
41
 
38
42
  module Logging
39
43
  class << self
44
+ # @return [Logger, PostHog::PrefixedLogger] The logger used by the SDK.
40
45
  def logger
41
46
  return @logger if @logger
42
47
 
@@ -52,6 +57,7 @@ module PostHog
52
57
  @logger = PrefixedLogger.new(base_logger, '[posthog-ruby]')
53
58
  end
54
59
 
60
+ # @param logger [Logger, #debug, #info, #warn, #error] Custom logger used by the SDK.
55
61
  attr_writer :logger
56
62
  end
57
63
 
@@ -63,6 +69,7 @@ module PostHog
63
69
  end
64
70
  end
65
71
 
72
+ # @return [Logger, PostHog::PrefixedLogger] The logger used by the SDK.
66
73
  def logger
67
74
  Logging.logger
68
75
  end
@@ -4,7 +4,9 @@ require 'forwardable'
4
4
  require 'posthog/logging'
5
5
 
6
6
  module PostHog
7
- # A batch of `Message`s to be sent to the API
7
+ # A batch of messages to be sent to the API.
8
+ #
9
+ # @api private
8
10
  class MessageBatch
9
11
  class JSONGenerationError < StandardError
10
12
  end
@@ -13,12 +15,15 @@ module PostHog
13
15
  include PostHog::Logging
14
16
  include PostHog::Defaults::MessageBatch
15
17
 
18
+ # @param max_message_count [Integer] Maximum number of messages in the batch.
16
19
  def initialize(max_message_count)
17
20
  @messages = []
18
21
  @max_message_count = max_message_count
19
22
  @json_size = 0
20
23
  end
21
24
 
25
+ # @param message [Hash] Message to add to the batch.
26
+ # @return [Array<Hash>, nil]
22
27
  def <<(message)
23
28
  begin
24
29
  message_json = message.to_json
@@ -35,10 +40,12 @@ module PostHog
35
40
  end
36
41
  end
37
42
 
43
+ # @return [Boolean] Whether the batch is full.
38
44
  def full?
39
45
  item_count_exhausted? || size_exhausted?
40
46
  end
41
47
 
48
+ # @return [void]
42
49
  def clear
43
50
  @messages.clear
44
51
  @json_size = 0
@@ -1,21 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # A worker that doesn't consume jobs
4
3
  module PostHog
4
+ # A worker that doesn't consume jobs.
5
+ #
6
+ # @api private
5
7
  class NoopWorker
8
+ # @param queue [Queue]
6
9
  def initialize(queue)
7
10
  @queue = queue
8
11
  end
9
12
 
13
+ # @return [void]
10
14
  def run
11
15
  # Does nothing
12
16
  end
13
17
 
18
+ # @return [Boolean]
14
19
  # TODO: Rename to `requesting?` in future version
15
20
  def is_requesting? # rubocop:disable Naming/PredicateName
16
21
  false
17
22
  end
18
23
 
24
+ # @return [void]
19
25
  def shutdown
20
26
  # Does nothing
21
27
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
+ # API response wrapper returned by the SDK transport.
5
+ #
6
+ # @api private
4
7
  class Response
5
8
  attr_reader :status, :error
6
9
 
7
- # public: Simple class to wrap responses from the API
8
- #
9
- #
10
+ # @param status [Integer] HTTP status code, or -1 for SDK/transport errors.
11
+ # @param error [String, nil] Error message returned by the API or SDK.
10
12
  def initialize(status = 200, error = nil)
11
13
  @status = status
12
14
  @error = error
@@ -3,16 +3,29 @@
3
3
  require 'posthog/utils'
4
4
 
5
5
  module PostHog
6
- # Options for configuring feature flag behavior in capture calls
6
+ # Options for configuring deprecated feature flag behavior in capture calls.
7
+ #
8
+ # @deprecated Prefer passing a {PostHog::FeatureFlagEvaluations} snapshot to `capture(flags:)`.
7
9
  class SendFeatureFlagsOptions
8
- attr_reader :only_evaluate_locally, :person_properties, :group_properties
10
+ # @return [Boolean, nil] Whether remote feature flag evaluation should be skipped.
11
+ attr_reader :only_evaluate_locally
9
12
 
13
+ # @return [Hash] Person properties to use for feature flag evaluation.
14
+ attr_reader :person_properties
15
+
16
+ # @return [Hash] Group properties to use for feature flag evaluation.
17
+ attr_reader :group_properties
18
+
19
+ # @param only_evaluate_locally [Boolean, nil] Skip remote feature flag evaluation.
20
+ # @param person_properties [Hash, nil] Person properties to use for feature flag evaluation.
21
+ # @param group_properties [Hash, nil] Group properties to use for feature flag evaluation.
10
22
  def initialize(only_evaluate_locally: nil, person_properties: nil, group_properties: nil)
11
23
  @only_evaluate_locally = only_evaluate_locally
12
24
  @person_properties = person_properties || {}
13
25
  @group_properties = group_properties || {}
14
26
  end
15
27
 
28
+ # @return [Hash] A hash representation suitable for `capture(send_feature_flags:)`.
16
29
  def to_h
17
30
  {
18
31
  only_evaluate_locally: @only_evaluate_locally,
@@ -21,6 +34,8 @@ module PostHog
21
34
  }
22
35
  end
23
36
 
37
+ # @param hash [Hash]
38
+ # @return [PostHog::SendFeatureFlagsOptions, nil]
24
39
  def self.from_hash(hash)
25
40
  return nil unless hash.is_a?(Hash)
26
41
 
@@ -6,6 +6,9 @@ require 'posthog/transport'
6
6
  require 'posthog/utils'
7
7
 
8
8
  module PostHog
9
+ # Background worker that batches and sends queued events.
10
+ #
11
+ # @api private
9
12
  class SendWorker
10
13
  include PostHog::Utils
11
14
  include PostHog::Defaults
@@ -16,12 +19,13 @@ module PostHog
16
19
  # The worker continuously takes messages off the queue
17
20
  # and makes requests to the posthog.com api
18
21
  #
19
- # queue - Queue synchronized between client and worker
20
- # api_key - String of the project's API key
21
- # options - Hash of worker options
22
- # batch_size - Fixnum of how many items to send in a batch
23
- # on_error - Proc of what to do on an error
24
- #
22
+ # @param queue [Queue] Queue synchronized between client and worker.
23
+ # @param api_key [String] Project API key.
24
+ # @param options [Hash] Worker options.
25
+ # @option options [Integer] :batch_size How many items to send in a batch.
26
+ # @option options [Proc] :on_error Callback invoked as `on_error.call(status, error)`.
27
+ # @option options [String] :host PostHog API host URL.
28
+ # @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
25
29
  def initialize(queue, api_key, options = {})
26
30
  symbolize_keys! options
27
31
  @queue = queue
@@ -33,8 +37,9 @@ module PostHog
33
37
  @transport = Transport.new api_host: options[:host], skip_ssl_verification: options[:skip_ssl_verification]
34
38
  end
35
39
 
36
- # public: Continuously runs the loop to check for new events
40
+ # Continuously runs the loop to check for new events.
37
41
  #
42
+ # @return [void]
38
43
  def run
39
44
  until Thread.current[:should_exit]
40
45
  return if @queue.empty?
@@ -54,12 +59,14 @@ module PostHog
54
59
  @transport.shutdown
55
60
  end
56
61
 
62
+ # @return [void]
57
63
  def shutdown
58
64
  @transport.shutdown
59
65
  end
60
66
 
61
67
  # public: Check whether we have outstanding requests.
62
68
  #
69
+ # @return [Boolean] Whether the worker has outstanding requests.
63
70
  # TODO: Rename to `requesting?` in future version
64
71
  def is_requesting? # rubocop:disable Naming/PredicateName
65
72
  @lock.synchronize { !@batch.empty? }
@@ -10,11 +10,24 @@ require 'net/https'
10
10
  require 'json'
11
11
 
12
12
  module PostHog
13
+ # HTTP transport used by the SDK workers.
14
+ #
15
+ # @api private
13
16
  class Transport
14
17
  include PostHog::Defaults::Request
15
18
  include PostHog::Utils
16
19
  include PostHog::Logging
17
20
 
21
+ # @param options [Hash] Transport configuration.
22
+ # @option options [String] :api_host Full PostHog API host URL.
23
+ # @option options [String] :host Hostname to connect to.
24
+ # @option options [Integer] :port Port to connect to.
25
+ # @option options [Boolean] :ssl Whether to use HTTPS.
26
+ # @option options [Hash] :headers HTTP headers for batch requests.
27
+ # @option options [String] :path HTTP path for batch requests.
28
+ # @option options [Integer] :retries Number of retry attempts for retryable failures.
29
+ # @option options [PostHog::BackoffPolicy] :backoff_policy Backoff policy used between retries.
30
+ # @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
18
31
  def initialize(options = {})
19
32
  if options[:api_host]
20
33
  uri = URI.parse(options[:api_host])
@@ -43,6 +56,8 @@ module PostHog
43
56
 
44
57
  # Sends a batch of messages to the API
45
58
  #
59
+ # @param api_key [String] Project API key.
60
+ # @param batch [PostHog::MessageBatch, Array<Hash>] Batch of messages to send.
46
61
  # @return [Response] API response
47
62
  def send(api_key, batch)
48
63
  logger.debug("Sending request for #{batch.length} items")
@@ -72,7 +87,9 @@ module PostHog
72
87
  end
73
88
  end
74
89
 
75
- # Closes a persistent connection if it exists
90
+ # Closes a persistent connection if it exists.
91
+ #
92
+ # @return [void]
76
93
  def shutdown
77
94
  @http.finish if @http.started?
78
95
  end
data/lib/posthog/utils.rb CHANGED
@@ -6,6 +6,9 @@ module PostHog
6
6
  class InconclusiveMatchError < StandardError
7
7
  end
8
8
 
9
+ # Utility helpers used internally by the SDK.
10
+ #
11
+ # @api private
9
12
  module Utils
10
13
  module_function
11
14
 
@@ -145,12 +148,19 @@ module PostHog
145
148
  end
146
149
  end
147
150
 
151
+ # Hash that clears itself when it reaches a maximum length.
152
+ #
153
+ # @api private
148
154
  class SizeLimitedHash < Hash
155
+ # @param max_length [Integer]
149
156
  def initialize(max_length, ...)
150
157
  super(...)
151
158
  @max_length = max_length
152
159
  end
153
160
 
161
+ # @param key [Object]
162
+ # @param value [Object]
163
+ # @return [Object]
154
164
  def []=(key, value)
155
165
  clear if length >= @max_length
156
166
  super
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
- VERSION = '3.9.0'
4
+ VERSION = '3.9.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posthog-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.0
4
+ version: 3.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''