karafka-rdkafka 0.27.1 → 0.27.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: '081094b1f78c17abf2aced07df01ee8a5c4c60bb5c7e6246de14390369c9cdfc'
4
- data.tar.gz: 93dafa8264ebbe6879e1aa4fe3a0c90971fd2bcabf02f5a25e6401f58af3d052
3
+ metadata.gz: 28b25d5553da8103cf3ba2840c57d954bc36a957004a01e31a7a4ace76b82382
4
+ data.tar.gz: ee834fb05a4afa6ac3bb31d2dcf8735779f6bcd9c7e4b910d95e22ecae74b3fc
5
5
  SHA512:
6
- metadata.gz: fd3764348be10ce1b4ce8972f71289221f1af06f281eefd6fcb00184d2aae9c28b955551eef16201f85d7a5d82c84f04284e34fc62ec99d1dc0a93a3730c37e5
7
- data.tar.gz: 83dfc87c29cc503766bbc61d7a345670cfee39c9c1c7d73b9964d0f63b6ddf6a2b224810211b8d221b6cfc0b58a10925b6b938fb7afcb640ad0859966194b7bf
6
+ metadata.gz: d4fe487cab97e1cf1ea5c275a682feee20247d1e20517d257c1a03383d5fb9bcb926404626123e3d0c7e05d9832fa7675c37b0b5f6b0ff484c277324a432c66f
7
+ data.tar.gz: 223c61df2cb43ad07df271caf29c535e8daa13f49602a21cfea5ef8ddb030e6378f23fe698f15025a673083fd486b749c04f3078edb6f69d14fa0339cd55658f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Rdkafka Changelog
2
2
 
3
+ ## 0.27.2 (2026-05-21)
4
+ - [Enhancement] `poll_batch` and `poll_batch_nb` now return error events inline as `RdkafkaError` objects rather than raising on the first error. The return type is `Array<Message, RdkafkaError>` and callers are responsible for handling errors in the result.
5
+
3
6
  ## 0.27.1 (2026-05-14)
4
7
  - [Fix] `poll_nb`, `poll_nb_each`, `poll_batch`, and `poll_batch_nb` now raise `RdkafkaError` with `details` populated (`{topic:, partition:, offset:}`) when a message contains an error (e.g. `:partition_eof`). Previously these methods raised via `RdkafkaError.new(code)`, discarding the native message struct context. They now use `RdkafkaError.validate!(native_message, client_ptr: inner)`, consistent with `poll`.
5
8
 
@@ -801,16 +801,21 @@ module Rdkafka
801
801
  # is available, librdkafka fills the buffer with whatever is immediately ready and
802
802
  # returns without further waiting.
803
803
  #
804
+ # Error events (e.g. `:partition_eof`) are returned inline as {RdkafkaError} objects
805
+ # rather than raised, so callers receive the complete batch — both messages and errors —
806
+ # and can decide how to handle each. This is particularly useful when multiple partitions
807
+ # signal EOF simultaneously: all signals appear in the returned array rather than only
808
+ # the first one being raised and the rest silently discarded.
809
+ #
804
810
  # @param timeout_ms [Integer] Timeout waiting for the first message (-1 for infinite)
805
811
  # @param max_items [Integer] Maximum number of messages to return per call
806
- # @return [Array<Message>] Array of messages (empty if none available within timeout)
807
- # @raise [RdkafkaError] When a consumed message contains an error
812
+ # @return [Array<Message, RdkafkaError>] Batch of messages and/or error events in arrival order
808
813
  # @raise [ClosedConsumerError] When called on a closed consumer
809
814
  def poll_batch(timeout_ms, max_items: 100)
810
815
  closed_consumer_check(__method__)
811
816
 
812
817
  buffer = batch_buffer(max_items)
813
- messages = []
818
+ results = []
814
819
 
815
820
  count = @native_kafka.with_inner do |_inner|
816
821
  Rdkafka::Bindings.rd_kafka_consume_batch_queue(
@@ -821,7 +826,7 @@ module Rdkafka
821
826
  )
822
827
  end
823
828
 
824
- return messages if count <= 0
829
+ return results if count <= 0
825
830
 
826
831
  i = 0
827
832
  begin
@@ -836,12 +841,13 @@ module Rdkafka
836
841
  native_message = Rdkafka::Bindings::Message.new(ptr)
837
842
 
838
843
  if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
839
- @native_kafka.with_inner do |inner|
840
- Rdkafka::RdkafkaError.validate!(native_message, client_ptr: inner)
841
- end
844
+ results << build_batch_error(native_message)
845
+ Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
846
+ i += 1
847
+ next
842
848
  end
843
849
 
844
- messages << Rdkafka::Consumer::Message.new(native_message)
850
+ results << Rdkafka::Consumer::Message.new(native_message)
845
851
  Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
846
852
  i += 1
847
853
  end
@@ -853,7 +859,7 @@ module Rdkafka
853
859
  end
854
860
  end
855
861
 
856
- messages
862
+ results
857
863
  end
858
864
 
859
865
  # Poll for a batch of messages without releasing the GVL (Global VM Lock).
@@ -865,16 +871,17 @@ module Rdkafka
865
871
  # @note Since the GVL is not released, a non-zero timeout_ms will block all Ruby
866
872
  # threads/fibers for the duration. Use {#poll_batch} if you need a blocking wait.
