waterdrop 2.6.1 → 2.6.3
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
- checksums.yaml.gz.sig +4 -2
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +5 -5
- data/lib/waterdrop/clients/buffered.rb +2 -2
- data/lib/waterdrop/producer/async.rb +0 -4
- data/lib/waterdrop/producer/buffer.rb +1 -4
- data/lib/waterdrop/producer/sync.rb +0 -4
- data/lib/waterdrop/producer.rb +28 -6
- data/lib/waterdrop/version.rb +1 -1
- data/lib/waterdrop.rb +1 -0
- data/waterdrop.gemspec +1 -1
- data.tar.gz.sig +4 -3
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f051a62baab08b5b23bb85a5b2264f3b33bebb77c0f3628ed90eda5eda8c22f2
|
4
|
+
data.tar.gz: 9a5f27b24bee02bb2efcaeec926a8568c540c420c77cf1c9a06a6d72fcf496b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fd5cd82e391ad95e9c48b4e6794ad6b4e0715b6f4a64e838c676064b96e22c2c0a0cea1f18e4131c5dc60ae33923b943d2828278404038f5f7a79b754cb6e37
|
7
|
+
data.tar.gz: 004d5f3fdbbe48733ba47f132e12dcf1bd3ab5e0705181825f8e93b207e12b955b97cf6c283dcb58049153dd3325dd3ea655130e60982d0300ec309460e0d583
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
��
|
1
|
+
�N>�c����(�P}cRMo4�xB�=_qQ`��YG��+�vX�
|
2
|
+
��+rH�AT�Wq��\�����]h3�X��f��=�'{��Cᮄ��hRp8Ҵ e8�H=D��3�{y;����/�Bqkm�+�q�?'6�*q�S| ,ԡl�tg��� �+�����"��8�\�3�7#߀)PZ��(����7�����*Y&3
|
3
|
+
!J�5F�%��VҾ5�s^q�6dy���(�4�^�m+�?�x�g )�ގt���9�u��7Q�7o�$�����k�
|
4
|
+
�����a���+vT�g7��]o,f�&�X)�?
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# WaterDrop changelog
|
2
2
|
|
3
|
+
### 2.6.3 (2023-06-28)
|
4
|
+
- [Change] Use `Concurrent::AtomicFixnum` to track operations in progress to prevent potential race conditions on JRuby and TruffleRuby (not yet supported but this is for future usage).
|
5
|
+
- [Change] Require `karafka-rdkafka` `>= 0.13.2`.
|
6
|
+
- [Change] Require 'karafka-core' `>= 2.1.1`
|
7
|
+
|
8
|
+
### 2.6.2 (2023-06-21)
|
9
|
+
- [Refactor] Introduce a counter-based locking approach to make sure, that we close the producer safely but at the same time not to limit messages production with producing lock.
|
10
|
+
- [Refactor] Make private methods private.
|
11
|
+
- [Refactor] Validate that producer is not closed only when attempting to produce.
|
12
|
+
- [Refactor] Improve one 5 minute long spec to run in 10 seconds.
|
13
|
+
- [Refactor] clear client assignment after closing.
|
14
|
+
|
3
15
|
### 2.6.1 (2023-06-19)
|
4
16
|
- [Refactor] Remove no longer needed patches.
|
5
17
|
- [Fix] Fork detection on a short lived processes seems to fail. Clear the used parent process client reference not to close it in the finalizer (#356).
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
waterdrop (2.6.
|
5
|
-
karafka-core (>= 2.1.
|
4
|
+
waterdrop (2.6.3)
|
5
|
+
karafka-core (>= 2.1.1, < 3.0.0)
|
6
6
|
zeitwerk (~> 2.3)
|
7
7
|
|
8
8
|
GEM
|
@@ -22,10 +22,10 @@ GEM
|
|
22
22
|
ffi (1.15.5)
|
23
23
|
i18n (1.14.1)
|
24
24
|
concurrent-ruby (~> 1.0)
|
25
|
-
karafka-core (2.1.
|
25
|
+
karafka-core (2.1.1)
|
26
26
|
concurrent-ruby (>= 1.1)
|
27
|
-
karafka-rdkafka (>= 0.13.
|
28
|
-
karafka-rdkafka (0.13.
|
27
|
+
karafka-rdkafka (>= 0.13.1, < 0.14.0)
|
28
|
+
karafka-rdkafka (0.13.2)
|
29
29
|
ffi (~> 1.15)
|
30
30
|
mini_portile2 (~> 2.6)
|
31
31
|
rake (> 12)
|
@@ -24,8 +24,8 @@ module WaterDrop
|
|
24
24
|
# "Produces" message to Kafka: it acknowledges it locally, adds it to the internal buffer
|
25
25
|
# @param message [Hash] `WaterDrop::Producer#produce_sync` message hash
|
26
26
|
def produce(message)
|
27
|
-
|
28
|
-
@topics[topic] << message
|
27
|
+
# We pre-validate the message payload, so topic is ensured to be present
|
28
|
+
@topics[message.fetch(:topic)] << message
|
29
29
|
@messages << message
|
30
30
|
SyncResponse.new
|
31
31
|
end
|
@@ -14,8 +14,6 @@ module WaterDrop
|
|
14
14
|
# @raise [Errors::MessageInvalidError] When provided message details are invalid and the
|
15
15
|
# message could not be sent to Kafka
|
16
16
|
def produce_async(message)
|
17
|
-
ensure_active!
|
18
|
-
|
19
17
|
message = middleware.run(message)
|
20
18
|
validate_message!(message)
|
21
19
|
|
@@ -49,8 +47,6 @@ module WaterDrop
|
|
49
47
|
# @raise [Errors::MessageInvalidError] When any of the provided messages details are invalid
|
50
48
|
# and the message could not be sent to Kafka
|
51
49
|
def produce_many_async(messages)
|
52
|
-
ensure_active!
|
53
|
-
|
54
50
|
dispatched = []
|
55
51
|
messages = middleware.run_many(messages)
|
56
52
|
messages.each { |message| validate_message!(message) }
|
@@ -11,6 +11,7 @@ module WaterDrop
|
|
11
11
|
# message could not be sent to Kafka
|
12
12
|
def buffer(message)
|
13
13
|
ensure_active!
|
14
|
+
|
14
15
|
message = middleware.run(message)
|
15
16
|
validate_message!(message)
|
16
17
|
|
@@ -49,8 +50,6 @@ module WaterDrop
|
|
49
50
|
# @return [Array<Rdkafka::Producer::DeliveryHandle>] delivery handles for messages that were
|
50
51
|
# flushed
|
51
52
|
def flush_async
|
52
|
-
ensure_active!
|
53
|
-
|
54
53
|
@monitor.instrument(
|
55
54
|
'buffer.flushed_async',
|
56
55
|
producer_id: id,
|
@@ -62,8 +61,6 @@ module WaterDrop
|
|
62
61
|
# @return [Array<Rdkafka::Producer::DeliveryReport>] delivery reports for messages that were
|
63
62
|
# flushed
|
64
63
|
def flush_sync
|
65
|
-
ensure_active!
|
66
|
-
|
67
64
|
@monitor.instrument(
|
68
65
|
'buffer.flushed_sync',
|
69
66
|
producer_id: id,
|
@@ -16,8 +16,6 @@ module WaterDrop
|
|
16
16
|
# @raise [Errors::MessageInvalidError] When provided message details are invalid and the
|
17
17
|
# message could not be sent to Kafka
|
18
18
|
def produce_sync(message)
|
19
|
-
ensure_active!
|
20
|
-
|
21
19
|
message = middleware.run(message)
|
22
20
|
validate_message!(message)
|
23
21
|
|
@@ -55,8 +53,6 @@ module WaterDrop
|
|
55
53
|
# @raise [Errors::MessageInvalidError] When any of the provided messages details are invalid
|
56
54
|
# and the message could not be sent to Kafka
|
57
55
|
def produce_many_sync(messages)
|
58
|
-
ensure_active! unless @closing_thread_id && @closing_thread_id == Thread.current.object_id
|
59
|
-
|
60
56
|
messages = middleware.run_many(messages)
|
61
57
|
messages.each { |message| validate_message!(message) }
|
62
58
|
|
data/lib/waterdrop/producer.rb
CHANGED
@@ -34,9 +34,10 @@ module WaterDrop
|
|
34
34
|
# @param block [Proc] configuration block
|
35
35
|
# @return [Producer] producer instance
|
36
36
|
def initialize(&block)
|
37
|
+
@operations_in_progress = Concurrent::AtomicFixnum.new(0)
|
37
38
|
@buffer_mutex = Mutex.new
|
38
39
|
@connecting_mutex = Mutex.new
|
39
|
-
@
|
40
|
+
@operating_mutex = Mutex.new
|
40
41
|
|
41
42
|
@status = Status.new
|
42
43
|
@messages = Concurrent::Array.new
|
@@ -118,7 +119,7 @@ module WaterDrop
|
|
118
119
|
|
119
120
|
# Flushes the buffers in a sync way and closes the producer
|
120
121
|
def close
|
121
|
-
@
|
122
|
+
@operating_mutex.synchronize do
|
122
123
|
return unless @status.active?
|
123
124
|
|
124
125
|
@monitor.instrument(
|
@@ -135,6 +136,10 @@ module WaterDrop
|
|
135
136
|
# producer for final flush of buffers.
|
136
137
|
@closing_thread_id = Thread.current.object_id
|
137
138
|
|
139
|
+
# Wait until all the outgoing operations are done. Only when no one is using the
|
140
|
+
# underlying client running operations we can close
|
141
|
+
sleep(0.001) until @operations_in_progress.value.zero?
|
142
|
+
|
138
143
|
# Flush has its own buffer mutex but even if it is blocked, flushing can still happen
|
139
144
|
# as we close the client after the flushing (even if blocked by the mutex)
|
140
145
|
flush(true)
|
@@ -143,7 +148,10 @@ module WaterDrop
|
|
143
148
|
# It is safe to run it several times but not exactly the same moment
|
144
149
|
# We also mark it as closed only if it was connected, if not, it would trigger a new
|
145
150
|
# connection that anyhow would be immediately closed
|
146
|
-
|
151
|
+
if @client
|
152
|
+
client.close
|
153
|
+
@client = nil
|
154
|
+
end
|
147
155
|
|
148
156
|
# Remove callbacks runners that were registered
|
149
157
|
::Karafka::Core::Instrumentation.statistics_callbacks.delete(@id)
|
@@ -154,13 +162,17 @@ module WaterDrop
|
|
154
162
|
end
|
155
163
|
end
|
156
164
|
|
165
|
+
private
|
166
|
+
|
157
167
|
# Ensures that we don't run any operations when the producer is not configured or when it
|
158
168
|
# was already closed
|
159
169
|
def ensure_active!
|
160
170
|
return if @status.active?
|
171
|
+
return if @status.closing? && @operating_mutex.owned?
|
161
172
|
|
162
173
|
raise Errors::ProducerNotConfiguredError, id if @status.initial?
|
163
|
-
raise Errors::ProducerClosedError, id if @status.closing?
|
174
|
+
raise Errors::ProducerClosedError, id if @status.closing?
|
175
|
+
raise Errors::ProducerClosedError, id if @status.closed?
|
164
176
|
|
165
177
|
# This should never happen
|
166
178
|
raise Errors::StatusInvalidError, [id, @status.to_s]
|
@@ -184,14 +196,21 @@ module WaterDrop
|
|
184
196
|
)
|
185
197
|
end
|
186
198
|
|
187
|
-
private
|
188
|
-
|
189
199
|
# Runs the client produce method with a given message
|
190
200
|
#
|
191
201
|
# @param message [Hash] message we want to send
|
192
202
|
def produce(message)
|
193
203
|
produce_time ||= monotonic_now
|
194
204
|
|
205
|
+
# This can happen only during flushing on closing, in case like this we don't have to
|
206
|
+
# synchronize because we already own the lock
|
207
|
+
if @operating_mutex.owned?
|
208
|
+
@operations_in_progress.increment
|
209
|
+
else
|
210
|
+
@operating_mutex.synchronize { @operations_in_progress.increment }
|
211
|
+
ensure_active!
|
212
|
+
end
|
213
|
+
|
195
214
|
client.produce(**message)
|
196
215
|
rescue SUPPORTED_FLOW_ERRORS.first => e
|
197
216
|
# Unless we want to wait and retry and it's a full queue, we raise normally
|
@@ -229,7 +248,10 @@ module WaterDrop
|
|
229
248
|
sleep @config.wait_backoff_on_queue_full
|
230
249
|
end
|
231
250
|
|
251
|
+
@operations_in_progress.decrement
|
232
252
|
retry
|
253
|
+
ensure
|
254
|
+
@operations_in_progress.decrement
|
233
255
|
end
|
234
256
|
end
|
235
257
|
end
|
data/lib/waterdrop/version.rb
CHANGED
data/lib/waterdrop.rb
CHANGED
data/waterdrop.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.description = spec.summary
|
17
17
|
spec.license = 'MIT'
|
18
18
|
|
19
|
-
spec.add_dependency 'karafka-core', '>= 2.1.
|
19
|
+
spec.add_dependency 'karafka-core', '>= 2.1.1', '< 3.0.0'
|
20
20
|
spec.add_dependency 'zeitwerk', '~> 2.3'
|
21
21
|
|
22
22
|
if $PROGRAM_NAME.end_with?('gem')
|
data.tar.gz.sig
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
#�}��6���ӝߕ�4
|
2
|
+
�
|
3
|
+
�01\������� .)dF��J�bvN,
|
4
|
+
��Y,�e�i�i�g�Q&��
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: waterdrop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.
|
4
|
+
version: 2.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Mensfeld
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
Qf04B9ceLUaC4fPVEz10FyobjaFoY4i32xRto3XnrzeAgfEe4swLq8bQsR3w/EF3
|
36
36
|
MGU0FeSV2Yj7Xc2x/7BzLK8xQn5l7Yy75iPF+KP3vVmDHnNl
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2023-06-
|
38
|
+
date: 2023-06-28 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: karafka-core
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 2.1.
|
46
|
+
version: 2.1.1
|
47
47
|
- - "<"
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: 3.0.0
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
requirements:
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: 2.1.
|
56
|
+
version: 2.1.1
|
57
57
|
- - "<"
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: 3.0.0
|
metadata.gz.sig
CHANGED
Binary file
|