getfluxly 0.1.1 → 0.1.2

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: 7b553cd969af21278e3071f204d9d411f3834b4adfa8bf550c0b89c19808080f
4
- data.tar.gz: ad1dd0761594bbdb6e51bdfa96ce953f5c024835eb1a6fd4a3dc9c881155a51c
3
+ metadata.gz: a785fdebe171148a4796f039e87637fd1356c8236e962298399a1c6f0a2e735a
4
+ data.tar.gz: fd356389bcc839e35de4ac7d2942f796b8e045e815a455d9ebd9fb8d3b5db64d
5
5
  SHA512:
6
- metadata.gz: 28d163f2f11fb101529abc046586c4e095a64a5a16bd42b9b605f1f0862f7d5ef63eb2d90e04a585619080618bd38eade3d86a0fa989a4140316c95ffe1b75a8
7
- data.tar.gz: 4434c2e2c16c502e1e2ae00c88d86b6c65fd6526c651e7c7f064fddd3db8886f33eb1a35767e84f051cb012e81aa79093dcef5ccaff1a71de8a76014ac2b935b
6
+ metadata.gz: a6fb8a5a95dbd841e4e6a2c1844a28b4702a8be0798947ad1ecaaa4c1e30c2be21a468fa88a6fd4f6304bb06a4e8a745a85c082e2f16108934397b2da84b25a4
7
+ data.tar.gz: c698da31e1ad2814c7f3cf3fdcb16e86ad6b9da86040c1ae49247da6a9fbe6e194d579e42952e231b21e7242cd36fc3de69817962250cd7fdb9a32c50e4ea89f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to `getfluxly` (Ruby) will be documented in this file.
4
4
 
5
+ ## [0.1.2] - 2026-07-03
6
+
7
+ ### Fixed
8
+ - `flush_interval` now works: the client starts a background flusher thread
9
+ on the first enqueued event that drains the queue every `flush_interval`
10
+ seconds. Previously the parameter was accepted but never used, so events
11
+ only left the process when the queue reached `flush_at` (default 20), on an
12
+ explicit `flush`, or at graceful interpreter exit — low-volume producers
13
+ effectively never delivered. Set `flush_interval: 0` to disable the flusher
14
+ and restore the old behavior. The flusher survives `fork` (restarts in the
15
+ child) and a failed scheduled flush warns and retries on the next tick.
16
+
5
17
  ## [0.1.1] - 2026-06-23
6
18
 
7
19
  ### Added
@@ -4,8 +4,10 @@ module GetFluxly
4
4
  # Synchronous GetFluxly client.
5
5
  #
6
6
  # Batches events with retry, jitter, and X-Idempotency-Key.
7
- # The background flusher thread drains the queue every
8
- # `flush_interval` seconds. at_exit runs a final flush.
7
+ # A batch goes out when the queue reaches `flush_at`, when the
8
+ # background flusher thread fires (every `flush_interval` seconds
9
+ # once the first event is enqueued; `<= 0` disables it), on an
10
+ # explicit `flush`, and at_exit.
9
11
  class Client
10
12
  DEFAULT_API_HOST = "https://api.getfluxly.com"
11
13
  EVENTS_BATCH_PATH = "/v1/events/batch"
@@ -32,6 +34,11 @@ module GetFluxly
32
34
  @http = Http.new(token: token, api_host: api_host, timeout: timeout, max_retries: max_retries)
33
35
  @shutdown = false
34
36
  @shutdown_mutex = Mutex.new
37
+ @flusher = nil
38
+ @flusher_pid = nil
39
+ @wake_mutex = Mutex.new
40
+ @wake = ConditionVariable.new
41
+ @woken = false
35
42
 
36
43
  return unless register_atexit
37
44
 
@@ -138,11 +145,24 @@ module GetFluxly
138
145
  end
139
146
 
140
147
  def shutdown
148
+ flusher = nil
141
149
  @shutdown_mutex.synchronize do
142
150
  return Batch.empty_flush_result if @shutdown
143
151
 
144
152
  @shutdown = true
153
+ flusher = @flusher
154
+ @flusher = nil
145
155
  end
156
+ # Wake the flusher so it exits promptly, and wait for it so a
157
+ # scheduled flush can't race the final flush below. The join is
158
+ # bounded by one in-flight HTTP round-trip (timeout x retries).
159
+ # @woken makes the wake sticky: a broadcast that lands before the
160
+ # flusher reaches wait would otherwise be lost.
161
+ @wake_mutex.synchronize do
162
+ @woken = true
163
+ @wake.broadcast
164
+ end
165
+ flusher&.join(30) unless flusher == Thread.current
146
166
  flush
147
167
  end
148
168
 
@@ -152,9 +172,42 @@ module GetFluxly
152
172
 
153
173
  def enqueue(payload)
154
174
  size = @batch.enqueue(payload)
175
+ ensure_flusher
155
176
  return flush if size >= @flush_at
156
177
 
157
178
  nil
158
179
  end
180
+
181
+ def ensure_flusher
182
+ return if @flush_interval <= 0
183
+
184
+ @shutdown_mutex.synchronize do
185
+ return if @shutdown
186
+ # Threads don't survive fork; the pid check restarts the
187
+ # flusher in forked workers (puma, sidekiq).
188
+ return if @flusher&.alive? && @flusher_pid == Process.pid
189
+
190
+ @flusher_pid = Process.pid
191
+ @flusher = Thread.new { flush_loop }
192
+ @flusher.name = "getfluxly-flusher"
193
+ end
194
+ end
195
+
196
+ def flush_loop
197
+ loop do
198
+ @wake_mutex.synchronize do
199
+ @wake.wait(@wake_mutex, @flush_interval) unless @woken
200
+ end
201
+ return if @shutdown
202
+
203
+ begin
204
+ flush
205
+ rescue StandardError => e
206
+ # A failed scheduled flush must not kill the thread; flush
207
+ # already requeued any retryable batch.
208
+ warn("[GetFluxly] scheduled flush failed: #{e.class}: #{e.message}")
209
+ end
210
+ end
211
+ end
159
212
  end
160
213
  end
@@ -4,5 +4,5 @@
4
4
  # run `ruby scripts/sync_version.rb` to regenerate.
5
5
 
6
6
  module GetFluxly
7
- VERSION = "0.1.1"
7
+ VERSION = "0.1.2"
8
8
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: getfluxly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - GetFluxly
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-07-03 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: minitest
@@ -95,6 +96,7 @@ metadata:
95
96
  bug_tracker_uri: https://github.com/dineshmiriyala/getfluxly/issues
96
97
  changelog_uri: https://github.com/dineshmiriyala/getfluxly/blob/main/packages/ruby/CHANGELOG.md
97
98
  rubygems_mfa_required: 'true'
99
+ post_install_message:
98
100
  rdoc_options: []
99
101
  require_paths:
100
102
  - lib
@@ -109,7 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
111
  - !ruby/object:Gem::Version
110
112
  version: '0'
111
113
  requirements: []
112
- rubygems_version: 4.0.3
114
+ rubygems_version: 3.5.22
115
+ signing_key:
113
116
  specification_version: 4
114
117
  summary: GetFluxly Ruby SDK
115
118
  test_files: []