karafka-rdkafka 0.28.0-aarch64-linux-gnu → 0.28.2-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.
@@ -35,11 +35,13 @@ module Rdkafka
35
35
  # consumer-queue reference, then destroy the native client. The default `NativeKafka#finalizer`
36
36
  # went straight to `rd_kafka_destroy`, leaving the consumer-queue reference (from
37
37
  # `rd_kafka_queue_get_consumer`, taken by `poll_batch`) dangling - which can make
38
- # `rd_kafka_destroy` block inside the finalizer (process hang at GC/shutdown) or leak the handle.
38
+ # `rd_kafka_destroy` block inside the finalizer (process hang at GC/shutdown) or leak the
39
+ # handle.
39
40
  #
40
41
  # @private
41
42
  # @param native_kafka [NativeKafka] the wrapped native client
42
- # @param queue_holder [Array] single-element holder carrying the consumer queue pointer (or empty)
43
+ # @param queue_holder [Array] single-element holder carrying the consumer queue pointer
44
+ # (or empty)
43
45
  # @return [Proc] finalizer proc that must not reference the consumer instance
44
46
  def self.finalizer(native_kafka, queue_holder)
45
47
  proc do
@@ -125,11 +127,6 @@ module Rdkafka
125
127
  # @return [nil]
126
128
  # @raise [Rdkafka::ClosedConsumerError] if called on a closed consumer
127
129
  #
128
- # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
129
- # Other consumer operations will wait until this method returns.
130
- # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
131
- # @note Do NOT use this if `consumer_poll_set` was set to `true`
132
- #
133
130
  # @example Drain all pending events
134
131
  # consumer.events_poll_nb_each { |_count| }
135
132
  #
@@ -138,6 +135,10 @@ module Rdkafka
138
135
  # consumer.events_poll_nb_each do |_count|
139
136
  # :stop if monotonic_now >= deadline
140
137
  # end
138
+ # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
139
+ # Other consumer operations will wait until this method returns.
140
+ # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
141
+ # @note Do NOT use this if `consumer_poll_set` was set to `true`
141
142
  def events_poll_nb_each
142
143
  closed_consumer_check(__method__)
143
144
 
@@ -163,14 +164,6 @@ module Rdkafka
163
164
  # @raise [Rdkafka::ClosedConsumerError] if called on a closed consumer
164
165
  # @raise [Rdkafka::RdkafkaError] if a Kafka error occurs while polling
165
166
  #
166
- # @note This method uses `rd_kafka_consumer_poll` to fetch messages, unlike
167
- # `events_poll_nb_each` which uses `rd_kafka_poll` for event callbacks (delivery reports,
168
- # statistics, etc.). For consumers, use this method to receive messages and
169
- # `events_poll_nb_each` for processing background events.
170
- # @note This method holds the inner lock for the duration. Other consumer operations
171
- # will wait until this method returns.
172
- # @note Timeout/max_messages logic should be implemented by the caller
173
- #
174
167
  # @example Process messages until queue is empty
175
168
  # consumer.poll_nb_each do |message|
176
169
  # process(message)
@@ -183,6 +176,13 @@ module Rdkafka
183
176
  # count += 1
184
177
  # :stop if count >= 10
185
178
  # end
179
+ # @note This method uses `rd_kafka_consumer_poll` to fetch messages, unlike
180
+ # `events_poll_nb_each` which uses `rd_kafka_poll` for event callbacks (delivery reports,
181
+ # statistics, etc.). For consumers, use this method to receive messages and
182
+ # `events_poll_nb_each` for processing background events.
183
+ # @note This method holds the inner lock for the duration. Other consumer operations
184
+ # will wait until this method returns.
185
+ # @note Timeout/max_messages logic should be implemented by the caller
186
186
  def poll_nb_each
187
187
  closed_consumer_check(__method__)
188
188
 
@@ -437,9 +437,11 @@ module Rdkafka
437
437
  end
438
438
 
439
439
  # Return the current positions (offsets) for topics and partitions.
440
- # The offset field of each requested partition will be set to the offset of the last consumed message + 1, or nil in case there was no previous message.
440
+ # The offset field of each requested partition will be set to the offset of the last consumed
441
+ # message + 1, or nil in case there was no previous message.
441
442
  #
