posthog-ruby 3.9.1 → 3.9.3

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: 1388daa77d143c2822f15642b375b1e833a893d86677337d0d8bfc88875b364c
4
- data.tar.gz: 2e71adb4fdc958bd8793515dbb3317652d9e811166678e7e38c57e57a85f3a08
3
+ metadata.gz: 89fab2ec7ac4caec58095c06aacdc2ccc4a283cec328672291bfbed58a8ebf31
4
+ data.tar.gz: 4a8a95003bb34a4ddbeee89c2cd3d41daf1d1df4026de52f2f776f04a5225fef
5
5
  SHA512:
6
- metadata.gz: a3ab6ee23fabf6375facb994ed3a16de3ec21ec53c88da0121fe3158d9b6552127d081124bb02870ca0b04d47bd2df4a79b7a95c45d8991095e2a4cbdfc63d09
7
- data.tar.gz: ae04e209088f84ccb2760f0dc5fc3760cfb25e2ecd452201cf16b5432e4761acd63ef9471fc87cf88e21a1d16ce744191ea7ed6a445b2544fcf3e3a0f2f1040a
6
+ metadata.gz: bc3a513fabd5d515ae95bb716a58ea28ecb0b303db57ac91d50e0c0d14995af3da2de6a0f6a121cd0601e3e161535410f54b4b2fa765d858a89174cdbb067c94
7
+ data.tar.gz: a1528a5562c611c1a1a9115bd7bf64ac772f0cc2207c4a27326c44be4190221d168035e17954cc86d363f307f2c32ab079922ba7851326eae5bc27c6feed3415
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'time'
4
+ require 'json'
4
5
  require 'securerandom'
5
6
 
6
7
  require 'posthog/defaults'
@@ -51,7 +52,7 @@ module PostHog
51
52
  end
52
53
 
53
54
  # @param opts [Hash] Client configuration.
54
- # @option opts [String] :api_key Your project's API key. Required.
55
+ # @option opts [String, nil] :api_key Your project's API key. Missing or blank values disable the client.
55
56
  # @option opts [String, nil] :personal_api_key Your personal API key. Required for local feature flag evaluation.
56
57
  # @option opts [String] :host Fully qualified hostname of the PostHog server. Defaults to `https://us.i.posthog.com`.
57
58
  # @option opts [Integer] :max_queue_size Maximum number of calls to remain queued. Defaults to 10_000.
@@ -71,7 +72,7 @@ module PostHog
71
72
  # @option opts [Boolean] :skip_ssl_verification +true+ to disable SSL certificate verification for requests.
72
73
  # Intended only for local development or custom deployments.
73
74
  # @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.
75
+ # interface for distributed flag definition caching.
75
76
  def initialize(opts = {})
76
77
  symbolize_keys!(opts)
77
78
 
@@ -81,11 +82,12 @@ module PostHog
81
82
 
82
83
  @queue = Queue.new
83
84
  @api_key = opts[:api_key]
85
+ @disabled = @api_key.nil? || @api_key.empty?
84
86
  @max_queue_size = opts[:max_queue_size] || Defaults::Queue::MAX_SIZE
85
87
  @worker_mutex = Mutex.new
86
- @sync_mode = opts[:sync_mode] == true && !opts[:test_mode]
88
+ @sync_mode = opts[:sync_mode] == true && !opts[:test_mode] && !@disabled
87
89
  @on_error = opts[:on_error] || proc { |status, error| }
88
- @worker = if opts[:test_mode]
90
+ @worker = if opts[:test_mode] || @disabled
89
91
  NoopWorker.new(@queue)
90
92
  elsif @sync_mode
91
93
  nil
@@ -104,11 +106,10 @@ module PostHog
104
106
  @feature_flags_poller = nil
105
107
  @personal_api_key = opts[:personal_api_key]
106
108
 
107
- check_api_key!
108
- logger.error('api_key is empty after trimming whitespace; check your project API key') if @api_key == ''
109
+ logger.error('api_key is missing or empty after trimming whitespace; check your project API key') if @disabled
109
110
 
110
111
  # Warn when multiple clients are created with the same API key (can cause dropped events)
111
- unless opts[:test_mode] || opts[:disable_singleton_warning]
112
+ unless @disabled || opts[:test_mode] || opts[:disable_singleton_warning]
112
113
  previous_count = self.class._increment_instance_count(@api_key)