867
873
  #
874
+ # Error events are returned inline as {RdkafkaError} objects; see {#poll_batch} for details.
875
+ #
868
876
  # @param timeout_ms [Integer] Timeout waiting for the first message (default: 0 for non-blocking)
869
877
  # @param max_items [Integer] Maximum number of messages to return per call
870
- # @return [Array<Message>] Array of messages (empty if none available within timeout)
871
- # @raise [RdkafkaError] When a consumed message contains an error
878
+ # @return [Array<Message, RdkafkaError>] Batch of messages and/or error events in arrival order
872
879
  # @raise [ClosedConsumerError] When called on a closed consumer
873
880
  def poll_batch_nb(timeout_ms = 0, max_items: 100)
874
881
  closed_consumer_check(__method__)
875
882
 
876
883
  buffer = batch_buffer(max_items)
877
- messages = []
884
+ results = []
878
885
 
879
886
  count = @native_kafka.with_inner do |_inner|
880
887
  Rdkafka::Bindings.rd_kafka_consume_batch_queue_nb(
@@ -885,7 +892,7 @@ module Rdkafka
885
892
  )
886
893
  end
887
894
 
888
- return messages if count <= 0
895
+ return results if count <= 0
889
896
 
890
897
  i = 0
891
898
  begin
@@ -900,12 +907,13 @@ module Rdkafka
900
907
  native_message = Rdkafka::Bindings::Message.new(ptr)
901
908
 
902
909
  if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
903
- @native_kafka.with_inner do |inner|
904
- Rdkafka::RdkafkaError.validate!(native_message, client_ptr: inner)
905
- end
910
+ results << build_batch_error(native_message)
911
+ Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
912
+ i += 1
913
+ next
906
914
  end
907
915
 
908
- messages << Rdkafka::Consumer::Message.new(native_message)
916
+ results << Rdkafka::Consumer::Message.new(native_message)
909
917
  Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
910
918
  i += 1
911
919
  end
@@ -917,7 +925,7 @@ module Rdkafka
917
925
  end
918
926
  end
919
927
 
920
- messages
928
+ results
921
929
  end
922
930
 
923
931
  # Poll for new messages and yield for each received one. Iteration
@@ -1001,6 +1009,21 @@ module Rdkafka
1001
1009
  end
1002
1010
  end
1003
1011
 
1012
+ # Builds an RdkafkaError from a native message, promoting to a fatal error when
1013
+ # librdkafka flagged a fatal condition on the underlying client handle.
1014
+ # @param native_message [Rdkafka::Bindings::Message] the errored native message
1015
+ # @return [RdkafkaError]
1016
+ def build_batch_error(native_message)
1017
+ err = Rdkafka::RdkafkaError.build(native_message)
1018
+ if err && err.rdkafka_response == Rdkafka::Bindings::RD_KAFKA_RESP_ERR__FATAL
1019
+ @native_kafka.with_inner do |inner|
1020
+ Rdkafka::RdkafkaError.build_fatal(inner, fallback_error_code: err.rdkafka_response)
1021
+ end
1022
+ else
1023
+ err
1024
+ end
1025
+ end
1026
+
1004
1027
  # Returns a reusable FFI buffer for batch polling, growing if needed
1005
1028
  # @param max_items [Integer] minimum buffer capacity
1006
1029
  # @return [FFI::MemoryPointer] pointer buffer
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  # Current rdkafka-ruby gem version
5
- VERSION = "0.27.1"
5
+ VERSION = "0.27.2"
6
6
  # Target librdkafka version to be used
7
7
  LIBRDKAFKA_VERSION = "2.14.1"
8
8
  # SHA256 hash of the librdkafka source tarball for verification
data/package-lock.json CHANGED
@@ -286,9 +286,9 @@
286
286
  }
287
287
  },
288
288
  "node_modules/smol-toml": {
289
- "version": "1.6.0",
290
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz",
291
- "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==",
289
+ "version": "1.6.1",
290
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
291
+ "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==",
292
292
  "dev": true,
293
293
  "license": "BSD-3-Clause",
294
294
  "engines": {
@@ -312,9 +312,9 @@
312
312
  }
313
313
  },
314
314
  "node_modules/yaml": {
315
- "version": "2.8.2",
316
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
317
- "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
315
+ "version": "2.8.4",
316
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
317
+ "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
318
318
  "dev": true,
319
319
  "license": "ISC",
320
320
  "bin": {
data/renovate.json CHANGED
@@ -85,7 +85,8 @@
85
85
  "ruby/setup-ruby",
86
86
  "ruby"
87
87
  ],
88
- "groupName": "ruby setup"
88
+ "groupName": "ruby setup",
89
+ "internalChecksFilter": "strict"
89
90
  }
90
91
  ],
91
92
  "labels": [
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.27.1
4
+ version: 0.27.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thijs Cadier
@@ -176,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
176
  - !ruby/object:Gem::Version
177
177
  version: '0'
178
178
  requirements: []
179
- rubygems_version: 4.0.6
179
+ rubygems_version: 4.0.10
180
180
  specification_version: 4
181
181
  summary: The rdkafka gem is a modern Kafka client library for Ruby based on librdkafka.
182
182
  It wraps the production-ready C client using the ffi gem and targets Kafka 1.0+