rdkafka 0.12.0 → 0.13.0.beta.3
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/.semaphore/semaphore.yml +6 -2
- data/CHANGELOG.md +12 -0
- data/Gemfile +2 -0
- data/Rakefile +2 -0
- data/ext/Rakefile +2 -0
- data/lib/rdkafka/abstract_handle.rb +2 -0
- data/lib/rdkafka/admin/create_topic_handle.rb +2 -0
- data/lib/rdkafka/admin/create_topic_report.rb +2 -0
- data/lib/rdkafka/admin/delete_topic_handle.rb +2 -0
- data/lib/rdkafka/admin/delete_topic_report.rb +2 -0
- data/lib/rdkafka/admin.rb +40 -35
- data/lib/rdkafka/bindings.rb +22 -6
- data/lib/rdkafka/callbacks.rb +7 -1
- data/lib/rdkafka/config.rb +9 -6
- data/lib/rdkafka/consumer/headers.rb +24 -7
- data/lib/rdkafka/consumer/message.rb +3 -1
- data/lib/rdkafka/consumer/partition.rb +2 -0
- data/lib/rdkafka/consumer/topic_partition_list.rb +2 -0
- data/lib/rdkafka/consumer.rb +37 -29
- data/lib/rdkafka/error.rb +9 -0
- data/lib/rdkafka/metadata.rb +2 -0
- data/lib/rdkafka/native_kafka.rb +62 -0
- data/lib/rdkafka/producer/delivery_handle.rb +5 -2
- data/lib/rdkafka/producer/delivery_report.rb +9 -2
- data/lib/rdkafka/producer.rb +23 -10
- data/lib/rdkafka/version.rb +5 -3
- data/lib/rdkafka.rb +3 -1
- data/rdkafka.gemspec +2 -0
- data/spec/rdkafka/abstract_handle_spec.rb +2 -0
- data/spec/rdkafka/admin/create_topic_handle_spec.rb +2 -0
- data/spec/rdkafka/admin/create_topic_report_spec.rb +2 -0
- data/spec/rdkafka/admin/delete_topic_handle_spec.rb +2 -0
- data/spec/rdkafka/admin/delete_topic_report_spec.rb +2 -0
- data/spec/rdkafka/admin_spec.rb +4 -3
- data/spec/rdkafka/bindings_spec.rb +2 -0
- data/spec/rdkafka/callbacks_spec.rb +2 -0
- data/spec/rdkafka/config_spec.rb +14 -0
- data/spec/rdkafka/consumer/headers_spec.rb +62 -0
- data/spec/rdkafka/consumer/message_spec.rb +3 -1
- data/spec/rdkafka/consumer/partition_spec.rb +2 -0
- data/spec/rdkafka/consumer/topic_partition_list_spec.rb +2 -0
- data/spec/rdkafka/consumer_spec.rb +84 -15
- data/spec/rdkafka/error_spec.rb +2 -0
- data/spec/rdkafka/metadata_spec.rb +3 -1
- data/spec/rdkafka/{producer/client_spec.rb → native_kafka_spec.rb} +22 -10
- data/spec/rdkafka/producer/delivery_handle_spec.rb +5 -0
- data/spec/rdkafka/producer/delivery_report_spec.rb +8 -2
- data/spec/rdkafka/producer_spec.rb +51 -19
- data/spec/spec_helper.rb +16 -0
- metadata +13 -11
- data/lib/rdkafka/producer/client.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9db414f84847b884bded4eb7643ead52ee664256acdde47dcf7bb5e8421b5882
|
4
|
+
data.tar.gz: d696bce3413d5a591542e6bb1b7191acabd5b331e4115fb7a78b6d65320874d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd209306c840710661108a357adbeec6a24cc1aa1a828959041a0810c25b19ddbb9b52442a69c389995361c96c075a9a572b532cc6ba97c70160d99db46f5d8d
|
7
|
+
data.tar.gz: 5cb50b3717ab7904d4d8afb46233f0435cf519511755ee5137ccdf638775947f23db3ff40ac1efcd0562a767e23f5a65224e8d59f3a753b33206253f9db4dfc6
|
data/.semaphore/semaphore.yml
CHANGED
@@ -9,15 +9,19 @@ agent:
|
|
9
9
|
blocks:
|
10
10
|
- name: Run specs
|
11
11
|
task:
|
12
|
+
prologue:
|
13
|
+
commands:
|
14
|
+
- sudo apt install -y valgrind
|
12
15
|
jobs:
|
13
16
|
- name: bundle exec rspec
|
14
17
|
matrix:
|
15
18
|
- env_var: RUBY_VERSION
|
16
|
-
values: [ "2.6.
|
19
|
+
values: [ "2.6.10", "2.7.6", "3.0.4", "3.1.2"]
|
17
20
|
commands:
|
18
21
|
- sem-version ruby $RUBY_VERSION
|
19
22
|
- checkout
|
20
23
|
- bundle install --path vendor/bundle
|
21
24
|
- cd ext && bundle exec rake && cd ..
|
22
25
|
- docker-compose up -d --no-recreate
|
23
|
-
-
|
26
|
+
- ulimit -c unlimited
|
27
|
+
- valgrind -v bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
|
+
# 0.13.0
|
2
|
+
* Support cooperative sticky partition assignment in the rebalance callback (methodmissing)
|
3
|
+
* Support both string and symbol header keys (ColinDKelley)
|
4
|
+
* Handle tombstone messages properly (kgalieva)
|
5
|
+
* Add topic name to delivery report (maeve)
|
6
|
+
* Allow string partitioner config (mollyegibson)
|
7
|
+
* Fix documented type for DeliveryReport#error (jimmydo)
|
8
|
+
* Bump librdkafka to 1.9.2 (thijsc)
|
9
|
+
* Use finalizers to cleanly exit producer and admin (thijsc)
|
10
|
+
|
1
11
|
# 0.12.0
|
2
12
|
* Bumps librdkafka to 1.9.0
|
13
|
+
* Fix crash on empty partition key (mensfeld)
|
14
|
+
* Pass the delivery handle to the callback (gvisokinskas)
|
3
15
|
|
4
16
|
# 0.11.0
|
5
17
|
* Upgrade librdkafka to 1.8.2
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/ext/Rakefile
CHANGED
data/lib/rdkafka/admin.rb
CHANGED
@@ -1,33 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "objspace"
|
4
|
+
|
1
5
|
module Rdkafka
|
2
6
|
class Admin
|
3
7
|
# @private
|
4
8
|
def initialize(native_kafka)
|
5
9
|
@native_kafka = native_kafka
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
if @closing && Rdkafka::Bindings.rd_kafka_outq_len(@native_kafka) == 0
|
14
|
-
break
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
@polling_thread.abort_on_exception = true
|
10
|
+
|
11
|
+
# Makes sure, that native kafka gets closed before it gets GCed by Ruby
|
12
|
+
ObjectSpace.define_finalizer(self, native_kafka.finalizer)
|
13
|
+
end
|
14
|
+
|
15
|
+
def finalizer
|
16
|
+
->(_) { close }
|
19
17
|
end
|
20
18
|
|
21
19
|
# Close this admin instance
|
22
20
|
def close
|
23
|
-
return
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@native_kafka
|
21
|
+
return if closed?
|
22
|
+
ObjectSpace.undefine_finalizer(self)
|
23
|
+
@native_kafka.close
|
24
|
+
end
|
25
|
+
|
26
|
+
# Whether this admin has closed
|
27
|
+
def closed?
|
28
|
+
@native_kafka.closed?
|
31
29
|
end
|
32
30
|
|
33
31
|
# Create a topic with the given partition count and replication factor
|
@@ -38,6 +36,7 @@ module Rdkafka
|
|
38
36
|
#
|
39
37
|
# @return [CreateTopicHandle] Create topic handle that can be used to wait for the result of creating the topic
|
40
38
|
def create_topic(topic_name, partition_count, replication_factor, topic_config={})
|
39
|
+
closed_admin_check(__method__)
|
41
40
|
|
42
41
|
# Create a rd_kafka_NewTopic_t representing the new topic
|
43
42
|
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
@@ -68,7 +67,7 @@ module Rdkafka
|
|
68
67
|
topics_array_ptr.write_array_of_pointer(pointer_array)
|
69
68
|
|
70
69
|
# Get a pointer to the queue that our request will be enqueued on
|
71
|
-
queue_ptr = Rdkafka::Bindings.rd_kafka_queue_get_background(@native_kafka)
|
70
|
+
queue_ptr = Rdkafka::Bindings.rd_kafka_queue_get_background(@native_kafka.inner)
|
72
71
|
if queue_ptr.null?
|
73
72
|
Rdkafka::Bindings.rd_kafka_NewTopic_destroy(new_topic_ptr)
|
74
73
|
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
@@ -79,16 +78,16 @@ module Rdkafka
|
|
79
78
|
create_topic_handle[:pending] = true
|
80
79
|
create_topic_handle[:response] = -1
|
81
80
|
CreateTopicHandle.register(create_topic_handle)
|
82
|
-
admin_options_ptr = Rdkafka::Bindings.rd_kafka_AdminOptions_new(@native_kafka, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATETOPICS)
|
81
|
+
admin_options_ptr = Rdkafka::Bindings.rd_kafka_AdminOptions_new(@native_kafka.inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATETOPICS)
|
83
82
|
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, create_topic_handle.to_ptr)
|
84
83
|
|
85
84
|
begin
|
86
85
|
Rdkafka::Bindings.rd_kafka_CreateTopics(
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
@native_kafka.inner,
|
87
|
+
topics_array_ptr,
|
88
|
+
1,
|
89
|
+
admin_options_ptr,
|
90
|
+
queue_ptr
|
92
91
|
)
|
93
92
|
rescue Exception
|
94
93
|
CreateTopicHandle.remove(create_topic_handle.to_ptr.address)
|
@@ -108,6 +107,7 @@ module Rdkafka
|
|
108
107
|
#
|
109
108
|
# @return [DeleteTopicHandle] Delete topic handle that can be used to wait for the result of deleting the topic
|
110
109
|
def delete_topic(topic_name)
|
110
|
+
closed_admin_check(__method__)
|
111
111
|
|
112
112
|
# Create a rd_kafka_DeleteTopic_t representing the topic to be deleted
|
113
113
|
delete_topic_ptr = Rdkafka::Bindings.rd_kafka_DeleteTopic_new(FFI::MemoryPointer.from_string(topic_name))
|
@@ -118,7 +118,7 @@ module Rdkafka
|
|
118
118
|
topics_array_ptr.write_array_of_pointer(pointer_array)
|
119
119
|
|
120
120
|
# Get a pointer to the queue that our request will be enqueued on
|
121
|
-
queue_ptr = Rdkafka::Bindings.rd_kafka_queue_get_background(@native_kafka)
|
121
|
+
queue_ptr = Rdkafka::Bindings.rd_kafka_queue_get_background(@native_kafka.inner)
|
122
122
|
if queue_ptr.null?
|
123
123
|
Rdkafka::Bindings.rd_kafka_DeleteTopic_destroy(delete_topic_ptr)
|
124
124
|
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
@@ -129,16 +129,16 @@ module Rdkafka
|
|
129
129
|
delete_topic_handle[:pending] = true
|
130
130
|
delete_topic_handle[:response] = -1
|
131
131
|
DeleteTopicHandle.register(delete_topic_handle)
|
132
|
-
admin_options_ptr = Rdkafka::Bindings.rd_kafka_AdminOptions_new(@native_kafka, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DELETETOPICS)
|
132
|
+
admin_options_ptr = Rdkafka::Bindings.rd_kafka_AdminOptions_new(@native_kafka.inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DELETETOPICS)
|
133
133
|
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, delete_topic_handle.to_ptr)
|
134
134
|
|
135
135
|
begin
|
136
136
|
Rdkafka::Bindings.rd_kafka_DeleteTopics(
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
137
|
+
@native_kafka.inner,
|
138
|
+
topics_array_ptr,
|
139
|
+
1,
|
140
|
+
admin_options_ptr,
|
141
|
+
queue_ptr
|
142
142
|
)
|
143
143
|
rescue Exception
|
144
144
|
DeleteTopicHandle.remove(delete_topic_handle.to_ptr.address)
|
@@ -151,5 +151,10 @@ module Rdkafka
|
|
151
151
|
|
152
152
|
delete_topic_handle
|
153
153
|
end
|
154
|
+
|
155
|
+
private
|
156
|
+
def closed_admin_check(method)
|
157
|
+
raise Rdkafka::ClosedAdminError.new(method) if closed?
|
158
|
+
end
|
154
159
|
end
|
155
160
|
end
|
data/lib/rdkafka/bindings.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "ffi"
|
2
4
|
require "json"
|
3
5
|
require "logger"
|
@@ -15,7 +17,7 @@ module Rdkafka
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
ffi_lib File.join(
|
20
|
+
ffi_lib File.join(__dir__, "../../ext/librdkafka.#{lib_extension}")
|
19
21
|
|
20
22
|
RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS = -175
|
21
23
|
RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS = -174
|
@@ -33,6 +35,7 @@ module Rdkafka
|
|
33
35
|
|
34
36
|
# Polling
|
35
37
|
|
38
|
+
attach_function :rd_kafka_flush, [:pointer, :int], :void, blocking: true
|
36
39
|
attach_function :rd_kafka_poll, [:pointer, :int], :void, blocking: true
|
37
40
|
attach_function :rd_kafka_outq_len, [:pointer], :int, blocking: true
|
38
41
|
|
@@ -110,6 +113,7 @@ module Rdkafka
|
|
110
113
|
attach_function :rd_kafka_conf_set_stats_cb, [:pointer, :stats_cb], :void
|
111
114
|
callback :error_cb, [:pointer, :int, :string, :pointer], :void
|
112
115
|
attach_function :rd_kafka_conf_set_error_cb, [:pointer, :error_cb], :void
|
116
|
+
attach_function :rd_kafka_rebalance_protocol, [:pointer], :string
|
113
117
|
|
114
118
|
# Log queue
|
115
119
|
attach_function :rd_kafka_set_log_queue, [:pointer, :pointer], :void
|
@@ -165,7 +169,9 @@ module Rdkafka
|
|
165
169
|
]
|
166
170
|
|
167
171
|
attach_function :rd_kafka_new, [:kafka_type, :pointer, :pointer, :int], :pointer
|
168
|
-
|
172
|
+
|
173
|
+
RD_KAFKA_DESTROY_F_IMMEDIATE = 0x4
|
174
|
+
attach_function :rd_kafka_destroy_flags, [:pointer, :int], :void
|
169
175
|
|
170
176
|
# Consumer
|
171
177
|
|
@@ -173,6 +179,8 @@ module Rdkafka
|
|
173
179
|
attach_function :rd_kafka_unsubscribe, [:pointer], :int
|
174
180
|
attach_function :rd_kafka_subscription, [:pointer, :pointer], :int
|
175
181
|
attach_function :rd_kafka_assign, [:pointer, :pointer], :int
|
182
|
+
attach_function :rd_kafka_incremental_assign, [:pointer, :pointer], :int
|
183
|
+
attach_function :rd_kafka_incremental_unassign, [:pointer, :pointer], :int
|
176
184
|
attach_function :rd_kafka_assignment, [:pointer, :pointer], :int
|
177
185
|
attach_function :rd_kafka_committed, [:pointer, :pointer, :int], :int
|
178
186
|
attach_function :rd_kafka_commit, [:pointer, :pointer, :bool], :int, blocking: true
|
@@ -198,9 +206,17 @@ module Rdkafka
|
|
198
206
|
) do |client_ptr, code, partitions_ptr, opaque_ptr|
|
199
207
|
case code
|
200
208
|
when RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
201
|
-
Rdkafka::Bindings.
|
209
|
+
if Rdkafka::Bindings.rd_kafka_rebalance_protocol(client_ptr) == "COOPERATIVE"
|
210
|
+
Rdkafka::Bindings.rd_kafka_incremental_assign(client_ptr, partitions_ptr)
|
211
|
+
else
|
212
|
+
Rdkafka::Bindings.rd_kafka_assign(client_ptr, partitions_ptr)
|
213
|
+
end
|
202
214
|
else # RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS or errors
|
203
|
-
Rdkafka::Bindings.
|
215
|
+
if Rdkafka::Bindings.rd_kafka_rebalance_protocol(client_ptr) == "COOPERATIVE"
|
216
|
+
Rdkafka::Bindings.rd_kafka_incremental_unassign(client_ptr, partitions_ptr)
|
217
|
+
else
|
218
|
+
Rdkafka::Bindings.rd_kafka_assign(client_ptr, FFI::Pointer::NULL)
|
219
|
+
end
|
204
220
|
end
|
205
221
|
|
206
222
|
opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
@@ -256,11 +272,11 @@ module Rdkafka
|
|
256
272
|
# Return RD_KAFKA_PARTITION_UA(unassigned partition) when partition count is nil/zero.
|
257
273
|
return -1 unless partition_count&.nonzero?
|
258
274
|
|
259
|
-
str_ptr = FFI::MemoryPointer.from_string(str)
|
275
|
+
str_ptr = str.empty? ? FFI::MemoryPointer::NULL : FFI::MemoryPointer.from_string(str)
|
260
276
|
method_name = PARTITIONERS.fetch(partitioner_name) do
|
261
277
|
raise Rdkafka::Config::ConfigError.new("Unknown partitioner: #{partitioner_name}")
|
262
278
|
end
|
263
|
-
public_send(method_name, nil, str_ptr, str.size, partition_count, nil, nil)
|
279
|
+
public_send(method_name, nil, str_ptr, str.size > 0 ? str.size : 1, partition_count, nil, nil)
|
264
280
|
end
|
265
281
|
|
266
282
|
# Create Topics
|
data/lib/rdkafka/callbacks.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rdkafka
|
2
4
|
module Callbacks
|
3
5
|
|
@@ -90,14 +92,18 @@ module Rdkafka
|
|
90
92
|
message = Rdkafka::Bindings::Message.new(message_ptr)
|
91
93
|
delivery_handle_ptr_address = message[:_private].address
|
92
94
|
if delivery_handle = Rdkafka::Producer::DeliveryHandle.remove(delivery_handle_ptr_address)
|
95
|
+
topic_name = Rdkafka::Bindings.rd_kafka_topic_name(message[:rkt])
|
96
|
+
|
93
97
|
# Update delivery handle
|
94
98
|
delivery_handle[:response] = message[:err]
|
95
99
|
delivery_handle[:partition] = message[:partition]
|
96
100
|
delivery_handle[:offset] = message[:offset]
|
101
|
+
delivery_handle[:topic_name] = FFI::MemoryPointer.from_string(topic_name)
|
97
102
|
delivery_handle[:pending] = false
|
103
|
+
|
98
104
|
# Call delivery callback on opaque
|
99
105
|
if opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
100
|
-
opaque.call_delivery_callback(Rdkafka::Producer::DeliveryReport.new(message[:partition], message[:offset], message[:err]), delivery_handle)
|
106
|
+
opaque.call_delivery_callback(Rdkafka::Producer::DeliveryReport.new(message[:partition], message[:offset], topic_name, message[:err]), delivery_handle)
|
101
107
|
end
|
102
108
|
end
|
103
109
|
end
|
data/lib/rdkafka/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "logger"
|
2
4
|
|
3
5
|
module Rdkafka
|
@@ -30,7 +32,6 @@ module Rdkafka
|
|
30
32
|
@@logger
|
31
33
|
end
|
32
34
|
|
33
|
-
|
34
35
|
# Returns a queue whose contents will be passed to the configured logger. Each entry
|
35
36
|
# should follow the format [Logger::Severity, String]. The benefit over calling the
|
36
37
|
# logger directly is that this is safe to use from trap contexts.
|
@@ -47,7 +48,7 @@ module Rdkafka
|
|
47
48
|
# @return [nil]
|
48
49
|
def self.logger=(logger)
|
49
50
|
raise NoLoggerError if logger.nil?
|
50
|
-
@@logger=logger
|
51
|
+
@@logger = logger
|
51
52
|
end
|
52
53
|
|
53
54
|
# Set a callback that will be called every time the underlying client emits statistics.
|
@@ -156,13 +157,14 @@ module Rdkafka
|
|
156
157
|
Rdkafka::Bindings.rd_kafka_conf_set_rebalance_cb(config, Rdkafka::Bindings::RebalanceCallback)
|
157
158
|
end
|
158
159
|
|
160
|
+
# Create native client
|
159
161
|
kafka = native_kafka(config, :rd_kafka_consumer)
|
160
162
|
|
161
163
|
# Redirect the main queue to the consumer
|
162
164
|
Rdkafka::Bindings.rd_kafka_poll_set_consumer(kafka)
|
163
165
|
|
164
166
|
# Return consumer with Kafka client
|
165
|
-
Rdkafka::Consumer.new(kafka)
|
167
|
+
Rdkafka::Consumer.new(Rdkafka::NativeKafka.new(kafka, run_polling_thread: false))
|
166
168
|
end
|
167
169
|
|
168
170
|
# Create a producer with this configuration.
|
@@ -179,7 +181,8 @@ module Rdkafka
|
|
179
181
|
# Set callback to receive delivery reports on config
|
180
182
|
Rdkafka::Bindings.rd_kafka_conf_set_dr_msg_cb(config, Rdkafka::Callbacks::DeliveryCallbackFunction)
|
181
183
|
# Return producer with Kafka client
|
182
|
-
|
184
|
+
partitioner_name = self[:partitioner] || self["partitioner"]
|
185
|
+
Rdkafka::Producer.new(Rdkafka::NativeKafka.new(native_kafka(config, :rd_kafka_producer), run_polling_thread: true), partitioner_name).tap do |producer|
|
183
186
|
opaque.producer = producer
|
184
187
|
end
|
185
188
|
end
|
@@ -194,7 +197,7 @@ module Rdkafka
|
|
194
197
|
opaque = Opaque.new
|
195
198
|
config = native_config(opaque)
|
196
199
|
Rdkafka::Bindings.rd_kafka_conf_set_background_event_cb(config, Rdkafka::Callbacks::BackgroundEventCallbackFunction)
|
197
|
-
Rdkafka::Admin.new(native_kafka(config, :rd_kafka_producer))
|
200
|
+
Rdkafka::Admin.new(Rdkafka::NativeKafka.new(native_kafka(config, :rd_kafka_producer), run_polling_thread: true))
|
198
201
|
end
|
199
202
|
|
200
203
|
# Error that is returned by the underlying rdkafka error if an invalid configuration option is present.
|
@@ -210,7 +213,7 @@ module Rdkafka
|
|
210
213
|
|
211
214
|
# This method is only intended to be used to create a client,
|
212
215
|
# using it in another way will leak memory.
|
213
|
-
def native_config(opaque=nil)
|
216
|
+
def native_config(opaque = nil)
|
214
217
|
Rdkafka::Bindings.rd_kafka_conf_new.tap do |config|
|
215
218
|
# Create config
|
216
219
|
@config_hash.merge(REQUIRED_CONFIG).each do |key, value|
|
@@ -1,10 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rdkafka
|
2
4
|
class Consumer
|
3
|
-
#
|
4
|
-
|
5
|
-
|
5
|
+
# Interface to return headers for a consumer message
|
6
|
+
module Headers
|
7
|
+
class HashWithSymbolKeysTreatedLikeStrings < Hash
|
8
|
+
def [](key)
|
9
|
+
if key.is_a?(Symbol)
|
10
|
+
Kernel.warn("rdkafka deprecation warning: header access with Symbol key #{key.inspect} treated as a String. " \
|
11
|
+
"Please change your code to use String keys to avoid this warning. Symbol keys will break in version 1.")
|
12
|
+
super(key.to_s)
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Reads a librdkafka native message's headers and returns them as a Ruby Hash
|
20
|
+
#
|
21
|
+
# @param [librdkakfa message] native_message
|
6
22
|
#
|
7
|
-
# @return [Hash<String, String>]
|
23
|
+
# @return [Hash<String, String>] headers Hash for the native_message
|
8
24
|
#
|
9
25
|
# @raise [Rdkafka::RdkafkaError] when fail to read headers
|
10
26
|
#
|
@@ -24,7 +40,8 @@ module Rdkafka
|
|
24
40
|
name_ptrptr = FFI::MemoryPointer.new(:pointer)
|
25
41
|
value_ptrptr = FFI::MemoryPointer.new(:pointer)
|
26
42
|
size_ptr = Rdkafka::Bindings::SizePtr.new
|
27
|
-
|
43
|
+
|
44
|
+
headers = HashWithSymbolKeysTreatedLikeStrings.new
|
28
45
|
|
29
46
|
idx = 0
|
30
47
|
loop do
|
@@ -51,12 +68,12 @@ module Rdkafka
|
|
51
68
|
|
52
69
|
value = value_ptr.read_string(size)
|
53
70
|
|
54
|
-
headers[name
|
71
|
+
headers[name] = value
|
55
72
|
|
56
73
|
idx += 1
|
57
74
|
end
|
58
75
|
|
59
|
-
headers
|
76
|
+
headers.freeze
|
60
77
|
end
|
61
78
|
end
|
62
79
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rdkafka
|
2
4
|
class Consumer
|
3
5
|
# A message that was consumed from a topic.
|
@@ -18,7 +20,7 @@ module Rdkafka
|
|
18
20
|
# @return [String, nil]
|
19
21
|
attr_reader :key
|
20
22
|
|
21
|
-
# This message's offset in
|
23
|
+
# This message's offset in its partition
|
22
24
|
# @return [Integer]
|
23
25
|
attr_reader :offset
|
24
26
|
|