442
- # @param list [TopicPartitionList, nil] The topic with partitions to get the offsets for or nil to use the current subscription.
443
+ # @param list [TopicPartitionList, nil] The topic with partitions to get the offsets for or nil
444
+ # to use the current subscription.
443
445
  #
444
446
  # @return [TopicPartitionList]
445
447
  #
@@ -592,7 +594,7 @@ module Rdkafka
592
594
  # When using this `enable.auto.offset.store` should be set to `false` in the config.
593
595
  #
594
596
  # @param message [Rdkafka::Consumer::Message] The message which offset will be stored
595
- # @param metadata [String, nil] commit metadata string or nil if none
597
+ # @param metadata [String, nil] commit metadata string to store alongside the offset
596
598
  # @return [nil]
597
599
  # @raise [RdkafkaError] When storing the offset fails
598
600
  def store_offset(message, metadata = nil)
@@ -646,9 +648,8 @@ module Rdkafka
646
648
  seek_by(message.topic, message.partition, message.offset)
647
649
  end
648
650
 
649
- # Seek to a particular message by providing the topic, partition and offset.
650
- # The next poll on the topic/partition will return the
651
- # message at the given offset.
651
+ # Seek to a particular message by providing the topic, partition and offset. The next poll on
652
+ # the topic/partition will return the message at the given offset.
652
653
  #
653
654
  # @param topic [String] The topic in which to seek
654
655
  # @param partition [Integer] The partition number to seek
@@ -875,7 +876,7 @@ module Rdkafka
875
876
  # returns without further waiting.
876
877
  #
877
878
  # Error events (e.g. `:partition_eof`) are returned inline as {RdkafkaError} objects
878
- # rather than raised, so callers receive the complete batch — both messages and errors —
879
+ # rather than raised, so callers receive the complete batch - both messages and errors -
879
880
  # and can decide how to handle each. This is particularly useful when multiple partitions
880
881
  # signal EOF simultaneously: all signals appear in the returned array rather than only
881
882
  # the first one being raised and the rest silently discarded.
@@ -905,33 +906,35 @@ module Rdkafka
905
906
  begin
906
907
  while i < count
907
908
  ptr = buffer.get_pointer(i * FFI::Pointer.size)
909
+ # Take ownership of this index before processing the pointer: advancing `i` up front means
910
+ # the cleanup loop in the `ensure` below starts past it, so a raise mid-iteration cannot
911
+ # double-free the same message.
912
+ i += 1
908
913
 
909
- if ptr.null?
910
- i += 1
911
- next
912
- end
914
+ next if ptr.null?
913
915
 
914
- native_message = Rdkafka::Bindings::Message.new(ptr)
916
+ # One `ensure` around the whole body guarantees `ptr` is destroyed exactly once on every
917
+ # path - the error branch, a successful build, a rescued `RdkafkaError`, or any other
918
+ # exception unwinding through here - so nothing leaks in the window before the build.
919
+ begin
920
+ native_message = Rdkafka::Bindings::Message.new(ptr)
915
921
 
916
- if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
917
- results << build_batch_error(native_message)
918
- Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
919
- i += 1
920
- next
921
- end
922
+ if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
923
+ results << build_batch_error(native_message)
924
+ next
925
+ end
922
926
 
923
- begin
924
- results << Rdkafka::Consumer::Message.new(native_message)
925
- rescue Rdkafka::RdkafkaError => e
926
- # A message that fails to build (e.g. a header read error) is surfaced inline as an
927
- # error event rather than discarding the whole batch - including the messages already
928
- # built - and raising, which silently lost them once their offsets had been stored.
929
- results << e
927
+ begin
928
+ results << Rdkafka::Consumer::Message.new(native_message)
929
+ rescue Rdkafka::RdkafkaError => e
930
+ # A message that fails to build (e.g. a header read error) is surfaced inline as an
931
+ # error event rather than discarding the whole batch - including the messages already
932
+ # built - and raising, which silently lost them once their offsets had been stored.
933
+ results << e
934
+ end
930
935
  ensure
931
936
  Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
932
937
  end
933
-
934
- i += 1
935
938
  end
936
939
  ensure
937
940
  while i < count
@@ -950,15 +953,15 @@ module Rdkafka
950
953
  # particularly useful in fiber scheduler contexts where GVL release/reacquire
