posthog-ruby 3.14.3 → 3.15.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/backoff_policy.rb +1 -1
- data/lib/posthog/client.rb +5 -1
- data/lib/posthog/feature_flags.rb +1 -1
- data/lib/posthog/send_worker.rb +7 -1
- data/lib/posthog/transport.rb +54 -9
- 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: edb7fbf2f848ccb05f6a79f9c3429d395ac39cde5fdd1f83c59d97990231cbc8
|
|
4
|
+
data.tar.gz: bf96ccaccf1cf2117b502311895d95eb32de786b005809bf1d03471c67fc3920
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a60d451d311741d7d3407515a8b05a0029a24d098445aae51fe4c4d51ab894c4005c0f78267f4d5717681a258ef83091e62e508d8f902068a6e9321ceead274b
|
|
7
|
+
data.tar.gz: 01b522405e918921a9667a1cf47271b314cf55cada33687ea31d8c2ed04239f602f61adf35c891920691c25a10d0ac6ad76c816ef2160b3ccfaf6208e564baa1
|
data/lib/posthog/client.rb
CHANGED
|
@@ -67,6 +67,8 @@ module PostHog
|
|
|
67
67
|
# in seconds. Defaults to 30.
|
|
68
68
|
# @option opts [Integer] :feature_flag_request_timeout_seconds How long to wait for feature flag evaluation,
|
|
69
69
|
# in seconds. Defaults to 3.
|
|
70
|
+
# @option opts [Integer] :max_retries How many times to retry batch uploads after the first send attempt.
|
|
71
|
+
# Defaults to the transport default. Set to 0 to disable retrying.
|
|
70
72
|
# @option opts [Integer] :feature_flag_request_max_retries How many times to retry a flag request after a
|
|
71
73
|
# transient network error. Each retry sleeps on the calling thread before retrying, so this adds to
|
|
72
74
|
# worst-case latency. Defaults to 1. Set to 0 to disable retrying.
|
|
@@ -76,6 +78,7 @@ module PostHog
|
|
|
76
78
|
# the same API key. Use only when you intentionally need multiple clients. Defaults to +false+.
|
|
77
79
|
# @option opts [Boolean] :skip_ssl_verification +true+ to disable SSL certificate verification for requests.
|
|
78
80
|
# Intended only for local development or custom deployments.
|
|
81
|
+
# @option opts [Boolean] :compress_request Set to +false+ to disable gzip compression for batch uploads.
|
|
79
82
|
# @option opts [Object] :flag_definition_cache_provider An object implementing the {FlagDefinitionCacheProvider}
|
|
80
83
|
# interface for distributed flag definition caching.
|
|
81
84
|
# @option opts [Boolean] :is_server +true+ to stamp captured events with `$is_server => true` so PostHog
|
|
@@ -109,7 +112,8 @@ module PostHog
|
|
|
109
112
|
@transport = Transport.new(
|
|
110
113
|
api_host: opts[:host],
|
|
111
114
|
skip_ssl_verification: opts[:skip_ssl_verification],
|
|
112
|
-
retries: 3
|
|
115
|
+
retries: opts.key?(:max_retries) ? opts[:max_retries].to_i + 1 : 3,
|
|
116
|
+
compress_request: opts[:compress_request]
|
|
113
117
|
)
|
|
114
118
|
@sync_lock = Mutex.new
|
|
115
119
|
end
|
|
@@ -150,7 +150,7 @@ module PostHog
|
|
|
150
150
|
group_properties: group_properties
|
|
151
151
|
}
|
|
152
152
|
request_data[:flag_keys_to_evaluate] = flag_keys if flag_keys && !flag_keys.empty?
|
|
153
|
-
request_data[:geoip_disable] =
|
|
153
|
+
request_data[:geoip_disable] = disable_geoip unless disable_geoip.nil?
|
|
154
154
|
|
|
155
155
|
flags_response = _request_feature_flag_evaluation(request_data)
|
|
156
156
|
|
data/lib/posthog/send_worker.rb
CHANGED
|
@@ -27,6 +27,7 @@ module PostHog
|
|
|
27
27
|
# @option options [Proc] :on_error Callback invoked as `on_error.call(status, error)`.
|
|
28
28
|
# @option options [String] :host PostHog API host URL.
|
|
29
29
|
# @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
|
|
30
|
+
# @option options [Boolean] :compress_request Set to +false+ to disable gzip batch request bodies.
|
|
30
31
|
def initialize(queue, api_key, options = {})
|
|
31
32
|
symbolize_keys! options
|
|
32
33
|
@queue = queue
|
|
@@ -42,7 +43,12 @@ module PostHog
|
|
|
42
43
|
@flush_requested = false
|
|
43
44
|
@shutdown = false
|
|
44
45
|
@pid = Process.pid
|
|
45
|
-
@transport_options = {
|
|
46
|
+
@transport_options = {
|
|
47
|
+
api_host: options[:host],
|
|
48
|
+
skip_ssl_verification: options[:skip_ssl_verification],
|
|
49
|
+
compress_request: options[:compress_request]
|
|
50
|
+
}
|
|
51
|
+
@transport_options[:retries] = options[:max_retries].to_i + 1 if options.key?(:max_retries)
|
|
46
52
|
@transport = Transport.new(@transport_options)
|
|
47
53
|
end
|
|
48
54
|
|
data/lib/posthog/transport.rb
CHANGED
|
@@ -8,6 +8,8 @@ require 'posthog/backoff_policy'
|
|
|
8
8
|
require 'net/http'
|
|
9
9
|
require 'net/https'
|
|
10
10
|
require 'json'
|
|
11
|
+
require 'time'
|
|
12
|
+
require 'zlib'
|
|
11
13
|
|
|
12
14
|
module PostHog
|
|
13
15
|
# HTTP transport used by the SDK workers.
|
|
@@ -28,6 +30,7 @@ module PostHog
|
|
|
28
30
|
# @option options [Integer] :retries Number of retry attempts for retryable failures.
|
|
29
31
|
# @option options [PostHog::BackoffPolicy] :backoff_policy Backoff policy used between retries.
|
|
30
32
|
# @option options [Boolean] :skip_ssl_verification Disable SSL certificate verification.
|
|
33
|
+
# @option options [Boolean] :compress_request Whether to gzip batch request bodies. Defaults to +true+.
|
|
31
34
|
def initialize(options = {})
|
|
32
35
|
if options[:api_host]
|
|
33
36
|
uri = URI.parse(options[:api_host])
|
|
@@ -40,10 +43,12 @@ module PostHog
|
|
|
40
43
|
options[:port] = options[:port].nil? ? PORT : options[:port]
|
|
41
44
|
options[:ssl] = options[:ssl].nil? ? SSL : options[:ssl]
|
|
42
45
|
|
|
43
|
-
@headers = options[:headers] || HEADERS
|
|
46
|
+
@headers = (options[:headers] || HEADERS).dup
|
|
44
47
|
@path = options[:path] || PATH
|
|
45
48
|
@retries = options[:retries] || RETRIES
|
|
46
49
|
@backoff_policy = options[:backoff_policy] || PostHog::BackoffPolicy.new
|
|
50
|
+
@compress_request = options[:compress_request] != false
|
|
51
|
+
@last_retry_after = nil
|
|
47
52
|
|
|
48
53
|
http = Net::HTTP.new(options[:host], options[:port])
|
|
49
54
|
http.use_ssl = options[:ssl]
|
|
@@ -100,10 +105,8 @@ module PostHog
|
|
|
100
105
|
private
|
|
101
106
|
|
|
102
107
|
def should_retry_request?(status_code, body)
|
|
103
|
-
if status_code >= 500
|
|
104
|
-
true # Server error
|
|
105
|
-
elsif status_code == 429 # rubocop:disable Lint/DuplicateBranch
|
|
106
|
-
true # Rate limited
|
|
108
|
+
if status_code >= 500 || [408, 429].include?(status_code)
|
|
109
|
+
true # Server error, request timeout, or rate limited
|
|
107
110
|
elsif status_code >= 400
|
|
108
111
|
logger.error(body)
|
|
109
112
|
false # Client error. Do not retry, but log
|
|
@@ -133,33 +136,75 @@ module PostHog
|
|
|
133
136
|
|
|
134
137
|
if should_retry && (retries_remaining > 1)
|
|
135
138
|
logger.debug("Retrying request, #{retries_remaining} retries left")
|
|
136
|
-
sleep(
|
|
139
|
+
sleep(retry_delay_seconds)
|
|
137
140
|
retry_with_backoff(retries_remaining - 1, &block)
|
|
138
141
|
else
|
|
139
142
|
[result, caught_exception]
|
|
140
143
|
end
|
|
141
144
|
end
|
|
142
145
|
|
|
146
|
+
def retry_delay_seconds
|
|
147
|
+
retry_after = parse_retry_after(@last_retry_after)
|
|
148
|
+
@last_retry_after = nil
|
|
149
|
+
return retry_after if retry_after
|
|
150
|
+
|
|
151
|
+
@backoff_policy.next_interval.to_f / 1000
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def parse_retry_after(value)
|
|
155
|
+
return nil if value.nil? || value.empty?
|
|
156
|
+
|
|
157
|
+
seconds = Float(value, exception: false)
|
|
158
|
+
return seconds if seconds && seconds >= 0
|
|
159
|
+
|
|
160
|
+
parsed_time = Time.httpdate(value)
|
|
161
|
+
delay = parsed_time - Time.now
|
|
162
|
+
delay.positive? ? delay : nil
|
|
163
|
+
rescue ArgumentError
|
|
164
|
+
nil
|
|
165
|
+
end
|
|
166
|
+
|
|
143
167
|
# Sends a request for the batch, returns [status_code, body]
|
|
144
168
|
def send_request(api_key, batch)
|
|
169
|
+
@last_retry_after = nil
|
|
145
170
|
payload = JSON.generate(api_key: api_key, batch: batch)
|
|
146
171
|
|
|
147
|
-
|
|
172
|
+
request_path, request_headers, request_payload = build_request(@path, @headers, payload)
|
|
173
|
+
request = Net::HTTP::Post.new(request_path, request_headers)
|
|
148
174
|
|
|
149
175
|
if self.class.stub
|
|
150
|
-
logger.debug "stubbed request to #{
|
|
176
|
+
logger.debug "stubbed request to #{request_path}: " \
|
|
151
177
|
"api key = #{api_key}, batch = #{JSON.generate(batch)}"
|
|
152
178
|
|
|
153
179
|
[200, '{}']
|
|
154
180
|
else
|
|
155
181
|
@http_mutex.synchronize do
|
|
156
182
|
@http.start unless @http.started? # Maintain a persistent connection
|
|
157
|
-
response = @http.request(request,
|
|
183
|
+
response = @http.request(request, request_payload)
|
|
184
|
+
@last_retry_after = response['Retry-After']
|
|
158
185
|
[response.code.to_i, response.body]
|
|
159
186
|
end
|
|
160
187
|
end
|
|
161
188
|
end
|
|
162
189
|
|
|
190
|
+
def build_request(path, headers, payload)
|
|
191
|
+
return [path, headers, payload] unless @compress_request
|
|
192
|
+
|
|
193
|
+
compressed_payload = gzip_payload(payload)
|
|
194
|
+
return [path, headers, payload] unless compressed_payload
|
|
195
|
+
|
|
196
|
+
compressed_headers = headers.merge('Content-Encoding' => 'gzip')
|
|
197
|
+
|
|
198
|
+
[path, compressed_headers, compressed_payload]
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def gzip_payload(payload)
|
|
202
|
+
Zlib.gzip(payload)
|
|
203
|
+
rescue Zlib::Error => e
|
|
204
|
+
logger.warn("gzip compression failed; sending uncompressed - #{e.message}")
|
|
205
|
+
nil
|
|
206
|
+
end
|
|
207
|
+
|
|
163
208
|
class << self
|
|
164
209
|
attr_writer :stub
|
|
165
210
|
|
data/lib/posthog/version.rb
CHANGED