posthog-ruby 3.11.1 → 3.12.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 +4 -4
- data/lib/posthog/client.rb +50 -8
- data/lib/posthog/feature_flags.rb +3 -1
- data/lib/posthog/send_worker.rb +25 -7
- data/lib/posthog/transport.rb +9 -4
- data/lib/posthog/utils.rb +19 -0
- data/lib/posthog/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f51843606a47a924b1a6b772f02c61c90e9446c16827b3d5b28d92d7fdade73a
|
|
4
|
+
data.tar.gz: 4cfbb395d74bf0f9630b35fafafc6f4eedcdbce9e32a0a8825880f461b581fd9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9978900c0f4091624f901a72396f4b2915cc4532503d1bd3a17c7f7e27a142463f5dbbe8e40d621cb52ae95871055f720d5a1a7a5e4652f266604a7311e2dd68
|
|
7
|
+
data.tar.gz: a815192b4521d259e0f2b8c3adba4c1ef2ef2b30748b4ca56c38f5b4d2b3633b1d500d7b06fe1f51d7e4046d3df618c82e2f5a0ed84ed12eb2f87d94f57dc7b8
|
data/lib/posthog/client.rb
CHANGED
|
@@ -84,10 +84,13 @@ module PostHog
|
|
|
84
84
|
opts[:host] = normalize_host_option(opts[:host])
|
|
85
85
|
|
|
86
86
|
@queue = Queue.new
|
|
87
|
+
@queue_mutex = Mutex.new
|
|
87
88
|
@api_key = opts[:api_key]
|
|
88
89
|
@disabled = @api_key.nil? || @api_key.empty?
|
|
89
90
|
@max_queue_size = opts[:max_queue_size] || Defaults::Queue::MAX_SIZE
|
|
90
91
|
@worker_mutex = Mutex.new
|
|
92
|
+
@shutdown_mutex = Mutex.new
|
|
93
|
+
@shutdown = false
|
|
91
94
|
@sync_mode = opts[:sync_mode] == true && !opts[:test_mode] && !@disabled
|
|
92
95
|
@on_error = opts[:on_error] || proc { |status, error| }
|
|
93
96
|
@worker = if opts[:test_mode] || @disabled
|
|
@@ -139,8 +142,9 @@ module PostHog
|
|
|
139
142
|
)
|
|
140
143
|
end
|
|
141
144
|
|
|
145
|
+
@distinct_id_has_sent_flag_calls_mutex = Mutex.new
|
|
142
146
|
@distinct_id_has_sent_flag_calls = SizeLimitedHash.new(Defaults::MAX_HASH_SIZE) do |hash, key|
|
|
143
|
-
hash[key] =
|
|
147
|
+
hash[key] = SizeLimitedArray.new(Defaults::MAX_HASH_SIZE)
|
|
144
148
|
end
|
|
145
149
|
|
|
146
150
|
@before_send = opts[:before_send]
|
|
@@ -173,7 +177,7 @@ module PostHog
|
|
|
173
177
|
#
|
|
174
178
|
# @return [void]
|
|
175
179
|
def clear
|
|
176
|
-
@queue.clear
|
|
180
|
+
@queue_mutex.synchronize { @queue.clear }
|
|
177
181
|
end
|
|
178
182
|
|
|
179
183
|
# @!macro common_attrs
|
|
@@ -745,10 +749,28 @@ module PostHog
|
|
|
745
749
|
@feature_flags_poller.load_feature_flags(true)
|
|
746
750
|
end
|
|
747
751
|
|
|
752
|
+
# Whether the client will actually send events. It is disabled when the
|
|
753
|
+
# api_key is missing or blank, in which case every capture call no-ops.
|
|
754
|
+
#
|
|
755
|
+
# @return [Boolean]
|
|
756
|
+
def enabled?
|
|
757
|
+
!@disabled
|
|
758
|
+
end
|
|
759
|
+
|
|
748
760
|
# Flush pending events and stop background resources.
|
|
749
761
|
#
|
|
750
762
|
# @return [void]
|
|
751
763
|
def shutdown
|
|
764
|
+
already_shutdown = @shutdown_mutex.synchronize do
|
|
765
|
+
if @shutdown
|
|
766
|
+
true
|
|
767
|
+
else
|
|
768
|
+
@shutdown = true
|
|
769
|
+
false
|
|
770
|
+
end
|
|
771
|
+
end
|
|
772
|
+
return if already_shutdown
|
|
773
|
+
|
|
752
774
|
self.class._decrement_instance_count(@api_key) unless @disabled
|
|
753
775
|
@feature_flags_poller&.shutdown_poller
|
|
754
776
|
flush
|
|
@@ -756,6 +778,7 @@ module PostHog
|
|
|
756
778
|
@sync_lock.synchronize { @transport&.shutdown }
|
|
757
779
|
else
|
|
758
780
|
@worker&.shutdown
|
|
781
|
+
@worker_thread&.join(1)
|
|
759
782
|
end
|
|
760
783
|
end
|
|
761
784
|
|
|
@@ -813,7 +836,16 @@ module PostHog
|
|
|
813
836
|
''
|
|
814
837
|
end
|
|
815
838
|
reported_key = "#{key}_#{response_repr}#{groups_repr}"
|
|
816
|
-
|
|
839
|
+
should_capture = @distinct_id_has_sent_flag_calls_mutex.synchronize do
|
|
840
|
+
sent_keys = @distinct_id_has_sent_flag_calls[distinct_id]
|
|
841
|
+
if sent_keys.include?(reported_key)
|
|
842
|
+
false
|
|
843
|
+
else
|
|
844
|
+
sent_keys << reported_key
|
|
845
|
+
true
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
return unless should_capture
|
|
817
849
|
|
|
818
850
|
msg = {
|
|
819
851
|
distinct_id: distinct_id,
|
|
@@ -824,7 +856,6 @@ module PostHog
|
|
|
824
856
|
msg[:disable_geoip] = disable_geoip unless disable_geoip.nil?
|
|
825
857
|
|
|
826
858
|
capture(msg)
|
|
827
|
-
@distinct_id_has_sent_flag_calls[distinct_id] << reported_key
|
|
828
859
|
end
|
|
829
860
|
|
|
830
861
|
def _feature_flag_evaluations_host
|
|
@@ -913,7 +944,7 @@ module PostHog
|
|
|
913
944
|
#
|
|
914
945
|
# returns Boolean of whether the item was added to the queue.
|
|
915
946
|
def enqueue(action)
|
|
916
|
-
return false if @disabled
|
|
947
|
+
return false if @disabled || shutdown?
|
|
917
948
|
|
|
918
949
|
action = process_before_send(action)
|
|
919
950
|
return false if action.nil? || action.empty?
|
|
@@ -926,10 +957,17 @@ module PostHog
|
|
|
926
957
|
return true
|
|
927
958
|
end
|
|
928
959
|
|
|
929
|
-
|
|
930
|
-
@queue
|
|
931
|
-
|
|
960
|
+
queued = @queue_mutex.synchronize do
|
|
961
|
+
if @queue.length < @max_queue_size
|
|
962
|
+
@queue << action
|
|
963
|
+
true
|
|
964
|
+
else
|
|
965
|
+
false
|
|
966
|
+
end
|
|
967
|
+
end
|
|
932
968
|
|
|
969
|
+
if queued
|
|
970
|
+
ensure_worker_running
|
|
933
971
|
true
|
|
934
972
|
else
|
|
935
973
|
logger.warn(
|
|
@@ -987,6 +1025,10 @@ module PostHog
|
|
|
987
1025
|
@worker_thread&.alive?
|
|
988
1026
|
end
|
|
989
1027
|
|
|
1028
|
+
def shutdown?
|
|
1029
|
+
@shutdown_mutex.synchronize { @shutdown }
|
|
1030
|
+
end
|
|
1031
|
+
|
|
990
1032
|
def add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
|
991
1033
|
groups ||= {}
|
|
992
1034
|
person_properties ||= {}
|
|
@@ -1250,7 +1250,9 @@ module PostHog
|
|
|
1250
1250
|
uri.hostname,
|
|
1251
1251
|
uri.port,
|
|
1252
1252
|
use_ssl: uri.scheme == 'https',
|
|
1253
|
-
|
|
1253
|
+
open_timeout: request_timeout,
|
|
1254
|
+
read_timeout: request_timeout,
|
|
1255
|
+
write_timeout: request_timeout
|
|
1254
1256
|
) do |http|
|
|
1255
1257
|
res = http.request(request_object)
|
|
1256
1258
|
status_code = res.code.to_i
|
data/lib/posthog/send_worker.rb
CHANGED
|
@@ -34,6 +34,8 @@ module PostHog
|
|
|
34
34
|
batch_size = options[:batch_size] || Defaults::MessageBatch::MAX_SIZE
|
|
35
35
|
@batch = MessageBatch.new(batch_size)
|
|
36
36
|
@lock = Mutex.new
|
|
37
|
+
@shutdown_mutex = Mutex.new
|
|
38
|
+
@shutdown = false
|
|
37
39
|
@transport = Transport.new api_host: options[:host], skip_ssl_verification: options[:skip_ssl_verification]
|
|
38
40
|
end
|
|
39
41
|
|
|
@@ -41,26 +43,32 @@ module PostHog
|
|
|
41
43
|
#
|
|
42
44
|
# @return [void]
|
|
43
45
|
def run
|
|
44
|
-
until
|
|
46
|
+
until shutdown?
|
|
45
47
|
return if @queue.empty?
|
|
46
48
|
|
|
47
49
|
@lock.synchronize do
|
|
48
50
|
consume_message_from_queue! until @batch.full? || @queue.empty?
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
begin
|
|
54
|
+
unless @batch.empty?
|
|
55
|
+
res = @transport.send @api_key, @batch
|
|
56
|
+
handle_error(res.status, res.error) unless res.status == 200
|
|
57
|
+
end
|
|
58
|
+
ensure
|
|
59
|
+
@lock.synchronize { @batch.clear }
|
|
54
60
|
end
|
|
55
|
-
|
|
56
|
-
@lock.synchronize { @batch.clear }
|
|
57
61
|
end
|
|
58
62
|
ensure
|
|
63
|
+
# Worker threads exit when the queue is drained and are restarted for the
|
|
64
|
+
# next burst of events. Close the persistent connection on each exit and
|
|
65
|
+
# let Transport reconnect lazily when a future worker sends another batch.
|
|
59
66
|
@transport.shutdown
|
|
60
67
|
end
|
|
61
68
|
|
|
62
69
|
# @return [void]
|
|
63
70
|
def shutdown
|
|
71
|
+
@shutdown_mutex.synchronize { @shutdown = true }
|
|
64
72
|
@transport.shutdown
|
|
65
73
|
end
|
|
66
74
|
|
|
@@ -74,10 +82,20 @@ module PostHog
|
|
|
74
82
|
|
|
75
83
|
private
|
|
76
84
|
|
|
85
|
+
def shutdown?
|
|
86
|
+
@shutdown_mutex.synchronize { @shutdown }
|
|
87
|
+
end
|
|
88
|
+
|
|
77
89
|
def consume_message_from_queue!
|
|
78
90
|
@batch << @queue.pop
|
|
79
91
|
rescue MessageBatch::JSONGenerationError => e
|
|
80
|
-
|
|
92
|
+
handle_error(-1, e.to_s)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def handle_error(status, error)
|
|
96
|
+
@on_error.call(status, error)
|
|
97
|
+
rescue StandardError => e
|
|
98
|
+
logger.error("Error in on_error callback: #{e.message}")
|
|
81
99
|
end
|
|
82
100
|
end
|
|
83
101
|
end
|
data/lib/posthog/transport.rb
CHANGED
|
@@ -52,6 +52,7 @@ module PostHog
|
|
|
52
52
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if options[:skip_ssl_verification]
|
|
53
53
|
|
|
54
54
|
@http = http
|
|
55
|
+
@http_mutex = Mutex.new
|
|
55
56
|
end
|
|
56
57
|
|
|
57
58
|
# Sends a batch of messages to the API
|
|
@@ -91,7 +92,9 @@ module PostHog
|
|
|
91
92
|
#
|
|
92
93
|
# @return [void]
|
|
93
94
|
def shutdown
|
|
94
|
-
@
|
|
95
|
+
@http_mutex.synchronize do
|
|
96
|
+
@http.finish if @http.started?
|
|
97
|
+
end
|
|
95
98
|
end
|
|
96
99
|
|
|
97
100
|
private
|
|
@@ -149,9 +152,11 @@ module PostHog
|
|
|
149
152
|
|
|
150
153
|
[200, '{}']
|
|
151
154
|
else
|
|
152
|
-
@
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
@http_mutex.synchronize do
|
|
156
|
+
@http.start unless @http.started? # Maintain a persistent connection
|
|
157
|
+
response = @http.request(request, payload)
|
|
158
|
+
[response.code.to_i, response.body]
|
|
159
|
+
end
|
|
155
160
|
end
|
|
156
161
|
end
|
|
157
162
|
|
data/lib/posthog/utils.rb
CHANGED
|
@@ -166,5 +166,24 @@ module PostHog
|
|
|
166
166
|
super
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
|
+
|
|
170
|
+
# Array that drops the oldest item when it reaches a maximum length.
|
|
171
|
+
#
|
|
172
|
+
# @api private
|
|
173
|
+
class SizeLimitedArray < Array
|
|
174
|
+
# @param max_length [Integer]
|
|
175
|
+
def initialize(max_length)
|
|
176
|
+
super()
|
|
177
|
+
@max_length = max_length
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @param value [Object]
|
|
181
|
+
# @return [Array]
|
|
182
|
+
def <<(value)
|
|
183
|
+
shift if length >= @max_length
|
|
184
|
+
super
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
private_constant :SizeLimitedArray
|
|
169
188
|
end
|
|
170
189
|
end
|
data/lib/posthog/version.rb
CHANGED