951
954
  # overhead is wasteful since we don't expect to wait.
952
955
  #
956
+ # @param timeout_ms [Integer] Timeout waiting for the first message
957
+ # (default: 0 for non-blocking)
958
+ # @param max_items [Integer] Maximum number of messages to return per call
959
+ # @return [Array<Message, RdkafkaError>] Batch of messages and/or error events in arrival order
960
+ # @raise [ClosedConsumerError] When called on a closed consumer
953
961
  # @note Since the GVL is not released, a non-zero timeout_ms will block all Ruby
954
962
  # threads/fibers for the duration. Use {#poll_batch} if you need a blocking wait.
955
963
  #
956
964
  # Error events are returned inline as {RdkafkaError} objects; see {#poll_batch} for details.
957
- #
958
- # @param timeout_ms [Integer] Timeout waiting for the first message (default: 0 for non-blocking)
959
- # @param max_items [Integer] Maximum number of messages to return per call
960
- # @return [Array<Message, RdkafkaError>] Batch of messages and/or error events in arrival order
961
- # @raise [ClosedConsumerError] When called on a closed consumer
962
965
  def poll_batch_nb(timeout_ms = 0, max_items: 100)
963
966
  closed_consumer_check(__method__)
964
967
 
@@ -980,33 +983,35 @@ module Rdkafka
980
983
  begin
981
984
  while i < count
982
985
  ptr = buffer.get_pointer(i * FFI::Pointer.size)
986
+ # Take ownership of this index before processing the pointer: advancing `i` up front means
987
+ # the cleanup loop in the `ensure` below starts past it, so a raise mid-iteration cannot
988
+ # double-free the same message.
989
+ i += 1
983
990
 
984
- if ptr.null?
985
- i += 1
986
- next
987
- end
991
+ next if ptr.null?
988
992
 
989
- native_message = Rdkafka::Bindings::Message.new(ptr)
993
+ # One `ensure` around the whole body guarantees `ptr` is destroyed exactly once on every
994
+ # path - the error branch, a successful build, a rescued `RdkafkaError`, or any other
995
+ # exception unwinding through here - so nothing leaks in the window before the build.
996
+ begin
997
+ native_message = Rdkafka::Bindings::Message.new(ptr)
990
998
 
991
- if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
992
- results << build_batch_error(native_message)
993
- Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
994
- i += 1
995
- next
996
- end
999
+ if native_message[:err] != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
1000
+ results << build_batch_error(native_message)
1001
+ next
1002
+ end
997
1003
 
998
- begin
999
- results << Rdkafka::Consumer::Message.new(native_message)
1000
- rescue Rdkafka::RdkafkaError => e
1001
- # A message that fails to build (e.g. a header read error) is surfaced inline as an
1002
- # error event rather than discarding the whole batch - including the messages already
1003
- # built - and raising, which silently lost them once their offsets had been stored.
1004
- results << e
1004
+ begin
1005
+ results << Rdkafka::Consumer::Message.new(native_message)
1006
+ rescue Rdkafka::RdkafkaError => e
1007
+ # A message that fails to build (e.g. a header read error) is surfaced inline as an
1008
+ # error event rather than discarding the whole batch - including the messages already
1009
+ # built - and raising, which silently lost them once their offsets had been stored.
1010
+ results << e
1011
+ end
1005
1012
  ensure
1006
1013
  Rdkafka::Bindings.rd_kafka_message_destroy(ptr)
1007
1014
  end
1008
-
1009
- i += 1
1010
1015
  end
1011
1016
  ensure
1012
1017
  while i < count
@@ -1085,7 +1090,15 @@ module Rdkafka
1085
1090
 
1086
1091
  private
1087
1092
 
1088
- # Copies a librdkafka-allocated C string into a Ruby string and frees the native buffer.
1093
+ # Checks if the consumer is closed and raises an error if so
1094
+ # @param method [Symbol] name of the calling method for error context
1095
+ # @raise [ClosedConsumerError] when the consumer is closed
1096
+ def closed_consumer_check(method)
1097
+ raise Rdkafka::ClosedConsumerError.new(method) if closed?
1098
+ end
1099
+ alias_method :closed_check, :closed_consumer_check
1100
+
1101
+ # Reads a librdkafka-allocated string and frees the underlying native buffer.
1089
1102
  #
