rdkafka 0.22.2 → 0.29.0
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 +101 -3
- data/README.md +21 -14
- data/Rakefile +21 -21
- data/bin/verify_kafka_warnings +39 -0
- data/dist/{librdkafka-2.8.0.tar.gz → librdkafka-2.14.2.tar.gz} +0 -0
- data/docker-compose-ssl.yml +35 -0
- data/docker-compose.yml +2 -2
- data/ext/Rakefile +27 -27
- data/lib/rdkafka/abstract_handle.rb +54 -7
- data/lib/rdkafka/admin/acl_binding_result.rb +5 -5
- data/lib/rdkafka/admin/config_binding_result.rb +2 -2
- data/lib/rdkafka/admin/config_resource_binding_result.rb +1 -0
- data/lib/rdkafka/admin/create_acl_handle.rb +10 -6
- data/lib/rdkafka/admin/create_acl_report.rb +3 -2
- data/lib/rdkafka/admin/create_partitions_handle.rb +8 -7
- data/lib/rdkafka/admin/create_partitions_report.rb +1 -0
- data/lib/rdkafka/admin/create_topic_handle.rb +8 -7
- data/lib/rdkafka/admin/create_topic_report.rb +3 -0
- data/lib/rdkafka/admin/delete_acl_handle.rb +9 -8
- data/lib/rdkafka/admin/delete_acl_report.rb +5 -3
- data/lib/rdkafka/admin/delete_groups_handle.rb +10 -7
- data/lib/rdkafka/admin/delete_groups_report.rb +3 -0
- data/lib/rdkafka/admin/delete_topic_handle.rb +8 -7
- data/lib/rdkafka/admin/delete_topic_report.rb +3 -0
- data/lib/rdkafka/admin/describe_acl_handle.rb +9 -8
- data/lib/rdkafka/admin/describe_acl_report.rb +5 -3
- data/lib/rdkafka/admin/describe_configs_handle.rb +7 -10
- data/lib/rdkafka/admin/describe_configs_report.rb +8 -6
- data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +7 -10
- data/lib/rdkafka/admin/incremental_alter_configs_report.rb +8 -6
- data/lib/rdkafka/admin/list_offsets_handle.rb +31 -0
- data/lib/rdkafka/admin/list_offsets_report.rb +51 -0
- data/lib/rdkafka/admin.rb +357 -159
- data/lib/rdkafka/bindings.rb +205 -111
- data/lib/rdkafka/callbacks/base_handler.rb +62 -0
- data/lib/rdkafka/callbacks/create_acl_handler.rb +37 -0
- data/lib/rdkafka/callbacks/create_partitions_handler.rb +37 -0
- data/lib/rdkafka/callbacks/create_topic_handler.rb +37 -0
- data/lib/rdkafka/callbacks/delete_acl_handler.rb +42 -0
- data/lib/rdkafka/callbacks/delete_groups_handler.rb +37 -0
- data/lib/rdkafka/callbacks/delete_topic_handler.rb +37 -0
- data/lib/rdkafka/callbacks/describe_acl_handler.rb +35 -0
- data/lib/rdkafka/callbacks/describe_configs_handler.rb +42 -0
- data/lib/rdkafka/callbacks/incremental_alter_configs_handler.rb +42 -0
- data/lib/rdkafka/callbacks/list_offsets_handler.rb +42 -0
- data/lib/rdkafka/callbacks.rb +125 -216
- data/lib/rdkafka/config.rb +126 -66
- data/lib/rdkafka/consumer/headers.rb +22 -7
- data/lib/rdkafka/consumer/message.rb +12 -11
- data/lib/rdkafka/consumer/partition.rb +15 -4
- data/lib/rdkafka/consumer/topic_partition_list.rb +64 -38
- data/lib/rdkafka/consumer.rb +513 -59
- data/lib/rdkafka/defaults.rb +125 -0
- data/lib/rdkafka/error.rb +40 -14
- data/lib/rdkafka/helpers/metadata.rb +29 -0
- data/lib/rdkafka/helpers/oauth.rb +45 -13
- data/lib/rdkafka/helpers/time.rb +5 -0
- data/lib/rdkafka/metadata.rb +128 -37
- data/lib/rdkafka/native_kafka.rb +91 -8
- data/lib/rdkafka/producer/delivery_handle.rb +6 -6
- data/lib/rdkafka/producer/delivery_report.rb +10 -6
- data/lib/rdkafka/producer/partitions_count_cache.rb +51 -55
- data/lib/rdkafka/producer.rb +193 -95
- data/lib/rdkafka/version.rb +6 -3
- data/lib/rdkafka.rb +15 -0
- data/package-lock.json +331 -0
- data/package.json +9 -0
- data/rdkafka.gemspec +58 -36
- data/renovate.json +39 -23
- metadata +39 -125
- data/.github/CODEOWNERS +0 -3
- data/.github/FUNDING.yml +0 -1
- data/.github/workflows/ci_linux_x86_64_gnu.yml +0 -271
- data/.github/workflows/ci_linux_x86_64_musl.yml +0 -194
- data/.github/workflows/ci_macos_arm64.yml +0 -284
- data/.github/workflows/push_linux_x86_64_gnu.yml +0 -65
- data/.github/workflows/push_linux_x86_64_musl.yml +0 -79
- data/.github/workflows/push_macos_arm64.yml +0 -54
- data/.github/workflows/push_ruby.yml +0 -37
- data/.github/workflows/verify-action-pins.yml +0 -16
- data/.gitignore +0 -14
- data/.rspec +0 -2
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.yardopts +0 -2
- data/Gemfile +0 -5
- data/ext/README.md +0 -19
- data/ext/build_common.sh +0 -361
- data/ext/build_linux_x86_64_gnu.sh +0 -306
- data/ext/build_linux_x86_64_musl.sh +0 -763
- data/ext/build_macos_arm64.sh +0 -550
- data/spec/rdkafka/abstract_handle_spec.rb +0 -117
- data/spec/rdkafka/admin/create_acl_handle_spec.rb +0 -56
- data/spec/rdkafka/admin/create_acl_report_spec.rb +0 -18
- data/spec/rdkafka/admin/create_topic_handle_spec.rb +0 -52
- data/spec/rdkafka/admin/create_topic_report_spec.rb +0 -16
- data/spec/rdkafka/admin/delete_acl_handle_spec.rb +0 -85
- data/spec/rdkafka/admin/delete_acl_report_spec.rb +0 -72
- data/spec/rdkafka/admin/delete_topic_handle_spec.rb +0 -52
- data/spec/rdkafka/admin/delete_topic_report_spec.rb +0 -16
- data/spec/rdkafka/admin/describe_acl_handle_spec.rb +0 -85
- data/spec/rdkafka/admin/describe_acl_report_spec.rb +0 -73
- data/spec/rdkafka/admin_spec.rb +0 -971
- data/spec/rdkafka/bindings_spec.rb +0 -199
- data/spec/rdkafka/callbacks_spec.rb +0 -20
- data/spec/rdkafka/config_spec.rb +0 -258
- data/spec/rdkafka/consumer/headers_spec.rb +0 -73
- data/spec/rdkafka/consumer/message_spec.rb +0 -139
- data/spec/rdkafka/consumer/partition_spec.rb +0 -57
- data/spec/rdkafka/consumer/topic_partition_list_spec.rb +0 -248
- data/spec/rdkafka/consumer_spec.rb +0 -1274
- data/spec/rdkafka/error_spec.rb +0 -89
- data/spec/rdkafka/metadata_spec.rb +0 -79
- data/spec/rdkafka/native_kafka_spec.rb +0 -130
- data/spec/rdkafka/producer/delivery_handle_spec.rb +0 -45
- data/spec/rdkafka/producer/delivery_report_spec.rb +0 -25
- data/spec/rdkafka/producer/partitions_count_cache_spec.rb +0 -359
- data/spec/rdkafka/producer_spec.rb +0 -1345
- data/spec/spec_helper.rb +0 -195
data/lib/rdkafka/producer.rb
CHANGED
|
@@ -5,9 +5,7 @@ module Rdkafka
|
|
|
5
5
|
class Producer
|
|
6
6
|
include Helpers::Time
|
|
7
7
|
include Helpers::OAuth
|
|
8
|
-
|
|
9
|
-
# Empty hash used as a default
|
|
10
|
-
EMPTY_HASH = {}.freeze
|
|
8
|
+
include Helpers::Metadata
|
|
11
9
|
|
|
12
10
|
# @private
|
|
13
11
|
@@partitions_count_cache = PartitionsCountCache.new
|
|
@@ -17,10 +15,9 @@ module Rdkafka
|
|
|
17
15
|
# then. Since the partitions count can only grow and should be same for all consumers and
|
|
18
16
|
# producers, we can use a global cache as long as we ensure that updates only move up.
|
|
19
17
|
#
|
|
18
|
+
# @return [Rdkafka::Producer::PartitionsCountCache]
|
|
20
19
|
# @note It is critical to remember, that not all users may have statistics callbacks enabled,
|
|
21
20
|
# hence we should not make assumption that this cache is always updated from the stats.
|
|
22
|
-
#
|
|
23
|
-
# @return [Rdkafka::Producer::PartitionsCountCache]
|
|
24
21
|
def self.partitions_count_cache
|
|
25
22
|
@@partitions_count_cache
|
|
26
23
|
end
|
|
@@ -30,6 +27,9 @@ module Rdkafka
|
|
|
30
27
|
@@partitions_count_cache = partitions_count_cache
|
|
31
28
|
end
|
|
32
29
|
|
|
30
|
+
# Empty hash used as a default
|
|
31
|
+
EMPTY_HASH = {}.freeze
|
|
32
|
+
|
|
33
33
|
private_constant :EMPTY_HASH
|
|
34
34
|
|
|
35
35
|
# Raised when there was a critical issue when invoking rd_kafka_topic_new
|
|
@@ -64,12 +64,13 @@ module Rdkafka
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Sets alternative set of configuration details that can be set per topic
|
|
67
|
-
#
|
|
68
|
-
# librdkafka caching
|
|
67
|
+
#
|
|
69
68
|
# @param topic [String] The topic name
|
|
70
69
|
# @param config [Hash] config we want to use per topic basis
|
|
71
70
|
# @param config_hash [Integer] hash of the config. We expect it here instead of computing it,
|
|
72
71
|
# because it is already computed during the retrieval attempt in the `#produce` flow.
|
|
72
|
+
# @note It is not allowed to re-set the same topic config twice because of the underlying
|
|
73
|
+
# librdkafka caching
|
|
73
74
|
def set_topic_config(topic, config, config_hash)
|
|
74
75
|
# Ensure lock on topic reference just in case
|
|
75
76
|
@native_kafka.with_inner do |inner|
|
|
@@ -80,25 +81,31 @@ module Rdkafka
|
|
|
80
81
|
|
|
81
82
|
# If config is empty, we create an empty reference that will be used with defaults
|
|
82
83
|
rd_topic_config = if config.empty?
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
nil
|
|
85
|
+
else
|
|
86
|
+
Rdkafka::Bindings.rd_kafka_topic_conf_new.tap do |topic_config|
|
|
87
|
+
config.each do |key, value|
|
|
88
|
+
error_buffer = FFI::MemoryPointer.new(:char, 256)
|
|
89
|
+
result = Rdkafka::Bindings.rd_kafka_topic_conf_set(
|
|
90
|
+
topic_config,
|
|
91
|
+
key.to_s,
|
|
92
|
+
value.to_s,
|
|
93
|
+
error_buffer,
|
|
94
|
+
256
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
unless result == :config_ok
|
|
98
|
+
# rd_kafka_topic_new has not been called yet, so librdkafka has not taken
|
|
99
|
+
# ownership of the config. Destroy it ourselves before raising, otherwise the
|
|
100
|
+
# partially built rd_kafka_topic_conf_t leaks. (On the rd_kafka_topic_new path
|
|
101
|
+
# librdkafka frees the conf on both success and failure, so we never destroy it
|
|
102
|
+
# there.)
|
|
103
|
+
Rdkafka::Bindings.rd_kafka_topic_conf_destroy(topic_config)
|
|
104
|
+
raise Config::ConfigError.new(error_buffer.read_string)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
102
109
|
|
|
103
110
|
topic_handle = Bindings.rd_kafka_topic_new(inner, topic, rd_topic_config)
|
|
104
111
|
|
|
@@ -122,11 +129,30 @@ module Rdkafka
|
|
|
122
129
|
end
|
|
123
130
|
end
|
|
124
131
|
|
|
132
|
+
# Enable IO event notifications for fiber scheduler integration
|
|
133
|
+
# When delivery confirmations arrive, librdkafka will write to your FD
|
|
134
|
+
#
|
|
135
|
+
# @param fd [Integer] file descriptor to signal (from IO.pipe or eventfd)
|
|
136
|
+
# @param payload [String] data to write to fd (default: "\x01")
|
|
137
|
+
# @return [nil]
|
|
138
|
+
# @raise [ClosedInnerError] when the producer is closed
|
|
139
|
+
def enable_queue_io_events(fd, payload = "\x01")
|
|
140
|
+
@native_kafka.enable_main_queue_io_events(fd, payload)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Enable IO event notifications for background events
|
|
144
|
+
# @param fd [Integer] file descriptor to signal (from IO.pipe or eventfd)
|
|
145
|
+
# @param payload [String] data to write to fd (default: "\x01")
|
|
146
|
+
# @return [nil]
|
|
147
|
+
# @raise [ClosedInnerError] when the producer is closed
|
|
148
|
+
def enable_background_queue_io_events(fd, payload = "\x01")
|
|
149
|
+
@native_kafka.enable_background_queue_io_events(fd, payload)
|
|
150
|
+
end
|
|
151
|
+
|
|
125
152
|
# Set a callback that will be called every time a message is successfully produced.
|
|
126
153
|
# The callback is called with a {DeliveryReport} and {DeliveryHandle}
|
|
127
154
|
#
|
|
128
|
-
# @param callback [Proc, #call]
|
|
129
|
-
#
|
|
155
|
+
# @param callback [Proc, #call] callable object to handle delivery reports
|
|
130
156
|
# @return [nil]
|
|
131
157
|
def delivery_callback=(callback)
|
|
132
158
|
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call)
|
|
@@ -168,7 +194,7 @@ module Rdkafka
|
|
|
168
194
|
# should be no other errors.
|
|
169
195
|
#
|
|
170
196
|
# @note For `timed_out` we do not raise an error to keep it backwards compatible
|
|
171
|
-
def flush(timeout_ms=
|
|
197
|
+
def flush(timeout_ms = Defaults::PRODUCER_FLUSH_TIMEOUT_MS)
|
|
172
198
|
closed_producer_check(__method__)
|
|
173
199
|
|
|
174
200
|
code = nil
|
|
@@ -208,11 +234,76 @@ module Rdkafka
|
|
|
208
234
|
code.zero? || raise(Rdkafka::RdkafkaError.new(code))
|
|
209
235
|
|
|
210
236
|
# Wait for the purge to affect everything
|
|
211
|
-
sleep(0
|
|
237
|
+
sleep(Defaults::PRODUCER_PURGE_SLEEP_INTERVAL_MS / 1000.0) until flush(Defaults::PRODUCER_PURGE_FLUSH_TIMEOUT_MS)
|
|
212
238
|
|
|
213
239
|
true
|
|
214
240
|
end
|
|
215
241
|
|
|
242
|
+
# Returns the number of messages and requests waiting to be sent to the broker as well as
|
|
243
|
+
# delivery reports queued for the application.
|
|
244
|
+
#
|
|
245
|
+
# This provides visibility into the producer's internal queue depth, useful for:
|
|
246
|
+
# - Monitoring producer backpressure
|
|
247
|
+
# - Implementing custom flow control
|
|
248
|
+
# - Debugging message delivery issues
|
|
249
|
+
# - Graceful shutdown logic (wait until queue is empty)
|
|
250
|
+
#
|
|
251
|
+
# @return [Integer] the number of messages in the queue
|
|
252
|
+
# @raise [Rdkafka::ClosedProducerError] if called on a closed producer
|
|
253
|
+
#
|
|
254
|
+
# @note This method is thread-safe as it uses the @native_kafka.with_inner synchronization
|
|
255
|
+
#
|
|
256
|
+
# @example
|
|
257
|
+
# producer.queue_size #=> 42
|
|
258
|
+
def queue_size
|
|
259
|
+
closed_producer_check(__method__)
|
|
260
|
+
|
|
261
|
+
@native_kafka.with_inner do |inner|
|
|
262
|
+
Rdkafka::Bindings.rd_kafka_outq_len(inner)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
alias_method :queue_length, :queue_size
|
|
267
|
+
|
|
268
|
+
# Polls for events in a non-blocking loop, yielding the count after each iteration.
|
|
269
|
+
#
|
|
270
|
+
# This method processes delivery callbacks in a single GVL/mutex session, which is more
|
|
271
|
+
# efficient than repeated individual polls. It uses non-blocking polls internally
|
|
272
|
+
# (no GVL release between polls).
|
|
273
|
+
#
|
|
274
|
+
# Yields the count of events processed after each poll iteration, allowing the caller
|
|
275
|
+
# to implement timeout or other termination logic by returning `:stop`.
|
|
276
|
+
#
|
|
277
|
+
# @yield [count] Called after each poll iteration
|
|
278
|
+
# @yieldparam count [Integer] Number of events processed in this iteration
|
|
279
|
+
# @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
|
|
280
|
+
# @return [nil]
|
|
281
|
+
# @raise [Rdkafka::ClosedProducerError] if called on a closed producer
|
|
282
|
+
#
|
|
283
|
+
# @note This method holds the inner lock until the queue is empty or `:stop` is returned.
|
|
284
|
+
# Other producer operations (produce, close, etc.) will wait until this method returns.
|
|
285
|
+
# @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
|
|
286
|
+
#
|
|
287
|
+
# @example Drain all pending callbacks
|
|
288
|
+
# producer.events_poll_nb_each { |_count| }
|
|
289
|
+
#
|
|
290
|
+
# @example With timeout control
|
|
291
|
+
# deadline = monotonic_now + timeout_ms
|
|
292
|
+
# producer.events_poll_nb_each do |_count|
|
|
293
|
+
# :stop if monotonic_now >= deadline
|
|
294
|
+
# end
|
|
295
|
+
def events_poll_nb_each
|
|
296
|
+
closed_producer_check(__method__)
|
|
297
|
+
|
|
298
|
+
@native_kafka.with_inner do |inner|
|
|
299
|
+
loop do
|
|
300
|
+
count = Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0)
|
|
301
|
+
break if count.zero?
|
|
302
|
+
break if yield(count) == :stop
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
216
307
|
# Partition count for a given topic.
|
|
217
308
|
#
|
|
218
309
|
# @param topic [String] The topic name.
|
|
@@ -237,15 +328,16 @@ module Rdkafka
|
|
|
237
328
|
topic_metadata = ::Rdkafka::Metadata.new(inner, topic).topics&.first
|
|
238
329
|
end
|
|
239
330
|
|
|
240
|
-
topic_metadata ? topic_metadata[:partition_count] :
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
331
|
+
topic_metadata ? topic_metadata[:partition_count] : Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
332
|
+
rescue Rdkafka::RdkafkaError => e
|
|
333
|
+
# A missing topic is an expected, cacheable outcome (the topic may be auto-created on
|
|
334
|
+
# produce, or simply not exist yet). Returning RD_KAFKA_PARTITION_UA from inside the block
|
|
335
|
+
# caches it, so we don't re-run a blocking metadata query on every produce(partition_key:)
|
|
336
|
+
# to that topic. Anything else is a real error and is re-raised.
|
|
337
|
+
raise(e) unless e.code == :unknown_topic_or_part
|
|
247
338
|
|
|
248
|
-
|
|
339
|
+
Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
340
|
+
end
|
|
249
341
|
end
|
|
250
342
|
|
|
251
343
|
# 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.
|
|
@@ -254,14 +346,15 @@ module Rdkafka
|
|
|
254
346
|
# When a timestamp is provided this is used instead of the auto-generated timestamp.
|
|
255
347
|
#
|
|
256
348
|
# @param topic [String] The topic to produce to
|
|
257
|
-
# @param payload [String,nil]
|
|
258
|
-
# @param key [String, nil]
|
|
259
|
-
# @param partition [Integer,nil] Optional partition to produce to
|
|
349
|
+
# @param payload [String, nil]
|
|
350
|
+
# @param key [String, nil]
|
|
351
|
+
# @param partition [Integer, nil] Optional partition to produce to
|
|
260
352
|
# @param partition_key [String, nil] Optional partition key based on which partition assignment can happen
|
|
261
|
-
# @param timestamp [Time,Integer,nil] Optional timestamp of this message. Integer timestamp is in milliseconds since Jan 1 1970.
|
|
262
|
-
# @param headers [Hash
|
|
353
|
+
# @param timestamp [Time, Integer, nil] Optional timestamp of this message. Integer timestamp is in milliseconds since Jan 1 1970.
|
|
354
|
+
# @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
|
|
263
355
|
# @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
|
|
264
356
|
# @param topic_config [Hash] topic config for given message dispatch. Allows to send messages to topics with different configuration
|
|
357
|
+
# @param partitioner [String] name of the partitioner to use
|
|
265
358
|
#
|
|
266
359
|
# @return [DeliveryHandle] Delivery handle that can be used to wait for the result of producing this message
|
|
267
360
|
#
|
|
@@ -284,17 +377,17 @@ module Rdkafka
|
|
|
284
377
|
|
|
285
378
|
# Get payload length
|
|
286
379
|
payload_size = if payload.nil?
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
380
|
+
0
|
|
381
|
+
else
|
|
382
|
+
payload.bytesize
|
|
383
|
+
end
|
|
291
384
|
|
|
292
385
|
# Get key length
|
|
293
386
|
key_size = if key.nil?
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
387
|
+
0
|
|
388
|
+
else
|
|
389
|
+
key.bytesize
|
|
390
|
+
end
|
|
298
391
|
|
|
299
392
|
topic_config_hash = topic_config.hash
|
|
300
393
|
|
|
@@ -311,50 +404,52 @@ module Rdkafka
|
|
|
311
404
|
selected_partitioner = @topics_configs.dig(topic, topic_config_hash, :partitioner) || partitioner
|
|
312
405
|
|
|
313
406
|
# If the topic is not present, set to -1
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
407
|
+
if partition_count.positive?
|
|
408
|
+
partition = Rdkafka::Bindings.partitioner(
|
|
409
|
+
topic_ref,
|
|
410
|
+
partition_key,
|
|
411
|
+
partition_count,
|
|
412
|
+
selected_partitioner
|
|
413
|
+
)
|
|
414
|
+
end
|
|
319
415
|
end
|
|
320
416
|
|
|
321
|
-
# If partition is nil, use
|
|
417
|
+
# If partition is nil, use RD_KAFKA_PARTITION_UA to let librdafka set the partition randomly or
|
|
322
418
|
# based on the key when present.
|
|
323
|
-
partition ||=
|
|
419
|
+
partition ||= Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
324
420
|
|
|
325
|
-
# If timestamp is nil use 0 and let Kafka set one. If an integer or time
|
|
326
|
-
# use it.
|
|
421
|
+
# If timestamp is nil use 0 and let Kafka set one. If an integer or time use it.
|
|
327
422
|
raw_timestamp = if timestamp.nil?
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
423
|
+
0
|
|
424
|
+
elsif timestamp.is_a?(Integer)
|
|
425
|
+
timestamp
|
|
426
|
+
elsif timestamp.is_a?(Time)
|
|
427
|
+
(timestamp.to_i * 1000) + (timestamp.usec / 1000)
|
|
428
|
+
else
|
|
429
|
+
raise TypeError.new("Timestamp has to be nil, an Integer or a Time")
|
|
430
|
+
end
|
|
336
431
|
|
|
337
432
|
delivery_handle = DeliveryHandle.new
|
|
338
433
|
delivery_handle.label = label
|
|
339
434
|
delivery_handle.topic = topic
|
|
340
435
|
delivery_handle[:pending] = true
|
|
341
|
-
delivery_handle[:response] =
|
|
342
|
-
delivery_handle[:partition] =
|
|
343
|
-
delivery_handle[:offset] =
|
|
436
|
+
delivery_handle[:response] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
437
|
+
delivery_handle[:partition] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
438
|
+
delivery_handle[:offset] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
344
439
|
DeliveryHandle.register(delivery_handle)
|
|
345
440
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
headers
|
|
441
|
+
begin
|
|
442
|
+
args = [
|
|
443
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_RKT, :pointer, topic_ref,
|
|
444
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_MSGFLAGS, :int, Rdkafka::Bindings::RD_KAFKA_MSG_F_COPY,
|
|
445
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_VALUE, :buffer_in, payload, :size_t, payload_size,
|
|
446
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_KEY, :buffer_in, key, :size_t, key_size,
|
|
447
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_PARTITION, :int32, partition,
|
|
448
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_TIMESTAMP, :int64, raw_timestamp,
|
|
449
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_OPAQUE, :pointer, delivery_handle
|
|
450
|
+
]
|
|
451
|
+
|
|
452
|
+
headers&.each do |key0, value0|
|
|
358
453
|
key = key0.to_s
|
|
359
454
|
if value0.is_a?(Array)
|
|
360
455
|
# Handle array of values per KIP-82
|
|
@@ -374,22 +469,24 @@ module Rdkafka
|
|
|
374
469
|
args << :size_t << value.bytesize
|
|
375
470
|
end
|
|
376
471
|
end
|
|
377
|
-
end
|
|
378
472
|
|
|
379
|
-
|
|
473
|
+
args << :int << Rdkafka::Bindings::RD_KAFKA_VTYPE_END
|
|
380
474
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
475
|
+
# Produce the message
|
|
476
|
+
response = @native_kafka.with_inner do |inner|
|
|
477
|
+
Rdkafka::Bindings.rd_kafka_producev(
|
|
478
|
+
inner,
|
|
479
|
+
*args
|
|
480
|
+
)
|
|
481
|
+
end
|
|
388
482
|
|
|
389
|
-
|
|
390
|
-
|
|
483
|
+
# Raise error if the produce call was not successful
|
|
484
|
+
if response != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
485
|
+
raise RdkafkaError.new(response)
|
|
486
|
+
end
|
|
487
|
+
rescue Exception
|
|
391
488
|
DeliveryHandle.remove(delivery_handle.to_ptr.address)
|
|
392
|
-
raise
|
|
489
|
+
raise
|
|
393
490
|
end
|
|
394
491
|
|
|
395
492
|
delivery_handle
|
|
@@ -431,5 +528,6 @@ module Rdkafka
|
|
|
431
528
|
def closed_producer_check(method)
|
|
432
529
|
raise Rdkafka::ClosedProducerError.new(method) if closed?
|
|
433
530
|
end
|
|
531
|
+
alias_method :closed_check, :closed_producer_check
|
|
434
532
|
end
|
|
435
533
|
end
|
data/lib/rdkafka/version.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rdkafka
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
# Current rdkafka-ruby gem version
|
|
5
|
+
VERSION = "0.29.0"
|
|
6
|
+
# Target librdkafka version to be used
|
|
7
|
+
LIBRDKAFKA_VERSION = "2.14.2"
|
|
8
|
+
# SHA256 hash of the librdkafka source tarball for verification
|
|
9
|
+
LIBRDKAFKA_SOURCE_SHA256 = "d7eec9c31c817fa44402f679c252dfbf97e4c338a849a25c3579a31fd127beb8"
|
|
7
10
|
end
|
data/lib/rdkafka.rb
CHANGED
|
@@ -8,6 +8,8 @@ require "json"
|
|
|
8
8
|
require "rdkafka/version"
|
|
9
9
|
require "rdkafka/helpers/time"
|
|
10
10
|
require "rdkafka/helpers/oauth"
|
|
11
|
+
require "rdkafka/helpers/metadata"
|
|
12
|
+
require "rdkafka/defaults"
|
|
11
13
|
require "rdkafka/abstract_handle"
|
|
12
14
|
require "rdkafka/admin"
|
|
13
15
|
require "rdkafka/admin/create_topic_handle"
|
|
@@ -28,11 +30,24 @@ require "rdkafka/admin/describe_configs_handle"
|
|
|
28
30
|
require "rdkafka/admin/describe_configs_report"
|
|
29
31
|
require "rdkafka/admin/incremental_alter_configs_handle"
|
|
30
32
|
require "rdkafka/admin/incremental_alter_configs_report"
|
|
33
|
+
require "rdkafka/admin/list_offsets_handle"
|
|
34
|
+
require "rdkafka/admin/list_offsets_report"
|
|
31
35
|
require "rdkafka/admin/acl_binding_result"
|
|
32
36
|
require "rdkafka/admin/config_binding_result"
|
|
33
37
|
require "rdkafka/admin/config_resource_binding_result"
|
|
34
38
|
require "rdkafka/bindings"
|
|
35
39
|
require "rdkafka/callbacks"
|
|
40
|
+
require "rdkafka/callbacks/base_handler"
|
|
41
|
+
require "rdkafka/callbacks/create_topic_handler"
|
|
42
|
+
require "rdkafka/callbacks/delete_topic_handler"
|
|
43
|
+
require "rdkafka/callbacks/create_partitions_handler"
|
|
44
|
+
require "rdkafka/callbacks/delete_groups_handler"
|
|
45
|
+
require "rdkafka/callbacks/create_acl_handler"
|
|
46
|
+
require "rdkafka/callbacks/delete_acl_handler"
|
|
47
|
+
require "rdkafka/callbacks/describe_acl_handler"
|
|
48
|
+
require "rdkafka/callbacks/describe_configs_handler"
|
|
49
|
+
require "rdkafka/callbacks/incremental_alter_configs_handler"
|
|
50
|
+
require "rdkafka/callbacks/list_offsets_handler"
|
|
36
51
|
require "rdkafka/config"
|
|
37
52
|
require "rdkafka/consumer"
|
|
38
53
|
require "rdkafka/consumer/headers"
|