113
114
  if previous_count >= 1
114
115
  logger.warn(
@@ -120,16 +121,18 @@ module PostHog
120
121
  end
121
122
  end
122
123
 
123
- @feature_flags_poller =
124
- FeatureFlagsPoller.new(
125
- opts[:feature_flags_polling_interval],
126
- opts[:personal_api_key],
127
- @api_key,
128
- opts[:host],
129
- opts[:feature_flag_request_timeout_seconds] || Defaults::FeatureFlags::FLAG_REQUEST_TIMEOUT_SECONDS,
130
- opts[:on_error],
131
- flag_definition_cache_provider: opts[:flag_definition_cache_provider]
132
- )
124
+ unless @disabled
125
+ @feature_flags_poller =
126
+ FeatureFlagsPoller.new(
127
+ opts[:feature_flags_polling_interval],
128
+ opts[:personal_api_key],
129
+ @api_key,
130
+ opts[:host],
131
+ opts[:feature_flag_request_timeout_seconds] || Defaults::FeatureFlags::FLAG_REQUEST_TIMEOUT_SECONDS,
132
+ opts[:on_error],
133
+ flag_definition_cache_provider: opts[:flag_definition_cache_provider]
134
+ )
135
+ end
133
136
 
134
137
  @distinct_id_has_sent_flag_calls = SizeLimitedHash.new(Defaults::MAX_HASH_SIZE) do |hash, key|
135
138
  hash[key] = []
@@ -197,6 +200,8 @@ module PostHog
197
200
  # @return [Boolean] Whether the event was queued or sent.
198
201
  # @macro common_attrs
199
202
  def capture(attrs)
203
+ return false if @disabled
204
+
200
205
  symbolize_keys! attrs
201
206
  enrich_capture_attrs_with_context(attrs)
202
207
 
@@ -225,7 +230,7 @@ module PostHog
225
230
  end
226
231
 
227
232
  send_feature_flags_param = attrs[:send_feature_flags]
228
- if send_feature_flags_param
233
+ if send_feature_flags_param && !@disabled
229
234
  _emit_deprecation(
230
235
  :capture_send_feature_flags,
231
236
  '`send_feature_flags` on `capture` is deprecated and will be removed in a future major ' \
@@ -387,6 +392,8 @@ module PostHog
387
392
  # @param flag_key [String, Symbol] The unique flag key of the remote config feature flag.
388
393
  # @return [Hash] The parsed remote config payload response.
389
394
  def get_remote_config_payload(flag_key)
395
+ return nil if @disabled
396
+
390
397
  @feature_flags_poller.get_remote_config_payload(flag_key.to_s)
391
398
  end
392
399
 
@@ -464,6 +471,8 @@ module PostHog
464
471
  '`flags.get_flag_payload(key)` instead — this consolidates flag evaluation into a single ' \
465
472
  '`/flags` request per incoming request.'
466
473
  )
474
+ return nil if @disabled
475
+
467
476
  _get_feature_flag_result(
468
477
  key, distinct_id,
469
478
  groups: groups, person_properties: person_properties, group_properties: group_properties,
@@ -506,6 +515,8 @@ module PostHog
506
515
  return FeatureFlagEvaluations.new(host: host, distinct_id: '', flags: {})
507
516
  end
508
517
 
518
+ return FeatureFlagEvaluations.new(host: host, distinct_id: distinct_id, flags: {}, groups: groups) if @disabled
519
+
509
520
  person_properties, group_properties = add_local_person_and_group_properties(
510
521
  distinct_id, groups, person_properties, group_properties
511
522
  )
@@ -619,6 +630,8 @@ module PostHog
619
630
  group_properties: {},
620
631
  only_evaluate_locally: false
621
632
  )
633
+ return {} if @disabled
634
+
622
635
  person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
623
636
  person_properties, group_properties)
624
637
  @feature_flags_poller.get_all_flags(distinct_id, groups, person_properties, group_properties,
@@ -656,6 +669,8 @@ module PostHog
656
669
  'instead — this consolidates flag evaluation into a single `/flags` request per ' \
657
670
  'incoming request.'
658
671
  )
