karafka-rdkafka 0.24.0.rc3-aarch64-linux-gnu → 0.24.0.rc4-aarch64-linux-gnu

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: 0fc37d005a8920103966e128744f2afefb21867046b43777d31cb5c40bc995f1
4
- data.tar.gz: 44a57e87fb413e25815419909cdb2de0f138e4c6cd83e10ef3ee0495bb324f4c
3
+ metadata.gz: 67aea1d29ab7c9accce635b701dc80e09e2a07ee8208554c5a8be054aa85319d
4
+ data.tar.gz: ea2677a630149511b68987a5dd18f7908def22b7325540ae8e5b238d32e94ca4
5
5
  SHA512:
6
- metadata.gz: 52b918e97d0db2b47bcdc8adbe73c24df0a82fb0cf3854cff644735de31cc577b509c8fd10d19a29087e6a419feacf930cb73f680f081deeb612933e3e402d46
7
- data.tar.gz: bc22e5d641c2e3bdac08844e6899e7ba750ddb4b3c1a7345175b2678f24f9a31fe088ef04799968c091520311398e616ce2377856ad90887d628bbdf3c825e9b
6
+ metadata.gz: 72e001033ae77d321f97b1aa4d9bc15fa01bf99c1553b36f477f7d0c189fd8d89dd02866f9ce8989be1e3f7a4dca554af84543e5cbdc8d69cd2992220814defd
7
+ data.tar.gz: 690df2547a6bdafdd3716490181c78e6a1ff2b61f2008a62e0c9aa397560b7839d5740153ac850d23213e6c6d264ddbf75f1a6c24d8dfc059e1d79f6e6529a8b
data/CHANGELOG.md CHANGED
@@ -16,6 +16,8 @@
16
16
  - [Enhancement] Enable parallel compilation (`make -j$(nproc)`) for ARM64 Alpine musl builds (from upstream).
17
17
  - [Enhancement] Bump librdkafka to 2.13.0.
18
18
  - [Enhancement] Add non-blocking poll methods (`poll_nb`, `events_poll_nb`) that skip GVL release for efficient fiber scheduler integration when using `poll(0)` (from upstream).
19
+ - [Enhancement] Add `events_poll_nb_each` method on `Producer`, `Consumer`, and `Admin` for polling events in a single GVL/mutex session. Yields count after each iteration, caller returns `:stop` to break (from upstream).
20
+ - [Enhancement] Add `poll_nb_each` method on `Consumer` for non-blocking message polling with proper resource cleanup, yielding each message and supporting early termination via `:stop` return value (from upstream).
19
21
  - [Fix] Fix Kerberos build on Alpine 3.23+ (GCC 15/C23) by forcing C17 semantics to maintain compatibility with old-style K&R declarations in MIT Kerberos and Cyrus SASL dependencies.
20
22
 
21
23
  ## 0.23.1 (2025-11-14)
data/ext/librdkafka.so CHANGED
Binary file
data/lib/rdkafka/admin.rb CHANGED
@@ -91,6 +91,45 @@ module Rdkafka
91
91
  @native_kafka.enable_background_queue_io_events(fd, payload)
92
92
  end
93
93
 
94
+ # Polls for events in a non-blocking loop, yielding the count after each iteration.
95
+ #
96
+ # This method processes events (stats, errors, etc.) in a single GVL/mutex session,
97
+ # which is more efficient than repeated individual polls. It uses non-blocking polls
98
+ # internally (no GVL release between polls).
99
+ #
100
+ # Yields the count of events processed after each poll iteration, allowing the caller
101
+ # to implement timeout or other termination logic by returning `:stop`.
102
+ #
103
+ # @yield [count] Called after each poll iteration
104
+ # @yieldparam count [Integer] Number of events processed in this iteration
105
+ # @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
106
+ # @return [nil]
107
+ # @raise [Rdkafka::ClosedAdminError] if called on a closed admin client
108
+ #
109
+ # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
110
+ # Other admin operations will wait until this method returns.
111
+ # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
112
+ #
113
+ # @example Drain all pending events
114
+ # admin.events_poll_nb_each { |_count| }
115
+ #
116
+ # @example With timeout control
117
+ # deadline = monotonic_now + timeout_ms
118
+ # admin.events_poll_nb_each do |_count|
119
+ # :stop if monotonic_now >= deadline
120
+ # end
121
+ def events_poll_nb_each
122
+ closed_admin_check(__method__)
123
+
124
+ @native_kafka.with_inner do |inner|
125
+ loop do
126
+ count = Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0)
127
+ break if count.zero?
128
+ break if yield(count) == :stop
129
+ end
130
+ end
131
+ end
132
+
94
133
  # @return [Proc] finalizer proc for closing the admin