1090
1103
  # `rd_kafka_memberid`/`rd_kafka_clusterid` return a string the caller owns and must release
1091
1104
  # with `rd_kafka_mem_free`; without this the buffer leaks on every call.
@@ -1101,14 +1114,6 @@ module Rdkafka
1101
1114
  Rdkafka::Bindings.rd_kafka_mem_free(inner, ptr) unless ptr.null?
1102
1115
  end
1103
1116
 
1104
- # Checks if the consumer is closed and raises an error if so
1105
- # @param method [Symbol] name of the calling method for error context
1106
- # @raise [ClosedConsumerError] when the consumer is closed
1107
- def closed_consumer_check(method)
1108
- raise Rdkafka::ClosedConsumerError.new(method) if closed?
1109
- end
1110
- alias_method :closed_check, :closed_consumer_check
1111
-
1112
1117
  # Reads this consumer's effective `isolation.level` from the live librdkafka configuration
1113
1118
  # and maps it to the numeric isolation level constant. Memoized: the value cannot change
1114
1119
  # after client creation.
@@ -3,8 +3,17 @@
3
3
  module Rdkafka
4
4
  # Provides default timeout and configuration values used throughout the library.
5
5
  #
6
- # These constants standardize timing values across consumers, producers, and admin clients.
7
- # Values are specified in milliseconds (ms) unless otherwise noted.
6
+ # All timeout values can be overridden per-call via method parameters. These constants provide
7
+ # a central place to understand and reference the default values used across the library.
8
+ #
9
+ # @example Overriding a timeout per-call
10
+ # consumer.committed(timeout_ms: 5_000) # Use 5 seconds instead of default 2 seconds
11
+ #
12
+ # @example Checking the default value
13
+ # Rdkafka::Defaults::CONSUMER_COMMITTED_TIMEOUT_MS # => 2000
14
+ # @note These are rdkafka-ruby defaults, not librdkafka configuration options.
15
+ # For librdkafka options, see:
16
+ # https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md
8
17
  module Defaults
9
18
  # Consumer timeout for fetching committed offsets
10
19
  # @see Consumer#committed
data/lib/rdkafka/error.rb CHANGED
@@ -139,7 +139,8 @@ module Rdkafka
139
139
  # Calls rd_kafka_fatal_error() to get the actual underlying error code and description.
140
140
  #
141
141
  # @param client_ptr [FFI::Pointer] Pointer to rd_kafka_t client
142
- # @param fallback_error_code [Integer] Error code to use if no fatal error found (default: -150)
142
+ # @param fallback_error_code [Integer] Error code to use if no fatal error found
143
+ # (default: -150)
143
144
  # @param fallback_message [String, nil] Message to use if no fatal error found
144
145
  # @param instance_name [String, nil] Optional name of the rdkafka instance
145
146
  # @return [RdkafkaError] Error object with fatal flag set to true
@@ -4,10 +4,14 @@ module Rdkafka
4
4
  module OAuth
5
5
  # Set the OAuthBearer token
6
6
  #
7
- # @param token [String] the mandatory token value to set, often (but not necessarily) a JWS compact serialization as per https://tools.ietf.org/html/rfc7515#section-3.1.
8
- # @param lifetime_ms [Integer] when the token expires, in terms of the number of milliseconds since the epoch. See https://currentmillis.com/.
7
+ # @param token [String] the mandatory token value to set, often (but not necessarily) a JWS
8
+ # compact serialization as per https://tools.ietf.org/html/rfc7515#section-3.1.
9
+ # @param lifetime_ms [Integer] when the token expires, in terms of the number of milliseconds
10
+ # since the epoch. See https://currentmillis.com/.
9
11
  # @param principal_name [String] the mandatory Kafka principal name associated with the token.
10
- # @param extensions [Hash] optional SASL extensions key-value pairs to be communicated to the broker as additional key-value pairs during the initial client response as per https://tools.ietf.org/html/rfc7628#section-3.1.
12
+ # @param extensions [Hash] optional SASL extensions key-value pairs to be communicated to the
13
+ # broker as additional key-value pairs during the initial client response as per
14
+ # https://tools.ietf.org/html/rfc7628#section-3.1.
11
15
  # @return [Integer] 0 on success