672
+ return nil if @disabled
673
+
659
674
  key = key.to_s
660
675
  person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
661
676
  person_properties, group_properties)
@@ -682,6 +697,8 @@ module PostHog
682
697
  group_properties: {},
683
698
  only_evaluate_locally: false
684
699
  )
700
+ return { featureFlags: {}, featureFlagPayloads: {} } if @disabled
701
+
685
702
  person_properties, group_properties = add_local_person_and_group_properties(
686
703
  distinct_id, groups, person_properties, group_properties
687
704
  )
@@ -699,6 +716,8 @@ module PostHog
699
716
  #
700
717
  # @return [void]
701
718
  def reload_feature_flags
719
+ return if @disabled
720
+
702
721
  unless @personal_api_key
703
722
  logger.error(
704
723
  'You need to specify a personal_api_key to locally evaluate feature flags'
@@ -712,8 +731,8 @@ module PostHog
712
731
  #
713
732
  # @return [void]
714
733
  def shutdown
715
- self.class._decrement_instance_count(@api_key) if @api_key
716
- @feature_flags_poller.shutdown_poller
734
+ self.class._decrement_instance_count(@api_key) unless @disabled
735
+ @feature_flags_poller&.shutdown_poller
717
736
  flush
718
737
  if @sync_mode
719
738
  @sync_lock.synchronize { @transport&.shutdown }
@@ -760,11 +779,22 @@ module PostHog
760
779
  # Shared by the legacy single-flag path ({#get_feature_flag_result}) and the
761
780
  # snapshot's access-recording. Owns dedup-key construction, the
762
781
  # per-distinct_id sent-flags cache, and the `$feature_flag_called` capture call.
782
+ # Group context is included in the dedup key so group-scoped flags fire a
783
+ # separate event for each group a user is evaluated under.
763
784
  def _capture_feature_flag_called_if_needed(
764
785
  distinct_id: nil, key: nil, response: nil, properties: nil,
765
786
  groups: nil, disable_geoip: nil
766
787
  )
767
- reported_key = "#{key}_#{response.nil? ? '::null::' : response}"
788
+ response_repr = response.nil? ? '::null::' : response
789
+ groups_repr =
790
+ if groups && !groups.empty?
791
+ # Canonicalize so two equal hashes with keys inserted in a different
792
+ # order produce the same dedup key.
793
+ "_#{groups.sort.to_json}"
794
+ else
795
+ ''
796
+ end
797
+ reported_key = "#{key}_#{response_repr}#{groups_repr}"
768
798
  return if @distinct_id_has_sent_flag_calls[distinct_id].include?(reported_key)
769
799
 
770
800
  msg = {
@@ -798,6 +828,8 @@ module PostHog
798
828
  only_evaluate_locally: false,
799
829
  send_feature_flag_events: true
800
830
  )
831
+ return nil if @disabled
832
+
801
833
  key = key.to_s
802
834
  person_properties, group_properties = add_local_person_and_group_properties(
803
835
  distinct_id, groups, person_properties, group_properties
@@ -863,6 +895,8 @@ module PostHog
863
895
  #
864
896
  # returns Boolean of whether the item was added to the queue.
865
897
  def enqueue(action)
898
+ return false if @disabled
899
+
866
900
  action = process_before_send(action)
867
901
  return false if action.nil? || action.empty?
868
902
 
@@ -889,11 +923,6 @@ module PostHog
889
923
  end
890
924
  end
891
925
 
892
- # private: Checks that the api_key is properly initialized
893
- def check_api_key!
894
- raise ArgumentError, 'API key must be initialized' if @api_key.nil?
895
- end
896
-
897
926
  def normalize_string_option(value, blank_as_nil: false)
898
927
  return value unless value.is_a?(String)
899
928
 
@@ -3,8 +3,6 @@
3
3
  module PostHog
4
4
  # Interface for external caching of feature flag definitions.
5
5
  #
6
- # EXPERIMENTAL: This API may change in future minor version bumps.
7
- #
8
6
  # Enables multi-worker environments (Kubernetes, load-balanced servers,
9
7
  # serverless functions) to share flag definitions via an external cache,
10
8
  # reducing redundant API calls.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
- VERSION = '3.9.1'
4
+ VERSION = '3.9.3'
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.1
4
+ version: 3.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''