95
134
  # @private
96
135
  def finalizer
@@ -75,6 +75,103 @@ module Rdkafka
75
75
  @native_kafka.enable_background_queue_io_events(fd, payload)
76
76
  end
77
77
 
78
+ # Polls for events in a non-blocking loop, yielding the count after each iteration.
79
+ #
80
+ # This method processes events (stats, errors, etc.) in a single GVL/mutex session,
81
+ # which is more efficient than repeated individual polls. It uses non-blocking polls
82
+ # internally (no GVL release between polls).
83
+ #
84
+ # Yields the count of events processed after each poll iteration, allowing the caller
85
+ # to implement timeout or other termination logic by returning `:stop`.
86
+ #
87
+ # @yield [count] Called after each poll iteration
88
+ # @yieldparam count [Integer] Number of events processed in this iteration
89
+ # @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
90
+ # @return [nil]
91
+ # @raise [Rdkafka::ClosedConsumerError] if called on a closed consumer
92
+ #
93
+ # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
94
+ # Other consumer operations will wait until this method returns.
95
+ # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
96
+ # @note Do NOT use this if `consumer_poll_set` was set to `true`
97
+ #
98
+ # @example Drain all pending events
99
+ # consumer.events_poll_nb_each { |_count| }
100
+ #
101
+ # @example With timeout control
102
+ # deadline = monotonic_now + timeout_ms
103
+ # consumer.events_poll_nb_each do |_count|
104
+ # :stop if monotonic_now >= deadline
105
+ # end
106
+ def events_poll_nb_each
107
+ closed_consumer_check(__method__)
108
+
109
+ @native_kafka.with_inner do |inner|
110
+ loop do
111
+ count = Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0)
112
+ break if count.zero?
113
+ break if yield(count) == :stop
114
+ end
115
+ end
116
+ end
117
+
118
+ # Polls for messages in a non-blocking loop, yielding each message to the caller.
119
+ #
120
+ # This method processes messages in a single GVL/mutex session until the queue is empty
121
+ # or the caller returns `:stop`. It handles the message pointer lifecycle internally,
122
+ # ensuring proper cleanup via `rd_kafka_message_destroy`.
123
+ #
124
+ # @yield [message] Called for each message received
125
+ # @yieldparam message [Consumer::Message] The received message
126
+ # @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
127
+ # @return [nil]
128
+ # @raise [Rdkafka::ClosedConsumerError] if called on a closed consumer
129
+ # @raise [Rdkafka::RdkafkaError] if a Kafka error occurs while polling
130
+ #
131
+ # @note This method uses `rd_kafka_consumer_poll` to fetch messages, unlike
132
+ # `events_poll_nb_each` which uses `rd_kafka_poll` for event callbacks (delivery reports,
133
+ # statistics, etc.). For consumers, use this method to receive messages and
134
+ # `events_poll_nb_each` for processing background events.
135
+ # @note This method holds the inner lock for the duration. Other consumer operations
136
+ # will wait until this method returns.
137
+ # @note Timeout/max_messages logic should be implemented by the caller
138
+ #
139
+ # @example Process messages until queue is empty
140
+ # consumer.poll_nb_each do |message|
141
+ # process(message)
142
+ # end
143
+ #
144
+ # @example Process with early termination
145
+ # count = 0
146
+ # consumer.poll_nb_each do |message|
147
+ # process(message)
148
+ # count += 1
149
+ # :stop if count >= 10
150
+ # end
151
+ def poll_nb_each
152
+ closed_consumer_check(__method__)
153
+
154
+ @native_kafka.with_inner do |inner|
155
+ loop do
156
+ message_ptr = Rdkafka::Bindings.rd_kafka_consumer_poll_nb(inner, 0)
157
+ break if message_ptr.null?
158
+
159
+ begin
160
+ native_message = Rdkafka::Bindings::Message.new(message_ptr)
161
+
162
+ if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
163
+ raise Rdkafka::RdkafkaError.new(native_message[:err])
164
+ end
165
+
166
+ result = yield Consumer::Message.new(native_message)
167
+ break if result == :stop
168
+ ensure
169
+ Rdkafka::Bindings.rd_kafka_message_destroy(message_ptr)
170
+ end
171
+ end
172
+ end
173
+ end
174
+
78
175
  # @return [Proc] finalizer proc for closing the consumer