12
16
  def oauthbearer_set_token(token:, lifetime_ms:, principal_name:, extensions: nil)
13
17
  error_buffer = FFI::MemoryPointer.from_string(" " * 256)
@@ -49,7 +53,8 @@ module Rdkafka
49
53
  # Convert extensions hash to FFI::MemoryPointer (`const char **`).
50
54
  #
51
55
  # @param extensions [Hash, nil] extension key-value pairs
52
- # @return [Array<FFI::MemoryPointer, Array<FFI::MemoryPointer>>] array pointer and string pointers
56
+ # @return [Array<FFI::MemoryPointer, Array<FFI::MemoryPointer>>] array pointer and string
57
+ # pointers
53
58
  # @note The returned pointers must be freed manually (autorelease = false).
54
59
  def map_extensions(extensions)
55
60
  return [nil, nil] if extensions.nil? || extensions.empty?
@@ -80,7 +85,7 @@ module Rdkafka
80
85
  #
81
86
  # @param extensions [Hash, nil] extension key-value pairs
82
87
  # @return [Integer] non-negative even number representing keys + values count
83
- # @see https://github.com/confluentinc/librdkafka/blob/master/src/rdkafka_sasl_oauthbearer.c#L327-L347
88
+ # @see github.com/confluentinc/librdkafka/blob/master/src/rdkafka_sasl_oauthbearer.c#L327-L347
84
89
  def extension_size(extensions)
85
90
  return 0 unless extensions
86
91
  extensions.size * 2
@@ -13,6 +13,14 @@ module Rdkafka
13
13
  def initialize(inner, run_polling_thread:, opaque:, auto_start: true, timeout_ms: Defaults::NATIVE_KAFKA_POLL_TIMEOUT_MS)
14
14
  @inner = inner
15
15
  @opaque = opaque
16
+ # Process that owns `@inner`. librdkafka is not fork-safe: `fork` copies only the calling
17
+ # thread, so the background/broker threads backing this handle do not exist in a child
18
+ # process. An inherited handle therefore must not be polled or destroyed in the child -
19
+ # `rd_kafka_destroy` would walk thread state that no longer exists (segfault) and the
20
+ # inherited mutexes may have been copied in a locked state (deadlock). We record the creator
21
+ # pid so a forked child can recognise an inherited handle and leave its teardown to the
22
+ # parent, which still owns the running threads.
23
+ @creator_pid = Process.pid
16
24
  # Lock around external access
17
25
  @access_mutex = Mutex.new
18
26
  # Lock around internal polling
@@ -116,17 +124,21 @@ module Rdkafka
116
124
  end
117
125
 
118
126
  # Returns whether this native Kafka handle is closed or closing
127
+ #
128
+ # A handle inherited across `fork` is reported as closed in the child: it belongs to another
129
+ # process whose threads back the native client, so it is not usable here and must not be
130
+ # destroyed here (see the `@creator_pid` note in `#initialize`). This makes every `#close`
131
+ # path - including the GC finalizers that run during a child's exit - skip the native teardown
132
+ # for inherited handles, which is what would otherwise segfault the child.
133
+ #
119
134
  # @return [Boolean] true if closed or closing
120
135
  def closed?
121
- @closing || @inner.nil?
136
+ @closing || @inner.nil? || @creator_pid != Process.pid
122
137
  end
123
138
 
124
139
  # Enable IO event notifications on the main queue
125
140
  # Librdkafka will write to your FD when the queue transitions from empty to non-empty
126
141
  #
127
- # @note This method is incompatible with background polling threads.
128
- # If background polling is enabled, use manual polling instead (e.g., consumer.poll)
129
- #
130
142
  # @param fd [Integer] your file descriptor (from IO.pipe or eventfd)
131
143
  # @param payload [String] data to write to fd when queue has data (default: "\x01")
132
144
  # @return [nil]
@@ -143,6 +155,8 @@ module Rdkafka
143
155
  # if readable
144
156
  # consumer.poll(0) # Get messages
145
157
  # end
158
+ # @note This method is incompatible with background polling threads.
159
+ # If background polling is enabled, use manual polling instead (e.g., consumer.poll)
146
160
  def enable_main_queue_io_events(fd, payload = "\x01")
147
161
  if @run_polling_thread
