rdkafka 0.24.2-aarch64-linux-gnu → 0.25.1-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 +4 -4
- data/CHANGELOG.md +18 -0
- data/Gemfile +8 -0
- data/Gemfile.lint +14 -0
- data/Gemfile.lint.lock +123 -0
- data/README.md +2 -1
- data/Rakefile +21 -21
- data/docker-compose-ssl.yml +1 -1
- data/docker-compose.yml +1 -1
- data/ext/librdkafka.so +0 -0
- data/lib/rdkafka/abstract_handle.rb +23 -5
- data/lib/rdkafka/admin/acl_binding_result.rb +5 -5
- data/lib/rdkafka/admin/config_resource_binding_result.rb +1 -0
- data/lib/rdkafka/admin/create_acl_handle.rb +7 -4
- data/lib/rdkafka/admin/create_acl_report.rb +3 -2
- data/lib/rdkafka/admin/create_partitions_handle.rb +8 -5
- data/lib/rdkafka/admin/create_partitions_report.rb +1 -0
- data/lib/rdkafka/admin/create_topic_handle.rb +8 -5
- data/lib/rdkafka/admin/create_topic_report.rb +3 -0
- data/lib/rdkafka/admin/delete_acl_handle.rb +9 -6
- data/lib/rdkafka/admin/delete_acl_report.rb +5 -3
- data/lib/rdkafka/admin/delete_groups_handle.rb +10 -5
- data/lib/rdkafka/admin/delete_groups_report.rb +3 -0
- data/lib/rdkafka/admin/delete_topic_handle.rb +8 -5
- data/lib/rdkafka/admin/delete_topic_report.rb +3 -0
- data/lib/rdkafka/admin/describe_acl_handle.rb +9 -6
- data/lib/rdkafka/admin/describe_acl_report.rb +5 -3
- data/lib/rdkafka/admin/describe_configs_handle.rb +7 -4
- data/lib/rdkafka/admin/describe_configs_report.rb +7 -1
- data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +7 -4
- data/lib/rdkafka/admin/incremental_alter_configs_report.rb +7 -1
- data/lib/rdkafka/admin.rb +194 -132
- data/lib/rdkafka/bindings.rb +155 -107
- data/lib/rdkafka/callbacks.rb +81 -21
- data/lib/rdkafka/config.rb +36 -24
- data/lib/rdkafka/consumer/headers.rb +3 -2
- data/lib/rdkafka/consumer/message.rb +12 -11
- data/lib/rdkafka/consumer/partition.rb +8 -4
- data/lib/rdkafka/consumer/topic_partition_list.rb +18 -18
- data/lib/rdkafka/consumer.rb +247 -42
- data/lib/rdkafka/defaults.rb +106 -0
- data/lib/rdkafka/error.rb +28 -13
- data/lib/rdkafka/helpers/oauth.rb +11 -6
- data/lib/rdkafka/helpers/time.rb +5 -0
- data/lib/rdkafka/metadata.rb +45 -21
- data/lib/rdkafka/native_kafka.rb +89 -4
- data/lib/rdkafka/producer/delivery_handle.rb +5 -5
- data/lib/rdkafka/producer/delivery_report.rb +8 -4
- data/lib/rdkafka/producer/partitions_count_cache.rb +29 -19
- data/lib/rdkafka/producer.rb +165 -79
- data/lib/rdkafka/version.rb +6 -3
- data/lib/rdkafka.rb +1 -0
- data/package-lock.json +331 -0
- data/package.json +9 -0
- data/rdkafka.gemspec +39 -47
- data/renovate.json +22 -8
- metadata +7 -86
data/lib/rdkafka/producer.rb
CHANGED
|
@@ -14,10 +14,9 @@ module Rdkafka
|
|
|
14
14
|
# then. Since the partitions count can only grow and should be same for all consumers and
|
|
15
15
|
# producers, we can use a global cache as long as we ensure that updates only move up.
|
|
16
16
|
#
|
|
17
|
+
# @return [Rdkafka::Producer::PartitionsCountCache]
|
|
17
18
|
# @note It is critical to remember, that not all users may have statistics callbacks enabled,
|
|
18
19
|
# hence we should not make assumption that this cache is always updated from the stats.
|
|
19
|
-
#
|
|
20
|
-
# @return [Rdkafka::Producer::PartitionsCountCache]
|
|
21
20
|
def self.partitions_count_cache
|
|
22
21
|
@@partitions_count_cache
|
|
23
22
|
end
|
|
@@ -64,12 +63,13 @@ module Rdkafka
|
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
# Sets alternative set of configuration details that can be set per topic
|
|
67
|
-
#
|
|
68
|
-
# librdkafka caching
|
|
66
|
+
#
|
|
69
67
|
# @param topic [String] The topic name
|
|
70
68
|
# @param config [Hash] config we want to use per topic basis
|
|
71
69
|
# @param config_hash [Integer] hash of the config. We expect it here instead of computing it,
|
|
72
70
|
# because it is already computed during the retrieval attempt in the `#produce` flow.
|
|
71
|
+
# @note It is not allowed to re-set the same topic config twice because of the underlying
|
|
72
|
+
# librdkafka caching
|
|
73
73
|
def set_topic_config(topic, config, config_hash)
|
|
74
74
|
# Ensure lock on topic reference just in case
|
|
75
75
|
@native_kafka.with_inner do |inner|
|
|
@@ -80,25 +80,25 @@ module Rdkafka
|
|
|
80
80
|
|
|
81
81
|
# If config is empty, we create an empty reference that will be used with defaults
|
|
82
82
|
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
|
-
|
|
83
|
+
nil
|
|
84
|
+
else
|
|
85
|
+
Rdkafka::Bindings.rd_kafka_topic_conf_new.tap do |topic_config|
|
|
86
|
+
config.each do |key, value|
|
|
87
|
+
error_buffer = FFI::MemoryPointer.new(:char, 256)
|
|
88
|
+
result = Rdkafka::Bindings.rd_kafka_topic_conf_set(
|
|
89
|
+
topic_config,
|
|
90
|
+
key.to_s,
|
|
91
|
+
value.to_s,
|
|
92
|
+
error_buffer,
|
|
93
|
+
256
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
unless result == :config_ok
|
|
97
|
+
raise Config::ConfigError.new(error_buffer.read_string)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
102
|
|
|
103
103
|
topic_handle = Bindings.rd_kafka_topic_new(inner, topic, rd_topic_config)
|
|
104
104
|
|
|
@@ -122,11 +122,30 @@ module Rdkafka
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
+
# Enable IO event notifications for fiber scheduler integration
|
|
126
|
+
# When delivery confirmations arrive, librdkafka will write to your FD
|
|
127
|
+
#
|
|
128
|
+
# @param fd [Integer] file descriptor to signal (from IO.pipe or eventfd)
|
|
129
|
+
# @param payload [String] data to write to fd (default: "\x01")
|
|
130
|
+
# @return [nil]
|
|
131
|
+
# @raise [ClosedInnerError] when the producer is closed
|
|
132
|
+
def enable_queue_io_events(fd, payload = "\x01")
|
|
133
|
+
@native_kafka.enable_main_queue_io_events(fd, payload)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Enable IO event notifications for background events
|
|
137
|
+
# @param fd [Integer] file descriptor to signal (from IO.pipe or eventfd)
|
|
138
|
+
# @param payload [String] data to write to fd (default: "\x01")
|
|
139
|
+
# @return [nil]
|
|
140
|
+
# @raise [ClosedInnerError] when the producer is closed
|
|
141
|
+
def enable_background_queue_io_events(fd, payload = "\x01")
|
|
142
|
+
@native_kafka.enable_background_queue_io_events(fd, payload)
|
|
143
|
+
end
|
|
144
|
+
|
|
125
145
|
# Set a callback that will be called every time a message is successfully produced.
|
|
126
146
|
# The callback is called with a {DeliveryReport} and {DeliveryHandle}
|
|
127
147
|
#
|
|
128
|
-
# @param callback [Proc, #call]
|
|
129
|
-
#
|
|
148
|
+
# @param callback [Proc, #call] callable object to handle delivery reports
|
|
130
149
|
# @return [nil]
|
|
131
150
|
def delivery_callback=(callback)
|
|
132
151
|
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call)
|
|
@@ -168,7 +187,7 @@ module Rdkafka
|
|
|
168
187
|
# should be no other errors.
|
|
169
188
|
#
|
|
170
189
|
# @note For `timed_out` we do not raise an error to keep it backwards compatible
|
|
171
|
-
def flush(timeout_ms=
|
|
190
|
+
def flush(timeout_ms = Defaults::PRODUCER_FLUSH_TIMEOUT_MS)
|
|
172
191
|
closed_producer_check(__method__)
|
|
173
192
|
|
|
174
193
|
code = nil
|
|
@@ -208,11 +227,76 @@ module Rdkafka
|
|
|
208
227
|
code.zero? || raise(Rdkafka::RdkafkaError.new(code))
|
|
209
228
|
|
|
210
229
|
# Wait for the purge to affect everything
|
|
211
|
-
sleep(0
|
|
230
|
+
sleep(Defaults::PRODUCER_PURGE_SLEEP_INTERVAL_MS / 1000.0) until flush(Defaults::PRODUCER_PURGE_FLUSH_TIMEOUT_MS)
|
|
212
231
|
|
|
213
232
|
true
|
|
214
233
|
end
|
|
215
234
|
|
|
235
|
+
# Returns the number of messages and requests waiting to be sent to the broker as well as
|
|
236
|
+
# delivery reports queued for the application.
|
|
237
|
+
#
|
|
238
|
+
# This provides visibility into the producer's internal queue depth, useful for:
|
|
239
|
+
# - Monitoring producer backpressure
|
|
240
|
+
# - Implementing custom flow control
|
|
241
|
+
# - Debugging message delivery issues
|
|
242
|
+
# - Graceful shutdown logic (wait until queue is empty)
|
|
243
|
+
#
|
|
244
|
+
# @return [Integer] the number of messages in the queue
|
|
245
|
+
# @raise [Rdkafka::ClosedProducerError] if called on a closed producer
|
|
246
|
+
#
|
|
247
|
+
# @note This method is thread-safe as it uses the @native_kafka.with_inner synchronization
|
|
248
|
+
#
|
|
249
|
+
# @example
|
|
250
|
+
# producer.queue_size #=> 42
|
|
251
|
+
def queue_size
|
|
252
|
+
closed_producer_check(__method__)
|
|
253
|
+
|
|
254
|
+
@native_kafka.with_inner do |inner|
|
|
255
|
+
Rdkafka::Bindings.rd_kafka_outq_len(inner)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
alias_method :queue_length, :queue_size
|
|
260
|
+
|
|
261
|
+
# Polls for events in a non-blocking loop, yielding the count after each iteration.
|
|
262
|
+
#
|
|
263
|
+
# This method processes delivery callbacks in a single GVL/mutex session, which is more
|
|
264
|
+
# efficient than repeated individual polls. It uses non-blocking polls internally
|
|
265
|
+
# (no GVL release between polls).
|
|
266
|
+
#
|
|
267
|
+
# Yields the count of events processed after each poll iteration, allowing the caller
|
|
268
|
+
# to implement timeout or other termination logic by returning `:stop`.
|
|
269
|
+
#
|
|
270
|
+
# @yield [count] Called after each poll iteration
|
|
271
|
+
# @yieldparam count [Integer] Number of events processed in this iteration
|
|
272
|
+
# @yieldreturn [Symbol, Object] Return `:stop` to break the loop, any other value continues
|
|
273
|
+
# @return [nil]
|
|
274
|
+
# @raise [Rdkafka::ClosedProducerError] if called on a closed producer
|
|
275
|
+
#
|
|
276
|
+
# @note This method holds the inner lock until the queue is empty or `:stop` is returned.
|
|
277
|
+
# Other producer operations (produce, close, etc.) will wait until this method returns.
|
|
278
|
+
# @note This method is thread-safe as it uses @native_kafka.with_inner synchronization
|
|
279
|
+
#
|
|
280
|
+
# @example Drain all pending callbacks
|
|
281
|
+
# producer.events_poll_nb_each { |_count| }
|
|
282
|
+
#
|
|
283
|
+
# @example With timeout control
|
|
284
|
+
# deadline = monotonic_now + timeout_ms
|
|
285
|
+
# producer.events_poll_nb_each do |_count|
|
|
286
|
+
# :stop if monotonic_now >= deadline
|
|
287
|
+
# end
|
|
288
|
+
def events_poll_nb_each
|
|
289
|
+
closed_producer_check(__method__)
|
|
290
|
+
|
|
291
|
+
@native_kafka.with_inner do |inner|
|
|
292
|
+
loop do
|
|
293
|
+
count = Rdkafka::Bindings.rd_kafka_poll_nb(inner, 0)
|
|
294
|
+
break if count.zero?
|
|
295
|
+
break if yield(count) == :stop
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
216
300
|
# Partition count for a given topic.
|
|
217
301
|
#
|
|
218
302
|
# @param topic [String] The topic name.
|
|
@@ -237,13 +321,13 @@ module Rdkafka
|
|
|
237
321
|
topic_metadata = ::Rdkafka::Metadata.new(inner, topic).topics&.first
|
|
238
322
|
end
|
|
239
323
|
|
|
240
|
-
topic_metadata ? topic_metadata[:partition_count] :
|
|
324
|
+
topic_metadata ? topic_metadata[:partition_count] : Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
241
325
|
end
|
|
242
326
|
rescue Rdkafka::RdkafkaError => e
|
|
243
327
|
# If the topic does not exist, it will be created or if not allowed another error will be
|
|
244
|
-
# raised. We here return
|
|
245
|
-
# discovery.
|
|
246
|
-
return
|
|
328
|
+
# raised. We here return RD_KAFKA_PARTITION_UA so this can happen without early error
|
|
329
|
+
# happening on metadata discovery.
|
|
330
|
+
return Rdkafka::Bindings::RD_KAFKA_PARTITION_UA if e.code == :unknown_topic_or_part
|
|
247
331
|
|
|
248
332
|
raise(e)
|
|
249
333
|
end
|
|
@@ -254,14 +338,15 @@ module Rdkafka
|
|
|
254
338
|
# When a timestamp is provided this is used instead of the auto-generated timestamp.
|
|
255
339
|
#
|
|
256
340
|
# @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
|
|
341
|
+
# @param payload [String, nil]
|
|
342
|
+
# @param key [String, nil]
|
|
343
|
+
# @param partition [Integer, nil] Optional partition to produce to
|
|
260
344
|
# @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
|
|
345
|
+
# @param timestamp [Time, Integer, nil] Optional timestamp of this message. Integer timestamp is in milliseconds since Jan 1 1970.
|
|
346
|
+
# @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
347
|
# @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
348
|
# @param topic_config [Hash] topic config for given message dispatch. Allows to send messages to topics with different configuration
|
|
349
|
+
# @param partitioner [String] name of the partitioner to use
|
|
265
350
|
#
|
|
266
351
|
# @return [DeliveryHandle] Delivery handle that can be used to wait for the result of producing this message
|
|
267
352
|
#
|
|
@@ -284,17 +369,17 @@ module Rdkafka
|
|
|
284
369
|
|
|
285
370
|
# Get payload length
|
|
286
371
|
payload_size = if payload.nil?
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
372
|
+
0
|
|
373
|
+
else
|
|
374
|
+
payload.bytesize
|
|
375
|
+
end
|
|
291
376
|
|
|
292
377
|
# Get key length
|
|
293
378
|
key_size = if key.nil?
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
379
|
+
0
|
|
380
|
+
else
|
|
381
|
+
key.bytesize
|
|
382
|
+
end
|
|
298
383
|
|
|
299
384
|
topic_config_hash = topic_config.hash
|
|
300
385
|
|
|
@@ -311,36 +396,39 @@ module Rdkafka
|
|
|
311
396
|
selected_partitioner = @topics_configs.dig(topic, topic_config_hash, :partitioner) || partitioner
|
|
312
397
|
|
|
313
398
|
# If the topic is not present, set to -1
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
399
|
+
if partition_count.positive?
|
|
400
|
+
partition = Rdkafka::Bindings.partitioner(
|
|
401
|
+
topic_ref,
|
|
402
|
+
partition_key,
|
|
403
|
+
partition_count,
|
|
404
|
+
selected_partitioner
|
|
405
|
+
)
|
|
406
|
+
end
|
|
319
407
|
end
|
|
320
408
|
|
|
321
|
-
# If partition is nil, use
|
|
409
|
+
# If partition is nil, use RD_KAFKA_PARTITION_UA to let librdafka set the partition randomly or
|
|
322
410
|
# based on the key when present.
|
|
323
|
-
partition ||=
|
|
411
|
+
partition ||= Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
324
412
|
|
|
325
413
|
# If timestamp is nil use 0 and let Kafka set one. If an integer or time
|
|
326
414
|
# use it.
|
|
327
415
|
raw_timestamp = if timestamp.nil?
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
416
|
+
0
|
|
417
|
+
elsif timestamp.is_a?(Integer)
|
|
418
|
+
timestamp
|
|
419
|
+
elsif timestamp.is_a?(Time)
|
|
420
|
+
(timestamp.to_i * 1000) + (timestamp.usec / 1000)
|
|
421
|
+
else
|
|
422
|
+
raise TypeError.new("Timestamp has to be nil, an Integer or a Time")
|
|
423
|
+
end
|
|
336
424
|
|
|
337
425
|
delivery_handle = DeliveryHandle.new
|
|
338
426
|
delivery_handle.label = label
|
|
339
427
|
delivery_handle.topic = topic
|
|
340
428
|
delivery_handle[:pending] = true
|
|
341
|
-
delivery_handle[:response] =
|
|
342
|
-
delivery_handle[:partition] =
|
|
343
|
-
delivery_handle[:offset] =
|
|
429
|
+
delivery_handle[:response] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
430
|
+
delivery_handle[:partition] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
431
|
+
delivery_handle[:offset] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
344
432
|
DeliveryHandle.register(delivery_handle)
|
|
345
433
|
|
|
346
434
|
args = [
|
|
@@ -350,29 +438,27 @@ module Rdkafka
|
|
|
350
438
|
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_KEY, :buffer_in, key, :size_t, key_size,
|
|
351
439
|
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_PARTITION, :int32, partition,
|
|
352
440
|
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_TIMESTAMP, :int64, raw_timestamp,
|
|
353
|
-
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_OPAQUE, :pointer, delivery_handle
|
|
441
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_OPAQUE, :pointer, delivery_handle
|
|
354
442
|
]
|
|
355
443
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
value = value.to_s
|
|
363
|
-
args << :int << Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER
|
|
364
|
-
args << :string << key
|
|
365
|
-
args << :pointer << value
|
|
366
|
-
args << :size_t << value.bytesize
|
|
367
|
-
end
|
|
368
|
-
else
|
|
369
|
-
# Handle single value
|
|
370
|
-
value = value0.to_s
|
|
444
|
+
headers&.each do |key0, value0|
|
|
445
|
+
key = key0.to_s
|
|
446
|
+
if value0.is_a?(Array)
|
|
447
|
+
# Handle array of values per KIP-82
|
|
448
|
+
value0.each do |value|
|
|
449
|
+
value = value.to_s
|
|
371
450
|
args << :int << Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER
|
|
372
451
|
args << :string << key
|
|
373
452
|
args << :pointer << value
|
|
374
453
|
args << :size_t << value.bytesize
|
|
375
454
|
end
|
|
455
|
+
else
|
|
456
|
+
# Handle single value
|
|
457
|
+
value = value0.to_s
|
|
458
|
+
args << :int << Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER
|
|
459
|
+
args << :string << key
|
|
460
|
+
args << :pointer << value
|
|
461
|
+
args << :size_t << value.bytesize
|
|
376
462
|
end
|
|
377
463
|
end
|
|
378
464
|
|
|
@@ -387,7 +473,7 @@ module Rdkafka
|
|
|
387
473
|
end
|
|
388
474
|
|
|
389
475
|
# Raise error if the produce call was not successful
|
|
390
|
-
if response !=
|
|
476
|
+
if response != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
391
477
|
DeliveryHandle.remove(delivery_handle.to_ptr.address)
|
|
392
478
|
raise RdkafkaError.new(response)
|
|
393
479
|
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.25.1"
|
|
6
|
+
# Target librdkafka version to be used
|
|
7
|
+
LIBRDKAFKA_VERSION = "2.12.1"
|
|
8
|
+
# SHA256 hash of the librdkafka source tarball for verification
|
|
9
|
+
LIBRDKAFKA_SOURCE_SHA256 = "ec103fa05cb0f251e375f6ea0b6112cfc9d0acd977dc5b69fdc54242ba38a16f"
|
|
7
10
|
end
|
data/lib/rdkafka.rb
CHANGED