79
176
  # @private
80
177
  def finalizer
@@ -338,41 +338,41 @@ module Rdkafka
338
338
 
339
339
  alias_method :queue_length, :queue_size
340
340
 
341
- # Drains the producer's event queue by continuously polling until empty or time limit reached.
341
+ # Polls for events in a non-blocking loop, yielding the count after each iteration.
342
342
  #
343
- # This method is useful when you need to ensure delivery callbacks are processed within a
344
- # bounded time, particularly when polling multiple producers from a single thread where
345
- # fair scheduling is required to prevent starvation.
343
+ # This method processes delivery callbacks in a single GVL/mutex session, which is more
344
+ # efficient than repeated individual polls. It uses non-blocking polls internally
345
+ # (no GVL release between polls).
346
346
  #
347
- # Uses non-blocking polls internally (no GVL release) for efficiency. The method holds
348
- # a single `with_inner` lock for the duration, minimizing per-poll overhead when processing
349
- # many events.
347
+ # Yields the count of events processed after each poll iteration, allowing the caller
348
+ # to implement timeout or other termination logic by returning `:stop`.
350
349
  #
351
- # @param timeout_ms [Integer] maximum time to spend draining in milliseconds (default: 100)
352
- # @return [Boolean] true if no more events to process, false if stopped due to time limit
350
+ # @yield [count] Called after each poll iteration
351
+ # @yieldparam count [Integer] Number of events processed in this iteration
352
+ # @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
353
+ # @return [nil]
353
354
  # @raise [Rdkafka::ClosedProducerError] if called on a closed producer
354
355
  #
355
- # @note This method holds the inner lock for up to `timeout_ms`. Other producer operations
356
- # (produce, close, etc.) will wait until this method returns.
356
+ # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
357
+ # Other producer operations (produce, close, etc.) will wait until this method returns.
357
358
  # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
358
359
  #
359
- # @example Basic usage - drain for up to 100ms
360
- # fully_drained = producer.poll_drain_nb
360
+ # @example Drain all pending callbacks
361
+ # producer.events_poll_nb_each { |_count| }
361
362
  #
362
- # @example Round-robin polling multiple producers fairly
363
- # producers.each do |producer|
364
- # fully_drained = producer.poll_drain_nb(10)
365
- # # If false, this producer has more pending events
363
+ # @example With timeout control
364
+ # deadline = monotonic_now + timeout_ms
365
+ # producer.events_poll_nb_each do |_count|
366
+ # :stop if monotonic_now >= deadline
366
367
  # end
367
- def poll_drain_nb(timeout_ms = 100)
368
+ def events_poll_nb_each
368
369
  closed_producer_check(__method__)
369
370
 
370
371
  @native_kafka.with_inner do |inner|
371
- deadline = monotonic_now_ms + timeout_ms
372
-
373
372
  loop do
374
- break true if Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0).zero?
375
- break false if monotonic_now_ms >= deadline
373
+ count = Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0)
374
+ break if count.zero?
375
+ break if yield(count) == :stop
376
376
  end
377
377
  end
378
378
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  # Current rdkafka-ruby gem version
5
- VERSION = "0.24.0.rc3"
5
+ VERSION = "0.24.0.rc4"
6
6
  # Target librdkafka version to be used
7
7
  LIBRDKAFKA_VERSION = "2.13.0"
8
8
  # SHA256 hash of the librdkafka source tarball for verification
data/renovate.json CHANGED
@@ -5,6 +5,7 @@
5
5
  ],
6
6
  "minimumReleaseAge": "7 days",
7
7
  "includePaths": [
8
+ ".ruby-version",
8
9
  "Gemfile",
9
10
  "Gemfile.lint",
10
11
  "package.json",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: karafka-rdkafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.0.rc3
4
+ version: 0.24.0.rc4
5
5
  platform: aarch64-linux-gnu
6
6
  authors:
7
7
  - Thijs Cadier