148
162
  raise "Cannot enable IO events while background polling thread is active. " \
@@ -160,14 +174,13 @@ module Rdkafka
160
174
  # Enable IO event notifications on the background queue
161
175
  # Librdkafka will write to your FD when the background queue transitions from empty to non-empty
162
176
  #
163
- # @note This method is incompatible with background polling threads.
164
- # If background polling is enabled, use manual polling instead (e.g., consumer.poll)
165
- #
166
177
  # @param fd [Integer] your file descriptor (from IO.pipe or eventfd)
167
178
  # @param payload [String] data to write to fd when queue has data (default: "\x01")
168
179
  # @return [nil]
169
180
  # @raise [ClosedInnerError] when the handle is closed
170
181
  # @raise [RuntimeError] when background polling thread is active
182
+ # @note This method is incompatible with background polling threads.
183
+ # If background polling is enabled, use manual polling instead (e.g., consumer.poll)
171
184
  def enable_background_queue_io_events(fd, payload = "\x01")
172
185
  if @run_polling_thread
173
186
  raise "Cannot enable IO events while background polling thread is active. " \
@@ -2,8 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Producer
5
- # Handle to wait for a delivery report which is returned when
6
- # producing a message.
5
+ # Handle to wait for a delivery report which is returned when producing a message.
7
6
  class DeliveryHandle < Rdkafka::AbstractHandle
8
7
  layout :pending, :bool,
9
8
  :response, :int,
@@ -36,7 +36,8 @@ module Rdkafka
36
36
  # Checks if a fatal error has occurred and retrieves error details.
37
37
  # Calls rd_kafka_fatal_error to get the actual fatal error code and message.
38
38
  #
39
- # @return [Hash, nil] Hash with :error_code and :error_string if fatal error occurred, nil otherwise
39
+ # @return [Hash, nil] Hash with :error_code and :error_string if fatal error occurred,
40
+ # nil otherwise
40
41
  #
41
42
  # @example
42
43
  # if fatal_error = producer.fatal_error
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rdkafka
4
- # A producer for Kafka messages. To create a producer set up a {Config} and call {Config#producer producer} on that.
4
+ # A producer for Kafka messages. To create a producer set up a {Config} and call
5
+ # {Config#producer producer} on that.
5
6
  class Producer
6
7
  include Helpers::Time
7
8
  include Helpers::OAuth
8
9
  include Helpers::Metadata
9
10
 
10
- # @private
11
+ # @!visibility private
11
12
  @@partitions_count_cache = PartitionsCountCache.new
12
13
 
13
14
  # Global (process wide) partitions cache. We use it to store number of topics partitions,
@@ -175,8 +176,7 @@ module Rdkafka
175
176
  end
176
177
  end
177
178
 
178
- # Begin a new transaction
179
- # Requires {#init_transactions} to have been called first
179
+ # Begin a new transaction. Requires {#init_transactions} to have been called first
180
180
  #
181
181
  # @return [true] Returns true on success
182
182
  # @raise [RdkafkaError] if beginning the transaction fails
@@ -331,10 +331,9 @@ module Rdkafka
331
331
  # @return [Integer] the number of messages in the queue
332
332
  # @raise [Rdkafka::ClosedProducerError] if called on a closed producer
333
333
  #
334
- # @note This method is thread-safe as it uses the @native_kafka.with_inner synchronization
335
- #
336
334
  # @example
337
335
  # producer.queue_size #=> 42
336
+ # @note This method is thread-safe as it uses the @native_kafka.with_inner synchronization
338
337
  def queue_size
339
338
  closed_producer_check(__method__)
340
339
 
@@ -360,10 +359,6 @@ module Rdkafka
360
359
  # @return [nil]
361
360
  # @raise [Rdkafka::ClosedProducerError] if called on a closed producer
362
361
  #
363
- # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
364
- # Other producer operations (produce, close, etc.) will wait until this method returns.
365
- # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
366
- #
367
362
  # @example Drain all pending callbacks
368
363
  # producer.events_poll_nb_each { |_count| }
369
364
  #
@@ -372,6 +367,9 @@ module Rdkafka
372
367
  # producer.events_poll_nb_each do |_count|
373
368
  # :stop if monotonic_now >= deadline
374
369
  # end
