waterdrop 2.10.7 → 2.10.8
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/CHANGELOG.md +11 -5
- data/Gemfile +0 -4
- data/Gemfile.lock +2 -11
- data/lib/waterdrop/config.rb +9 -4
- data/lib/waterdrop/polling/queue_pipe.rb +2 -2
- data/lib/waterdrop/producer/transactions.rb +19 -1
- data/lib/waterdrop/producer.rb +1 -0
- data/lib/waterdrop/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: 7681d5f6c3333372a6349ddd24a1e1214a3474135755f918aa554064689976be
|
|
4
|
+
data.tar.gz: 2f9d99fff24a56acaf5575e539d647682b305f303206a75bbf10b128dd8112c8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63fcee865ef2c371bea98931f0b0ae1b5a9c118462acfb56746195547201741bba4cbdc6b6efc5feb1ec100e3c65fea8e6879da5774668f4d83691f4865cebe6
|
|
7
|
+
data.tar.gz: dc4c8e69e8ed7e6312a0aa4b4ccd7eeec3d233113b2b6b80b4308dd6602e40a7a55c3a29842ef80e258d850b3ad93482be5b68f328feebccc36d6809e5509092
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# WaterDrop changelog
|
|
2
2
|
|
|
3
|
+
## 2.10.8 (2026-10-25)
|
|
4
|
+
- [Maintenance] Document that a transaction timeout also raises `:fenced`, indistinguishable from a takeover, and when removing `:fenced` from `non_reloadable_errors` is safe.
|
|
5
|
+
- [Fix] Stop `Producer#close` from raising `Errno::EPIPE` on JRuby when its close signal races the poller closing the pipe.
|
|
6
|
+
- [Fix] Abort a failed transaction only once: raise an abortable commit error as is instead of a follow-up `Operation not valid in state Ready` error, and do not abort after a failed `begin_transaction`.
|
|
7
|
+
|
|
3
8
|
## 2.10.7 (2026-10-19)
|
|
4
9
|
- [Change] Require `karafka-rdkafka` `>=` `0.31.0` so delivery reports carry the message persistence status, latency and broker id.
|
|
10
|
+
- [Maintenance] Stop the transaction purge instrumentation spec from flaking when a slow runner lets librdkafka deliver the message before the abort, which leaves nothing to purge.
|
|
5
11
|
|
|
6
12
|
## 2.10.6 (2026-10-12)
|
|
7
13
|
- **[EOL]** Drop Ruby 3.2 support; require Ruby 3.3+.
|
|
@@ -48,7 +54,7 @@
|
|
|
48
54
|
## 2.10.0 (2026-05-07)
|
|
49
55
|
- [Fix] Clean up the native client, instrumentation callbacks and poller registration when `init_transactions` fails during producer construction, so failed attempts no longer leak threads and file descriptors.
|
|
50
56
|
- **[Breaking]** Skip librdkafka statistics when nothing subscribes to `statistics.emitted` before the rdkafka client is built, to save allocations. To use statistics, subscribe a listener BEFORE the first producer use.
|
|
51
|
-
- **[Breaking]** Raise `WaterDrop::Errors::StatisticsNotEnabledError` when
|
|
57
|
+
- **[Breaking]** Raise `WaterDrop::Errors::StatisticsNotEnabledError` when subscribing to `statistics.emitted` on a monitor whose librdkafka statistics were disabled at client build time, instead of silently doing nothing.
|
|
52
58
|
- [Feature] Add tombstone API (`#tombstone_sync`, `#tombstone_async`, `#tombstone_many_sync`, `#tombstone_many_async`) for producing tombstone records (nil-payload messages) with required key and partition validation. Works with variants.
|
|
53
59
|
- [Fix] Add `ensure_same_process!` to `Poller#unregister` for fork safety, so a child that inherited a pre-fork producer no longer deadlocks on `producer.close`.
|
|
54
60
|
|
|
@@ -57,7 +63,7 @@
|
|
|
57
63
|
- [Fix] Exclude test files, `.github/`, and `log/` directories from gem releases to reduce package size.
|
|
58
64
|
- **[Breaking]** Switch default polling mode from `:thread` to `:fd`. If you experience any issues, you can revert to the previous behavior by setting `config.polling.mode = :thread`. The `:thread` mode will be deprecated in 2.10 and removed in 2.11.
|
|
59
65
|
- **[Breaking]** Decorate only the statistics keys used by the built-in Datadog listener (`tx`, `txretries`, `txerrs`, `rxerrs`). If you use other `_d` or `_fd` keys, set a custom `config.statistics_decorator`.
|
|
60
|
-
- [Feature] Add `config.statistics_decorator` setting to
|
|
66
|
+
- [Feature] Add a `config.statistics_decorator` setting to use a custom `StatisticsDecorator` (e.g. with different `only_keys` and `excluded_keys`).
|
|
61
67
|
- [Change] Upscale default timeout values 3x closer to librdkafka defaults to prevent intermediate timeouts during node recovery (`message.timeout.ms`: 50s → 150s, `transaction.timeout.ms`: 55s → 165s, `max_wait_timeout`: 60s → 180s).
|
|
62
68
|
|
|
63
69
|
**Upgrade Notes**: https://karafka.io/docs/Upgrades-WaterDrop-2.9/
|
|
@@ -65,7 +71,7 @@
|
|
|
65
71
|
## 2.8.16 (2026-02-25)
|
|
66
72
|
- [Feature] Add FD-based polling (`config.polling.mode = :fd`): a single Ruby thread with `IO.select` instead of the default thread mode, with 39-54% higher throughput, lower memory usage and fewer threads.
|
|
67
73
|
- [Feature] Add `config.polling.fd.max_time` setting (default: 100ms) to control maximum polling time per producer per cycle. This enables per-producer priority differentiation.
|
|
68
|
-
- [Feature] Add `Producer#queue_size` (alias: `#queue_length`) to return the count of messages
|
|
74
|
+
- [Feature] Add `Producer#queue_size` (alias: `#queue_length`) to return the count of messages dispatched to librdkafka but not yet sent to the Kafka broker.
|
|
69
75
|
- [Enhancement] Add `poll_nb` and `poll_drain` methods to rdkafka Producer for efficient non-blocking polling without GVL release overhead.
|
|
70
76
|
- [Enhancement] Add `poller.producer_registered` and `poller.producer_unregistered` instrumentation events for FD mode.
|
|
71
77
|
- [Change] Update to use `max_wait_timeout_ms` parameter in rdkafka `AbstractHandle#wait` for consistency with librdkafka conventions.
|
|
@@ -108,10 +114,10 @@
|
|
|
108
114
|
|
|
109
115
|
## 2.8.10 (2025-09-25)
|
|
110
116
|
- [Enhancement] Add `#close` alias for `WaterDrop::ConnectionPool#shutdown` to align with producer API for consistent interface across both individual producers and connection pools.
|
|
111
|
-
- [Enhancement] Add `WaterDrop.monitor`
|
|
117
|
+
- [Enhancement] Add `WaterDrop.monitor` as the preferred alias for `WaterDrop.instrumentation`, matching the per-producer API. `instrumentation` remains as a deprecated alias.
|
|
112
118
|
|
|
113
119
|
## 2.8.9 (2025-09-23)
|
|
114
|
-
- [Enhancement] Add connection pool lifecycle events to global instrumentation
|
|
120
|
+
- [Enhancement] Add connection pool lifecycle events to global instrumentation: `connection_pool.created`, `connection_pool.setup`, `connection_pool.shutdown`, `connection_pool.reload` and `connection_pool.reloaded`.
|
|
115
121
|
- [Enhancement] Add default connection pool transactional direct API.
|
|
116
122
|
|
|
117
123
|
## 2.8.8 (2025-09-23)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
waterdrop (2.10.
|
|
4
|
+
waterdrop (2.10.8)
|
|
5
5
|
karafka-core (>= 2.5.12, < 3.0.0)
|
|
6
6
|
karafka-rdkafka (>= 0.31.0)
|
|
7
7
|
zeitwerk (~> 2.3)
|
|
@@ -9,12 +9,9 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
byebug (13.0.0)
|
|
13
|
-
reline (>= 0.6.0)
|
|
14
12
|
connection_pool (3.0.2)
|
|
15
13
|
drb (2.2.3)
|
|
16
14
|
ffi (1.17.4)
|
|
17
|
-
io-console (0.9.4)
|
|
18
15
|
json (3.0.2)
|
|
19
16
|
karafka-core (2.6.4)
|
|
20
17
|
karafka-rdkafka (>= 0.20.0)
|
|
@@ -35,8 +32,6 @@ GEM
|
|
|
35
32
|
ostruct (0.6.3)
|
|
36
33
|
prism (1.9.0)
|
|
37
34
|
rake (13.4.2)
|
|
38
|
-
reline (0.7.0)
|
|
39
|
-
io-console (~> 0.5)
|
|
40
35
|
ruby2_keywords (0.0.5)
|
|
41
36
|
simplecov (1.3.2)
|
|
42
37
|
warning (1.6.0)
|
|
@@ -46,7 +41,6 @@ PLATFORMS
|
|
|
46
41
|
ruby
|
|
47
42
|
|
|
48
43
|
DEPENDENCIES
|
|
49
|
-
byebug
|
|
50
44
|
connection_pool
|
|
51
45
|
minitest
|
|
52
46
|
mocha
|
|
@@ -57,11 +51,9 @@ DEPENDENCIES
|
|
|
57
51
|
zeitwerk (~> 2.8.0)
|
|
58
52
|
|
|
59
53
|
CHECKSUMS
|
|
60
|
-
byebug (13.0.0) sha256=d2263efe751941ca520fa29744b71972d39cbc41839496706f5d9b22e92ae05d
|
|
61
54
|
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
|
|
62
55
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
63
56
|
ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf
|
|
64
|
-
io-console (0.9.4) sha256=a403304f32928ee85e56d457b4612ca43f2703b561a3258844992bd24085fbb1
|
|
65
57
|
json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
|
66
58
|
karafka-core (2.6.4) sha256=e08166ca7ef12fadf0500f2a3aba63b5ba918a98533c3feaac9f43c90f159363
|
|
67
59
|
karafka-rdkafka (0.31.0) sha256=7d21274122d66ee8d08b8e56a0d06084933deb2306cf2a6e4bd0d073c14e7f9f
|
|
@@ -72,11 +64,10 @@ CHECKSUMS
|
|
|
72
64
|
ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
|
|
73
65
|
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
74
66
|
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
|
75
|
-
reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d
|
|
76
67
|
ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef
|
|
77
68
|
simplecov (1.3.2) sha256=2a22ec1759f1b8db60881a2e038758956fc69ef93ed669be0bde0678de6d0e85
|
|
78
69
|
warning (1.6.0) sha256=a49cdfae19fb77d19afff2efbe45f8ab759e9cd25b4e4ce2c79dbaf46bdb6c9e
|
|
79
|
-
waterdrop (2.10.
|
|
70
|
+
waterdrop (2.10.8)
|
|
80
71
|
zeitwerk (2.8.3) sha256=2c85125a8467ce069e20123d1e709a08955c9d29c118c25b46b7b7fafdbb92e5
|
|
81
72
|
|
|
82
73
|
BUNDLED WITH
|
data/lib/waterdrop/config.rb
CHANGED
|
@@ -130,13 +130,18 @@ module WaterDrop
|
|
|
130
130
|
# WARNING: Modifying this setting can cause infinite reload loops if not properly understood.
|
|
131
131
|
# The default includes :fenced errors because:
|
|
132
132
|
# - Fencing occurs when another producer with the same transactional.id takes over
|
|
133
|
-
# -
|
|
133
|
+
# - Fencing also occurs when the broker aborts a transaction that exceeded
|
|
134
|
+
# `transaction.timeout.ms`. Both cases raise the same :fenced error, so WaterDrop cannot
|
|
135
|
+
# tell them apart
|
|
136
|
+
# - After a takeover this is an unrecoverable state - reloading won't help as the other
|
|
137
|
+
# producer is active
|
|
134
138
|
# - Attempting to reload on fenced errors creates: produce -> fenced -> reload -> produce ->
|
|
135
139
|
# fenced -> reload (infinite loop)
|
|
136
140
|
#
|
|
137
|
-
# Only remove :fenced from this list if
|
|
138
|
-
#
|
|
139
|
-
#
|
|
141
|
+
# Only remove :fenced from this list if each transactional.id is used by one producer at a
|
|
142
|
+
# time (e.g., coordinated transactional.id assignment). Otherwise a reload fences the newer
|
|
143
|
+
# producer and the two can keep fencing each other for as long as both run. In most cases,
|
|
144
|
+
# you should keep the default value.
|
|
140
145
|
setting :non_reloadable_errors, default: %i[fenced]
|
|
141
146
|
# option [Integer] Idle disconnect timeout in milliseconds. When set to 0, idle disconnection
|
|
142
147
|
# is disabled. When set to a positive value, WaterDrop will automatically disconnect
|
|
@@ -29,8 +29,8 @@ module WaterDrop
|
|
|
29
29
|
# Thread-safe and non-blocking; silently ignores errors
|
|
30
30
|
def signal
|
|
31
31
|
@writer.write_nonblock("W", exception: false)
|
|
32
|
-
rescue IOError, Errno::EBADF
|
|
33
|
-
# Pipe closed
|
|
32
|
+
rescue IOError, Errno::EBADF, Errno::EPIPE
|
|
33
|
+
# Pipe closed. EPIPE: the reader is already closed, so there is no one left to wake
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Drains all pending bytes from the pipe
|
|
@@ -65,7 +65,12 @@ module WaterDrop
|
|
|
65
65
|
|
|
66
66
|
transactional_instrument(:finished) do
|
|
67
67
|
with_transactional_error_handling(:begin) do
|
|
68
|
-
transactional_instrument(:started)
|
|
68
|
+
transactional_instrument(:started) do
|
|
69
|
+
client.begin_transaction
|
|
70
|
+
# Set before the `started` listeners run, so an error raised by one of them still
|
|
71
|
+
# aborts the transaction that has begun
|
|
72
|
+
@transaction_open = true
|
|
73
|
+
end
|
|
69
74
|
end
|
|
70
75
|
|
|
71
76
|
result = nil
|
|
@@ -100,6 +105,15 @@ module WaterDrop
|
|
|
100
105
|
# We need to handle any interrupt including critical in order not to have the transaction
|
|
101
106
|
# running. This will also handle things like `IRB::Abort`
|
|
102
107
|
rescue Exception => e
|
|
108
|
+
# Neither a transaction that never began nor one the error handling already aborted
|
|
109
|
+
# (abortable error) has anything left to abort: aborting again would fail with an
|
|
110
|
+
# invalid state error that replaces the original one
|
|
111
|
+
unless @transaction_open
|
|
112
|
+
transactional_reload_client_if_needed(e)
|
|
113
|
+
|
|
114
|
+
raise
|
|
115
|
+
end
|
|
116
|
+
|
|
103
117
|
# This code is a bit tricky. We have an error and when it happens we try to rollback
|
|
104
118
|
# the transaction. However we may end up in a state where transaction aborting itself
|
|
105
119
|
# produces error. In such case we also want to handle it as fatal and reload client.
|
|
@@ -124,6 +138,8 @@ module WaterDrop
|
|
|
124
138
|
|
|
125
139
|
raise unless e.is_a?(WaterDrop::Errors::AbortTransaction)
|
|
126
140
|
ensure
|
|
141
|
+
@transaction_open = false
|
|
142
|
+
|
|
127
143
|
# The first delivery handle is scoped to the transaction that produced it and is only
|
|
128
144
|
# ever read by the abort path (which runs in the rescue above, before this). Clearing it
|
|
129
145
|
# here - on commit, on abort and on a re-raise alike - keeps it from outliving its
|
|
@@ -273,6 +289,8 @@ module WaterDrop
|
|
|
273
289
|
with_transactional_error_handling(:abort, allow_abortable: false) do
|
|
274
290
|
transactional_instrument(:aborted) { client.abort_transaction }
|
|
275
291
|
end
|
|
292
|
+
|
|
293
|
+
@transaction_open = false
|
|
276
294
|
end
|
|
277
295
|
|
|
278
296
|
raise
|
data/lib/waterdrop/producer.rb
CHANGED
data/lib/waterdrop/version.rb
CHANGED