rdkafka 0.13.0 → 0.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +57 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +155 -111
- data/{LICENSE → MIT-LICENSE} +2 -1
- data/README.md +60 -39
- data/certs/cert_chain.pem +26 -0
- data/docker-compose.yml +18 -15
- data/ext/README.md +1 -1
- data/ext/Rakefile +43 -26
- data/lib/rdkafka/abstract_handle.rb +40 -26
- data/lib/rdkafka/admin/acl_binding_result.rb +51 -0
- data/lib/rdkafka/admin/create_acl_handle.rb +28 -0
- data/lib/rdkafka/admin/create_acl_report.rb +24 -0
- data/lib/rdkafka/admin/create_partitions_handle.rb +27 -0
- data/lib/rdkafka/admin/create_partitions_report.rb +6 -0
- data/lib/rdkafka/admin/delete_acl_handle.rb +30 -0
- data/lib/rdkafka/admin/delete_acl_report.rb +23 -0
- data/lib/rdkafka/admin/delete_groups_handle.rb +28 -0
- data/lib/rdkafka/admin/delete_groups_report.rb +24 -0
- data/lib/rdkafka/admin/describe_acl_handle.rb +30 -0
- data/lib/rdkafka/admin/describe_acl_report.rb +23 -0
- data/lib/rdkafka/admin.rb +449 -7
- data/lib/rdkafka/bindings.rb +133 -7
- data/lib/rdkafka/callbacks.rb +196 -1
- data/lib/rdkafka/config.rb +53 -19
- data/lib/rdkafka/consumer/headers.rb +2 -4
- data/lib/rdkafka/consumer/topic_partition_list.rb +11 -8
- data/lib/rdkafka/consumer.rb +164 -74
- data/lib/rdkafka/helpers/time.rb +14 -0
- data/lib/rdkafka/metadata.rb +22 -1
- data/lib/rdkafka/native_kafka.rb +6 -1
- data/lib/rdkafka/producer/delivery_handle.rb +12 -1
- data/lib/rdkafka/producer/delivery_report.rb +16 -3
- data/lib/rdkafka/producer.rb +121 -13
- data/lib/rdkafka/version.rb +3 -3
- data/lib/rdkafka.rb +21 -1
- data/rdkafka.gemspec +19 -5
- data/renovate.json +6 -0
- data/spec/rdkafka/abstract_handle_spec.rb +0 -2
- data/spec/rdkafka/admin/create_acl_handle_spec.rb +56 -0
- data/spec/rdkafka/admin/create_acl_report_spec.rb +18 -0
- data/spec/rdkafka/admin/create_topic_handle_spec.rb +0 -2
- data/spec/rdkafka/admin/create_topic_report_spec.rb +0 -2
- data/spec/rdkafka/admin/delete_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/delete_acl_report_spec.rb +72 -0
- data/spec/rdkafka/admin/delete_topic_handle_spec.rb +0 -2
- data/spec/rdkafka/admin/delete_topic_report_spec.rb +0 -2
- data/spec/rdkafka/admin/describe_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/describe_acl_report_spec.rb +73 -0
- data/spec/rdkafka/admin_spec.rb +205 -2
- data/spec/rdkafka/bindings_spec.rb +0 -1
- data/spec/rdkafka/callbacks_spec.rb +0 -2
- data/spec/rdkafka/config_spec.rb +8 -2
- data/spec/rdkafka/consumer/headers_spec.rb +0 -2
- data/spec/rdkafka/consumer/message_spec.rb +0 -2
- data/spec/rdkafka/consumer/partition_spec.rb +0 -2
- data/spec/rdkafka/consumer/topic_partition_list_spec.rb +19 -2
- data/spec/rdkafka/consumer_spec.rb +232 -39
- data/spec/rdkafka/error_spec.rb +0 -2
- data/spec/rdkafka/metadata_spec.rb +2 -3
- data/spec/rdkafka/native_kafka_spec.rb +2 -3
- data/spec/rdkafka/producer/delivery_handle_spec.rb +0 -2
- data/spec/rdkafka/producer/delivery_report_spec.rb +4 -2
- data/spec/rdkafka/producer_spec.rb +183 -3
- data/spec/spec_helper.rb +3 -1
- data.tar.gz.sig +0 -0
- metadata +78 -14
- metadata.gz.sig +0 -0
- data/.semaphore/semaphore.yml +0 -27
data/lib/rdkafka/callbacks.rb
CHANGED
@@ -23,6 +23,96 @@ module Rdkafka
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
class GroupResult
|
27
|
+
attr_reader :result_error, :error_string, :result_name
|
28
|
+
def initialize(group_result_pointer)
|
29
|
+
native_error = Rdkafka::Bindings.rd_kafka_group_result_error(group_result_pointer)
|
30
|
+
|
31
|
+
if native_error.null?
|
32
|
+
@result_error = 0
|
33
|
+
@error_string = FFI::Pointer::NULL
|
34
|
+
else
|
35
|
+
@result_error = native_error[:code]
|
36
|
+
@error_string = native_error[:errstr]
|
37
|
+
end
|
38
|
+
|
39
|
+
@result_name = Rdkafka::Bindings.rd_kafka_group_result_name(group_result_pointer)
|
40
|
+
end
|
41
|
+
def self.create_group_results_from_array(count, array_pointer)
|
42
|
+
(1..count).map do |index|
|
43
|
+
result_pointer = (array_pointer + (index - 1)).read_pointer
|
44
|
+
new(result_pointer)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Extracts attributes of rd_kafka_acl_result_t
|
50
|
+
#
|
51
|
+
# @private
|
52
|
+
class CreateAclResult
|
53
|
+
attr_reader :result_error, :error_string
|
54
|
+
|
55
|
+
def initialize(acl_result_pointer)
|
56
|
+
rd_kafka_error_pointer = Bindings.rd_kafka_acl_result_error(acl_result_pointer)
|
57
|
+
@result_error = Rdkafka::Bindings.rd_kafka_error_code(rd_kafka_error_pointer)
|
58
|
+
@error_string = Rdkafka::Bindings.rd_kafka_error_string(rd_kafka_error_pointer)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.create_acl_results_from_array(count, array_pointer)
|
62
|
+
(1..count).map do |index|
|
63
|
+
result_pointer = (array_pointer + (index - 1)).read_pointer
|
64
|
+
new(result_pointer)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Extracts attributes of rd_kafka_DeleteAcls_result_response_t
|
70
|
+
#
|
71
|
+
# @private
|
72
|
+
class DeleteAclResult
|
73
|
+
attr_reader :result_error, :error_string, :matching_acls, :matching_acls_count
|
74
|
+
|
75
|
+
def initialize(acl_result_pointer)
|
76
|
+
@matching_acls=[]
|
77
|
+
rd_kafka_error_pointer = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_response_error(acl_result_pointer)
|
78
|
+
@result_error = Rdkafka::Bindings.rd_kafka_error_code(rd_kafka_error_pointer)
|
79
|
+
@error_string = Rdkafka::Bindings.rd_kafka_error_string(rd_kafka_error_pointer)
|
80
|
+
if @result_error == 0
|
81
|
+
# Get the number of matching acls
|
82
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
83
|
+
@matching_acls = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_response_matching_acls(acl_result_pointer, pointer_to_size_t)
|
84
|
+
@matching_acls_count = pointer_to_size_t.read_int
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.delete_acl_results_from_array(count, array_pointer)
|
89
|
+
(1..count).map do |index|
|
90
|
+
result_pointer = (array_pointer + (index - 1)).read_pointer
|
91
|
+
new(result_pointer)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Extracts attributes of rd_kafka_DeleteAcls_result_response_t
|
97
|
+
#
|
98
|
+
# @private
|
99
|
+
class DescribeAclResult
|
100
|
+
attr_reader :result_error, :error_string, :matching_acls, :matching_acls_count
|
101
|
+
|
102
|
+
def initialize(event_ptr)
|
103
|
+
@matching_acls=[]
|
104
|
+
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
105
|
+
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
106
|
+
if @result_error == 0
|
107
|
+
acl_describe_result = Rdkafka::Bindings.rd_kafka_event_DescribeAcls_result(event_ptr)
|
108
|
+
# Get the number of matching acls
|
109
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
110
|
+
@matching_acls = Rdkafka::Bindings.rd_kafka_DescribeAcls_result_acls(acl_describe_result, pointer_to_size_t)
|
111
|
+
@matching_acls_count = pointer_to_size_t.read_int
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
26
116
|
# FFI Function used for Create Topic and Delete Topic callbacks
|
27
117
|
BackgroundEventCallbackFunction = FFI::Function.new(
|
28
118
|
:void, [:pointer, :pointer, :pointer]
|
@@ -38,6 +128,16 @@ module Rdkafka
|
|
38
128
|
process_create_topic(event_ptr)
|
39
129
|
elsif event_type == Rdkafka::Bindings::RD_KAFKA_EVENT_DELETETOPICS_RESULT
|
40
130
|
process_delete_topic(event_ptr)
|
131
|
+
elsif event_type == Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATEPARTITIONS_RESULT
|
132
|
+
process_create_partitions(event_ptr)
|
133
|
+
elsif event_type == Rdkafka::Bindings::RD_KAFKA_EVENT_CREATEACLS_RESULT
|
134
|
+
process_create_acl(event_ptr)
|
135
|
+
elsif event_type == Rdkafka::Bindings::RD_KAFKA_EVENT_DELETEACLS_RESULT
|
136
|
+
process_delete_acl(event_ptr)
|
137
|
+
elsif event_type == Rdkafka::Bindings::RD_KAFKA_EVENT_DESCRIBEACLS_RESULT
|
138
|
+
process_describe_acl(event_ptr)
|
139
|
+
elsif event_type == Rdkafka::Bindings::RD_KAFKA_EVENT_DELETEGROUPS_RESULT
|
140
|
+
process_delete_groups(event_ptr)
|
41
141
|
end
|
42
142
|
end
|
43
143
|
|
@@ -60,6 +160,23 @@ module Rdkafka
|
|
60
160
|
end
|
61
161
|
end
|
62
162
|
|
163
|
+
def self.process_delete_groups(event_ptr)
|
164
|
+
delete_groups_result = Rdkafka::Bindings.rd_kafka_event_DeleteGroups_result(event_ptr)
|
165
|
+
|
166
|
+
# Get the number of delete group results
|
167
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
|
168
|
+
delete_group_result_array = Rdkafka::Bindings.rd_kafka_DeleteGroups_result_groups(delete_groups_result, pointer_to_size_t)
|
169
|
+
delete_group_results = GroupResult.create_group_results_from_array(pointer_to_size_t.read_int, delete_group_result_array) # TODO fix this
|
170
|
+
delete_group_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
171
|
+
|
172
|
+
if (delete_group_handle = Rdkafka::Admin::DeleteGroupsHandle.remove(delete_group_handle_ptr.address))
|
173
|
+
delete_group_handle[:response] = delete_group_results[0].result_error
|
174
|
+
delete_group_handle[:error_string] = delete_group_results[0].error_string
|
175
|
+
delete_group_handle[:result_name] = delete_group_results[0].result_name
|
176
|
+
delete_group_handle[:pending] = false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
63
180
|
def self.process_delete_topic(event_ptr)
|
64
181
|
delete_topics_result = Rdkafka::Bindings.rd_kafka_event_DeleteTopics_result(event_ptr)
|
65
182
|
|
@@ -76,6 +193,74 @@ module Rdkafka
|
|
76
193
|
delete_topic_handle[:pending] = false
|
77
194
|
end
|
78
195
|
end
|
196
|
+
|
197
|
+
def self.process_create_partitions(event_ptr)
|
198
|
+
create_partitionss_result = Rdkafka::Bindings.rd_kafka_event_CreatePartitions_result(event_ptr)
|
199
|
+
|
200
|
+
# Get the number of create topic results
|
201
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
202
|
+
create_partitions_result_array = Rdkafka::Bindings.rd_kafka_CreatePartitions_result_topics(create_partitionss_result, pointer_to_size_t)
|
203
|
+
create_partitions_results = TopicResult.create_topic_results_from_array(pointer_to_size_t.read_int, create_partitions_result_array)
|
204
|
+
create_partitions_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
205
|
+
|
206
|
+
if create_partitions_handle = Rdkafka::Admin::CreatePartitionsHandle.remove(create_partitions_handle_ptr.address)
|
207
|
+
create_partitions_handle[:response] = create_partitions_results[0].result_error
|
208
|
+
create_partitions_handle[:error_string] = create_partitions_results[0].error_string
|
209
|
+
create_partitions_handle[:result_name] = create_partitions_results[0].result_name
|
210
|
+
create_partitions_handle[:pending] = false
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def self.process_create_acl(event_ptr)
|
215
|
+
create_acls_result = Rdkafka::Bindings.rd_kafka_event_CreateAcls_result(event_ptr)
|
216
|
+
|
217
|
+
# Get the number of acl results
|
218
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
219
|
+
create_acl_result_array = Rdkafka::Bindings.rd_kafka_CreateAcls_result_acls(create_acls_result, pointer_to_size_t)
|
220
|
+
create_acl_results = CreateAclResult.create_acl_results_from_array(pointer_to_size_t.read_int, create_acl_result_array)
|
221
|
+
create_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
222
|
+
|
223
|
+
if create_acl_handle = Rdkafka::Admin::CreateAclHandle.remove(create_acl_handle_ptr.address)
|
224
|
+
create_acl_handle[:response] = create_acl_results[0].result_error
|
225
|
+
create_acl_handle[:response_string] = create_acl_results[0].error_string
|
226
|
+
create_acl_handle[:pending] = false
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.process_delete_acl(event_ptr)
|
231
|
+
delete_acls_result = Rdkafka::Bindings.rd_kafka_event_DeleteAcls_result(event_ptr)
|
232
|
+
|
233
|
+
# Get the number of acl results
|
234
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
235
|
+
delete_acl_result_responses = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_responses(delete_acls_result, pointer_to_size_t)
|
236
|
+
delete_acl_results = DeleteAclResult.delete_acl_results_from_array(pointer_to_size_t.read_int, delete_acl_result_responses)
|
237
|
+
delete_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
238
|
+
|
239
|
+
if delete_acl_handle = Rdkafka::Admin::DeleteAclHandle.remove(delete_acl_handle_ptr.address)
|
240
|
+
delete_acl_handle[:response] = delete_acl_results[0].result_error
|
241
|
+
delete_acl_handle[:response_string] = delete_acl_results[0].error_string
|
242
|
+
delete_acl_handle[:pending] = false
|
243
|
+
if delete_acl_results[0].result_error == 0
|
244
|
+
delete_acl_handle[:matching_acls] = delete_acl_results[0].matching_acls
|
245
|
+
delete_acl_handle[:matching_acls_count] = delete_acl_results[0].matching_acls_count
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.process_describe_acl(event_ptr)
|
251
|
+
describe_acl = DescribeAclResult.new(event_ptr)
|
252
|
+
describe_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
253
|
+
|
254
|
+
if describe_acl_handle = Rdkafka::Admin::DescribeAclHandle.remove(describe_acl_handle_ptr.address)
|
255
|
+
describe_acl_handle[:response] = describe_acl.result_error
|
256
|
+
describe_acl_handle[:response_string] = describe_acl.error_string
|
257
|
+
describe_acl_handle[:pending] = false
|
258
|
+
if describe_acl.result_error == 0
|
259
|
+
describe_acl_handle[:acls] = describe_acl.matching_acls
|
260
|
+
describe_acl_handle[:acls_count] = describe_acl.matching_acls_count
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
79
264
|
end
|
80
265
|
|
81
266
|
# FFI Function used for Message Delivery callbacks
|
@@ -103,10 +288,20 @@ module Rdkafka
|
|
103
288
|
|
104
289
|
# Call delivery callback on opaque
|
105
290
|
if opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
106
|
-
opaque.call_delivery_callback(
|
291
|
+
opaque.call_delivery_callback(
|
292
|
+
Rdkafka::Producer::DeliveryReport.new(
|
293
|
+
message[:partition],
|
294
|
+
message[:offset],
|
295
|
+
topic_name,
|
296
|
+
message[:err],
|
297
|
+
delivery_handle.label
|
298
|
+
),
|
299
|
+
delivery_handle
|
300
|
+
)
|
107
301
|
end
|
108
302
|
end
|
109
303
|
end
|
110
304
|
end
|
305
|
+
|
111
306
|
end
|
112
307
|
end
|
data/lib/rdkafka/config.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "logger"
|
4
|
-
|
5
3
|
module Rdkafka
|
6
4
|
# Configuration for a Kafka consumer or producer. You can create an instance and use
|
7
5
|
# the consumer and producer methods to create a client. Documentation of the available
|
8
|
-
# configuration options is available on https://github.com/
|
6
|
+
# configuration options is available on https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md.
|
9
7
|
class Config
|
10
8
|
# @private
|
11
9
|
@@logger = Logger.new(STDOUT)
|
@@ -14,7 +12,7 @@ module Rdkafka
|
|
14
12
|
# @private
|
15
13
|
@@error_callback = nil
|
16
14
|
# @private
|
17
|
-
@@opaques =
|
15
|
+
@@opaques = ObjectSpace::WeakMap.new
|
18
16
|
# @private
|
19
17
|
@@log_queue = Queue.new
|
20
18
|
|
@@ -53,13 +51,13 @@ module Rdkafka
|
|
53
51
|
|
54
52
|
# Set a callback that will be called every time the underlying client emits statistics.
|
55
53
|
# You can configure if and how often this happens using `statistics.interval.ms`.
|
56
|
-
# The callback is called with a hash that's documented here: https://github.com/
|
54
|
+
# The callback is called with a hash that's documented here: https://github.com/confluentinc/librdkafka/blob/master/STATISTICS.md
|
57
55
|
#
|
58
56
|
# @param callback [Proc, #call] The callback
|
59
57
|
#
|
60
58
|
# @return [nil]
|
61
59
|
def self.statistics_callback=(callback)
|
62
|
-
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call)
|
60
|
+
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback == nil
|
63
61
|
@@statistics_callback = callback
|
64
62
|
end
|
65
63
|
|
@@ -114,6 +112,7 @@ module Rdkafka
|
|
114
112
|
def initialize(config_hash = {})
|
115
113
|
@config_hash = DEFAULT_CONFIG.merge(config_hash)
|
116
114
|
@consumer_rebalance_listener = nil
|
115
|
+
@consumer_poll_set = true
|
117
116
|
end
|
118
117
|
|
119
118
|
# Set a config option.
|
@@ -142,12 +141,28 @@ module Rdkafka
|
|
142
141
|
@consumer_rebalance_listener = listener
|
143
142
|
end
|
144
143
|
|
145
|
-
#
|
144
|
+
# Should we use a single queue for the underlying consumer and events.
|
146
145
|
#
|
147
|
-
#
|
148
|
-
#
|
146
|
+
# This is an advanced API that allows for more granular control of the polling process.
|
147
|
+
# When this value is set to `false` (`true` by defualt), there will be two queues that need to
|
148
|
+
# be polled:
|
149
|
+
# - main librdkafka queue for events
|
150
|
+
# - consumer queue with messages and rebalances
|
151
|
+
#
|
152
|
+
# It is recommended to use the defaults and only set it to `false` in advance multi-threaded
|
153
|
+
# and complex cases where granular events handling control is needed.
|
154
|
+
#
|
155
|
+
# @param poll_set [Boolean]
|
156
|
+
def consumer_poll_set=(poll_set)
|
157
|
+
@consumer_poll_set = poll_set
|
158
|
+
end
|
159
|
+
|
160
|
+
# Creates a consumer with this configuration.
|
149
161
|
#
|
150
162
|
# @return [Consumer] The created consumer
|
163
|
+
#
|
164
|
+
# @raise [ConfigError] When the configuration contains invalid options
|
165
|
+
# @raise [ClientCreationError] When the native client cannot be created
|
151
166
|
def consumer
|
152
167
|
opaque = Opaque.new
|
153
168
|
config = native_config(opaque)
|
@@ -160,19 +175,25 @@ module Rdkafka
|
|
160
175
|
# Create native client
|
161
176
|
kafka = native_kafka(config, :rd_kafka_consumer)
|
162
177
|
|
163
|
-
# Redirect the main queue to the consumer
|
164
|
-
Rdkafka::Bindings.rd_kafka_poll_set_consumer(kafka)
|
178
|
+
# Redirect the main queue to the consumer queue
|
179
|
+
Rdkafka::Bindings.rd_kafka_poll_set_consumer(kafka) if @consumer_poll_set
|
165
180
|
|
166
181
|
# Return consumer with Kafka client
|
167
|
-
Rdkafka::Consumer.new(
|
182
|
+
Rdkafka::Consumer.new(
|
183
|
+
Rdkafka::NativeKafka.new(
|
184
|
+
kafka,
|
185
|
+
run_polling_thread: false,
|
186
|
+
opaque: opaque
|
187
|
+
)
|
188
|
+
)
|
168
189
|
end
|
169
190
|
|
170
191
|
# Create a producer with this configuration.
|
171
192
|
#
|
193
|
+
# @return [Producer] The created producer
|
194
|
+
#
|
172
195
|
# @raise [ConfigError] When the configuration contains invalid options
|
173
196
|
# @raise [ClientCreationError] When the native client cannot be created
|
174
|
-
#
|
175
|
-
# @return [Producer] The created producer
|
176
197
|
def producer
|
177
198
|
# Create opaque
|
178
199
|
opaque = Opaque.new
|
@@ -182,22 +203,35 @@ module Rdkafka
|
|
182
203
|
Rdkafka::Bindings.rd_kafka_conf_set_dr_msg_cb(config, Rdkafka::Callbacks::DeliveryCallbackFunction)
|
183
204
|
# Return producer with Kafka client
|
184
205
|
partitioner_name = self[:partitioner] || self["partitioner"]
|
185
|
-
Rdkafka::Producer.new(
|
206
|
+
Rdkafka::Producer.new(
|
207
|
+
Rdkafka::NativeKafka.new(
|
208
|
+
native_kafka(config, :rd_kafka_producer),
|
209
|
+
run_polling_thread: true,
|
210
|
+
opaque: opaque
|
211
|
+
),
|
212
|
+
partitioner_name
|
213
|
+
).tap do |producer|
|
186
214
|
opaque.producer = producer
|
187
215
|
end
|
188
216
|
end
|
189
217
|
|
190
|
-
#
|
218
|
+
# Creates an admin instance with this configuration.
|
219
|
+
#
|
220
|
+
# @return [Admin] The created admin instance
|
191
221
|
#
|
192
222
|
# @raise [ConfigError] When the configuration contains invalid options
|
193
223
|
# @raise [ClientCreationError] When the native client cannot be created
|
194
|
-
#
|
195
|
-
# @return [Admin] The created admin instance
|
196
224
|
def admin
|
197
225
|
opaque = Opaque.new
|
198
226
|
config = native_config(opaque)
|
199
227
|
Rdkafka::Bindings.rd_kafka_conf_set_background_event_cb(config, Rdkafka::Callbacks::BackgroundEventCallbackFunction)
|
200
|
-
Rdkafka::Admin.new(
|
228
|
+
Rdkafka::Admin.new(
|
229
|
+
Rdkafka::NativeKafka.new(
|
230
|
+
native_kafka(config, :rd_kafka_producer),
|
231
|
+
run_polling_thread: true,
|
232
|
+
opaque: opaque
|
233
|
+
)
|
234
|
+
)
|
201
235
|
end
|
202
236
|
|
203
237
|
# Error that is returned by the underlying rdkafka error if an invalid configuration option is present.
|
@@ -18,13 +18,11 @@ module Rdkafka
|
|
18
18
|
|
19
19
|
# Reads a librdkafka native message's headers and returns them as a Ruby Hash
|
20
20
|
#
|
21
|
-
# @
|
21
|
+
# @private
|
22
22
|
#
|
23
|
+
# @param [Rdkafka::Bindings::Message] native_message
|
23
24
|
# @return [Hash<String, String>] headers Hash for the native_message
|
24
|
-
#
|
25
25
|
# @raise [Rdkafka::RdkafkaError] when fail to read headers
|
26
|
-
#
|
27
|
-
# @private
|
28
26
|
def self.from_native(native_message)
|
29
27
|
headers_ptrptr = FFI::MemoryPointer.new(:pointer)
|
30
28
|
err = Rdkafka::Bindings.rd_kafka_message_headers(native_message, headers_ptrptr)
|
@@ -36,6 +36,11 @@ module Rdkafka
|
|
36
36
|
# Add a topic with optionally partitions to the list.
|
37
37
|
# Calling this method multiple times for the same topic will overwrite the previous configuraton.
|
38
38
|
#
|
39
|
+
# @param topic [String] The topic's name
|
40
|
+
# @param partitions [Array<Integer>, Range<Integer>, Integer] The topic's partitions or partition count
|
41
|
+
#
|
42
|
+
# @return [nil]
|
43
|
+
#
|
39
44
|
# @example Add a topic with unassigned partitions
|
40
45
|
# tpl.add_topic("topic")
|
41
46
|
#
|
@@ -45,10 +50,6 @@ module Rdkafka
|
|
45
50
|
# @example Add a topic with all topics up to a count
|
46
51
|
# tpl.add_topic("topic", 9)
|
47
52
|
#
|
48
|
-
# @param topic [String] The topic's name
|
49
|
-
# @param partitions [Array<Integer>, Range<Integer>, Integer] The topic's partitions or partition count
|
50
|
-
#
|
51
|
-
# @return [nil]
|
52
53
|
def add_topic(topic, partitions=nil)
|
53
54
|
if partitions.nil?
|
54
55
|
@data[topic.to_s] = nil
|
@@ -90,11 +91,11 @@ module Rdkafka
|
|
90
91
|
|
91
92
|
# Create a new topic partition list based of a native one.
|
92
93
|
#
|
94
|
+
# @private
|
95
|
+
#
|
93
96
|
# @param pointer [FFI::Pointer] Optional pointer to an existing native list. Its contents will be copied.
|
94
97
|
#
|
95
98
|
# @return [TopicPartitionList]
|
96
|
-
#
|
97
|
-
# @private
|
98
99
|
def self.from_native_tpl(pointer)
|
99
100
|
# Data to be moved into the tpl
|
100
101
|
data = {}
|
@@ -127,8 +128,8 @@ module Rdkafka
|
|
127
128
|
#
|
128
129
|
# The pointer will be cleaned by `rd_kafka_topic_partition_list_destroy` when GC releases it.
|
129
130
|
#
|
130
|
-
# @return [FFI::Pointer]
|
131
131
|
# @private
|
132
|
+
# @return [FFI::Pointer]
|
132
133
|
def to_native_tpl
|
133
134
|
tpl = Rdkafka::Bindings.rd_kafka_topic_partition_list_new(count)
|
134
135
|
|
@@ -142,11 +143,13 @@ module Rdkafka
|
|
142
143
|
)
|
143
144
|
|
144
145
|
if p.offset
|
146
|
+
offset = p.offset.is_a?(Time) ? p.offset.to_f * 1_000 : p.offset
|
147
|
+
|
145
148
|
Rdkafka::Bindings.rd_kafka_topic_partition_list_set_offset(
|
146
149
|
tpl,
|
147
150
|
topic,
|
148
151
|
p.partition,
|
149
|
-
|
152
|
+
offset
|
150
153
|
)
|
151
154
|
end
|
152
155
|
end
|