posthog-ruby 3.12.0 → 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 +42 -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
|
|
@@ -757,6 +761,16 @@ module PostHog
|
|
|
757
761
|
#
|
|
758
762
|
# @return [void]
|
|
759
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
|
+
|
|
760
774
|
self.class._decrement_instance_count(@api_key) unless @disabled
|
|
761
775
|
@feature_flags_poller&.shutdown_poller
|
|
762
776
|
flush
|
|
@@ -764,6 +778,7 @@ module PostHog
|
|
|
764
778
|
@sync_lock.synchronize { @transport&.shutdown }
|
|
765
779
|
else
|
|
766
780
|
@worker&.shutdown
|
|
781
|
+
@worker_thread&.join(1)
|
|
767
782
|
end
|
|
768
783
|
end
|
|
769
784
|
|
|
@@ -821,7 +836,16 @@ module PostHog
|
|
|
821
836
|
''
|
|
822
837
|
end
|
|
823
838
|
reported_key = "#{key}_#{response_repr}#{groups_repr}"
|
|
824
|
-
|
|
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
|
|
825
849
|
|
|
826
850
|
msg = {
|
|
827
851
|
distinct_id: distinct_id,
|
|
@@ -832,7 +856,6 @@ module PostHog
|
|
|
832
856
|
msg[:disable_geoip] = disable_geoip unless disable_geoip.nil?
|
|
833
857
|
|
|
834
858
|
capture(msg)
|
|
835
|
-
@distinct_id_has_sent_flag_calls[distinct_id] << reported_key
|
|
836
859
|
end
|
|
837
860
|
|
|
838
861
|
def _feature_flag_evaluations_host
|
|
@@ -921,7 +944,7 @@ module PostHog
|
|
|
921
944
|
#
|
|
922
945
|
# returns Boolean of whether the item was added to the queue.
|
|
923
946
|
def enqueue(action)
|
|
924
|
-
return false if @disabled
|
|
947
|
+
return false if @disabled || shutdown?
|
|
925
948
|
|
|
926
949
|
action = process_before_send(action)
|
|
927
950
|
return false if action.nil? || action.empty?
|
|
@@ -934,10 +957,17 @@ module PostHog
|
|
|
934
957
|
return true
|
|
935
958
|
end
|
|
936
959
|
|
|
937
|
-
|
|
938
|
-
@queue
|
|
939
|
-
|
|
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
|
|
940
968
|
|
|
969
|
+
if queued
|
|
970
|
+
ensure_worker_running
|
|
941
971
|
true
|
|
942
972
|
else
|
|
943
973
|
logger.warn(
|
|
@@ -995,6 +1025,10 @@ module PostHog
|
|
|
995
1025
|
@worker_thread&.alive?
|
|
996
1026
|
end
|
|
997
1027
|
|
|
1028
|
+
def shutdown?
|
|
1029
|
+
@shutdown_mutex.synchronize { @shutdown }
|
|
1030
|
+
end
|
|
1031
|
+
|
|
998
1032
|
def add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
|
|
999
1033
|
groups ||= {}
|
|
1000
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