370
+ # @note This method holds the inner lock until the queue is empty or `:stop` is returned.
371
+ # Other producer operations (produce, close, etc.) will wait until this method returns.
372
+ # @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
375
373
  def events_poll_nb_each
376
374
  closed_producer_check(__method__)
377
375
 
@@ -387,7 +385,8 @@ module Rdkafka
387
385
  # Partition count for a given topic.
388
386
  #
389
387
  # @param topic [String] The topic name.
390
- # @return [Integer] partition count for a given topic or `RD_KAFKA_PARTITION_UA (-1)` if it could not be obtained.
388
+ # @return [Integer] partition count for a given topic or `RD_KAFKA_PARTITION_UA (-1)` if it
389
+ # could not be obtained.
391
390
  #
392
391
  # @note If 'allow.auto.create.topics' is set to true in the broker, the topic will be
393
392
  # auto-created after returning nil.
@@ -422,23 +421,32 @@ module Rdkafka
422
421
  end
423
422
  end
424
423
 
425
- # Produces a message to a Kafka topic. The message is added to rdkafka's queue, call {DeliveryHandle#wait wait} on the returned delivery handle to make sure it is delivered.
424
+ # Produces a message to a Kafka topic. The message is added to rdkafka's queue, call
425
+ # {DeliveryHandle#wait wait} on the returned delivery handle to make sure it is delivered.
426
426
  #
427
- # When no partition is specified the underlying Kafka library picks a partition based on the key. If no key is specified, a random partition will be used.
428
- # When a timestamp is provided this is used instead of the auto-generated timestamp.
427
+ # When no partition is specified the underlying Kafka library picks a partition based on the
428
+ # key. If no key is specified, a random partition will be used. When a timestamp is provided
429
+ # this is used instead of the auto-generated timestamp.
429
430
  #
430
431
  # @param topic [String] The topic to produce to
431
432
  # @param payload [String, nil]
432
433
  # @param key [String, nil]
433
434
  # @param partition [Integer, nil] Optional partition to produce to
434
- # @param partition_key [String, nil] Optional partition key based on which partition assignment can happen
435
- # @param timestamp [Time, Integer, nil] Optional timestamp of this message. Integer timestamp is in milliseconds since Jan 1 1970.
436
- # @param headers [Hash{String => String, Array<String>}] Optional message headers. Values can be either a single string or an array of strings to support duplicate headers per KIP-82
437
- # @param label [Object, nil] a label that can be assigned when producing a message that will be part of the delivery handle and the delivery report
438
- # @param topic_config [Hash] topic config for given message dispatch. Allows to send messages to topics with different configuration
435
+ # @param partition_key [String, nil] Optional partition key based on which partition
436
+ # assignment can happen
437
+ # @param timestamp [Time, Integer, nil] Optional timestamp of this message. Integer
438
+ # timestamp is in milliseconds since Jan 1 1970.
439
+ # @param headers [Hash{String => String, Array<String>}] Optional message headers. Values
440
+ # can be either a single string or an array of strings to support duplicate headers per
441
+ # KIP-82
442
+ # @param label [Object, nil] a label that can be assigned when producing a message that
443
+ # will be part of the delivery handle and the delivery report
444
+ # @param topic_config [Hash] topic config for given message dispatch. Allows to send
445
+ # messages to topics with different configuration
439
446
  # @param partitioner [String] name of the partitioner to use
440
447
  #
441
- # @return [DeliveryHandle] Delivery handle that can be used to wait for the result of producing this message
448
+ # @return [DeliveryHandle] Delivery handle that can be used to wait for the result of
449
+ # producing this message
442
450
  #
443
451
  # @raise [RdkafkaError] When adding the message to rdkafka's queue failed
444
452
  def produce(
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  # Current rdkafka-ruby gem version
5
- VERSION = "0.28.0"
5
+ VERSION = "0.28.2"
6
6
  # Target librdkafka version to be used
7
7
  LIBRDKAFKA_VERSION = "2.14.2"
8
8
  # SHA256 hash of the librdkafka source tarball for verification
data/lib/rdkafka.rb CHANGED
@@ -17,6 +17,8 @@ require "rdkafka/admin/create_topic_handle"
17
17
  require "rdkafka/admin/create_topic_report"
18
18
  require "rdkafka/admin/delete_groups_handle"
19
19
  require "rdkafka/admin/delete_groups_report"
20
+ require "rdkafka/admin/delete_records_handle"
21
+ require "rdkafka/admin/delete_records_report"
20
22
  require "rdkafka/admin/delete_topic_handle"
21
23
  require "rdkafka/admin/delete_topic_report"
22
24
  require "rdkafka/admin/create_partitions_handle"
@@ -33,6 +35,8 @@ require "rdkafka/admin/incremental_alter_configs_handle"
33
35
  require "rdkafka/admin/incremental_alter_configs_report"
34
36
  require "rdkafka/admin/list_offsets_handle"
35
37
  require "rdkafka/admin/list_offsets_report"
38
+ require "rdkafka/admin/list_consumer_groups_handle"
39
+ require "rdkafka/admin/list_consumer_groups_report"
36
40
  require "rdkafka/admin/acl_binding_result"
37
41
  require "rdkafka/admin/config_binding_result"
38
42
  require "rdkafka/admin/config_resource_binding_result"
@@ -43,17 +47,20 @@ require "rdkafka/callbacks/create_topic_handler"
43
47
  require "rdkafka/callbacks/delete_topic_handler"
44
48
  require "rdkafka/callbacks/create_partitions_handler"
45
49
  require "rdkafka/callbacks/delete_groups_handler"
50
+ require "rdkafka/callbacks/delete_records_handler"
46
51
  require "rdkafka/callbacks/create_acl_handler"
47
52
  require "rdkafka/callbacks/delete_acl_handler"
48
53
  require "rdkafka/callbacks/describe_acl_handler"
49
54
  require "rdkafka/callbacks/describe_configs_handler"
50
55
  require "rdkafka/callbacks/incremental_alter_configs_handler"
51
56
  require "rdkafka/callbacks/list_offsets_handler"
57
+ require "rdkafka/callbacks/list_consumer_groups_handler"
52
58
  require "rdkafka/config"
53
59
  require "rdkafka/consumer"
54
60
  require "rdkafka/consumer/headers"
55
61
  require "rdkafka/consumer/message"
56
62
  require "rdkafka/consumer/partition"
63
+ require "rdkafka/consumer/allocator"
57
64
  require "rdkafka/consumer/topic_partition_list"
58
65
  require "rdkafka/error"
59
66
  require "rdkafka/metadata"
@@ -62,9 +69,12 @@ require "rdkafka/producer/partitions_count_cache"
62
69
  require "rdkafka/producer"
63
70
  require "rdkafka/producer/delivery_handle"
64
71
  require "rdkafka/producer/delivery_report"
72
+ require "rdkafka/clients"
65
73
 
66
74
  # Main Rdkafka namespace of this gem
67
75
  module Rdkafka
68
76
  end
69
77
 
70
78
  Rdkafka::Bindings.rd_kafka_global_init
79
+
80
+ at_exit { Rdkafka::Clients.close_all }
data/package-lock.json CHANGED
@@ -103,9 +103,9 @@
103
103
  }
104
104
  },
105
105
  "node_modules/fastq": {
106
- "version": "1.20.1",
107
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
108
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
106
+ "version": "1.20.2",
107
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.2.tgz",
108
+ "integrity": "sha512-UpGiiODyCGprM8EPP6JodP6jC9Rws6TCuiDOD+nn0CJhR8guI3g/ozo4ugL0vJ+Yz1UtJuuRPqvQuybVOF1VQA==",
109
109
  "dev": true,
110
110
  "license": "ISC",
111
111
  "dependencies": {
@@ -286,9 +286,9 @@
286
286
  }
287
287
  },
288
288
  "node_modules/smol-toml": {
289
- "version": "1.7.0",
290
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz",
291
- "integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==",
289
+ "version": "1.8.0",
290
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz",
291
+ "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==",
292
292
  "dev": true,
293
293
  "license": "BSD-3-Clause",
294
294
  "engines": {
data/renovate.json CHANGED
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "depNameTemplate": "openssl/openssl",
29
29
  "datasourceTemplate": "github-releases",
30
- "extractVersionTemplate": "^OpenSSL_(?<version>.*)$"
30
+ "extractVersionTemplate": "^openssl-(?<version>.*)$"
31
31
  },
32
32
  {
33
33
  "customType": "regex",