rdkafka 0.22.2 → 0.27.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 +63 -3
- data/Gemfile +8 -0
- data/Gemfile.lint +14 -0
- data/Gemfile.lint.lock +123 -0
- data/README.md +19 -14
- data/Rakefile +21 -21
- data/bin/verify_kafka_warnings +39 -0
- data/dist/{librdkafka-2.8.0.tar.gz → librdkafka-2.14.0.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 +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/list_offsets_handle.rb +36 -0
- data/lib/rdkafka/admin/list_offsets_report.rb +51 -0
- data/lib/rdkafka/admin.rb +301 -135
- data/lib/rdkafka/bindings.rb +199 -110
- data/lib/rdkafka/callbacks.rb +124 -21
- data/lib/rdkafka/config.rb +81 -33
- 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 +21 -17
- data/lib/rdkafka/consumer.rb +397 -45
- data/lib/rdkafka/defaults.rb +106 -0
- data/lib/rdkafka/error.rb +40 -14
- data/lib/rdkafka/helpers/oauth.rb +45 -13
- 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 +10 -6
- data/lib/rdkafka/producer/partitions_count_cache.rb +29 -19
- data/lib/rdkafka/producer.rb +168 -82
- data/lib/rdkafka/version.rb +6 -3
- data/lib/rdkafka.rb +3 -0
- data/package-lock.json +331 -0
- data/package.json +9 -0
- data/rdkafka.gemspec +57 -36
- data/renovate.json +29 -24
- metadata +29 -124
- 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/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/callbacks.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rdkafka
|
|
4
|
+
# Callback handlers for librdkafka events
|
|
5
|
+
# @private
|
|
4
6
|
module Callbacks
|
|
5
7
|
# Extracts attributes of a rd_kafka_topic_result_t
|
|
6
8
|
#
|
|
@@ -8,12 +10,16 @@ module Rdkafka
|
|
|
8
10
|
class TopicResult
|
|
9
11
|
attr_reader :result_error, :error_string, :result_name
|
|
10
12
|
|
|
13
|
+
# @param topic_result_pointer [FFI::Pointer] pointer to the topic result struct
|
|
11
14
|
def initialize(topic_result_pointer)
|
|
12
15
|
@result_error = Rdkafka::Bindings.rd_kafka_topic_result_error(topic_result_pointer)
|
|
13
16
|
@error_string = Rdkafka::Bindings.rd_kafka_topic_result_error_string(topic_result_pointer)
|
|
14
17
|
@result_name = Rdkafka::Bindings.rd_kafka_topic_result_name(topic_result_pointer)
|
|
15
18
|
end
|
|
16
19
|
|
|
20
|
+
# @param count [Integer] number of results
|
|
21
|
+
# @param array_pointer [FFI::Pointer] pointer to the results array
|
|
22
|
+
# @return [Array<TopicResult>] array of topic results
|
|
17
23
|
def self.create_topic_results_from_array(count, array_pointer)
|
|
18
24
|
(1..count).map do |index|
|
|
19
25
|
result_pointer = (array_pointer + (index - 1)).read_pointer
|
|
@@ -22,13 +28,18 @@ module Rdkafka
|
|
|
22
28
|
end
|
|
23
29
|
end
|
|
24
30
|
|
|
31
|
+
# Extracts attributes of rd_kafka_group_result_t
|
|
32
|
+
#
|
|
33
|
+
# @private
|
|
25
34
|
class GroupResult
|
|
26
35
|
attr_reader :result_error, :error_string, :result_name
|
|
36
|
+
|
|
37
|
+
# @param group_result_pointer [FFI::Pointer] pointer to the group result struct
|
|
27
38
|
def initialize(group_result_pointer)
|
|
28
39
|
native_error = Rdkafka::Bindings.rd_kafka_group_result_error(group_result_pointer)
|
|
29
40
|
|
|
30
41
|
if native_error.null?
|
|
31
|
-
@result_error =
|
|
42
|
+
@result_error = Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
32
43
|
@error_string = FFI::Pointer::NULL
|
|
33
44
|
else
|
|
34
45
|
@result_error = native_error[:code]
|
|
@@ -37,6 +48,10 @@ module Rdkafka
|
|
|
37
48
|
|
|
38
49
|
@result_name = Rdkafka::Bindings.rd_kafka_group_result_name(group_result_pointer)
|
|
39
50
|
end
|
|
51
|
+
|
|
52
|
+
# @param count [Integer] number of results
|
|
53
|
+
# @param array_pointer [FFI::Pointer] pointer to the results array
|
|
54
|
+
# @return [Array<GroupResult>] array of group results
|
|
40
55
|
def self.create_group_results_from_array(count, array_pointer)
|
|
41
56
|
(1..count).map do |index|
|
|
42
57
|
result_pointer = (array_pointer + (index - 1)).read_pointer
|
|
@@ -51,12 +66,16 @@ module Rdkafka
|
|
|
51
66
|
class CreateAclResult
|
|
52
67
|
attr_reader :result_error, :error_string
|
|
53
68
|
|
|
69
|
+
# @param acl_result_pointer [FFI::Pointer] pointer to the ACL result struct
|
|
54
70
|
def initialize(acl_result_pointer)
|
|
55
71
|
rd_kafka_error_pointer = Bindings.rd_kafka_acl_result_error(acl_result_pointer)
|
|
56
72
|
@result_error = Rdkafka::Bindings.rd_kafka_error_code(rd_kafka_error_pointer)
|
|
57
73
|
@error_string = Rdkafka::Bindings.rd_kafka_error_string(rd_kafka_error_pointer)
|
|
58
74
|
end
|
|
59
75
|
|
|
76
|
+
# @param count [Integer] number of results
|
|
77
|
+
# @param array_pointer [FFI::Pointer] pointer to the results array
|
|
78
|
+
# @return [Array<CreateAclResult>] array of ACL results
|
|
60
79
|
def self.create_acl_results_from_array(count, array_pointer)
|
|
61
80
|
(1..count).map do |index|
|
|
62
81
|
result_pointer = (array_pointer + (index - 1)).read_pointer
|
|
@@ -71,19 +90,23 @@ module Rdkafka
|
|
|
71
90
|
class DeleteAclResult
|
|
72
91
|
attr_reader :result_error, :error_string, :matching_acls, :matching_acls_count
|
|
73
92
|
|
|
93
|
+
# @param acl_result_pointer [FFI::Pointer] pointer to the delete ACL result response struct
|
|
74
94
|
def initialize(acl_result_pointer)
|
|
75
|
-
@matching_acls=[]
|
|
95
|
+
@matching_acls = []
|
|
76
96
|
rd_kafka_error_pointer = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_response_error(acl_result_pointer)
|
|
77
97
|
@result_error = Rdkafka::Bindings.rd_kafka_error_code(rd_kafka_error_pointer)
|
|
78
98
|
@error_string = Rdkafka::Bindings.rd_kafka_error_string(rd_kafka_error_pointer)
|
|
79
|
-
if @result_error ==
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
if @result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
100
|
+
# Get the number of matching acls
|
|
101
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
|
102
|
+
@matching_acls = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_response_matching_acls(acl_result_pointer, pointer_to_size_t)
|
|
103
|
+
@matching_acls_count = pointer_to_size_t.read_int
|
|
84
104
|
end
|
|
85
105
|
end
|
|
86
106
|
|
|
107
|
+
# @param count [Integer] number of results
|
|
108
|
+
# @param array_pointer [FFI::Pointer] pointer to the results array
|
|
109
|
+
# @return [Array<DeleteAclResult>] array of delete ACL results
|
|
87
110
|
def self.delete_acl_results_from_array(count, array_pointer)
|
|
88
111
|
(1..count).map do |index|
|
|
89
112
|
result_pointer = (array_pointer + (index - 1)).read_pointer
|
|
@@ -98,11 +121,12 @@ module Rdkafka
|
|
|
98
121
|
class DescribeAclResult
|
|
99
122
|
attr_reader :result_error, :error_string, :matching_acls, :matching_acls_count
|
|
100
123
|
|
|
124
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
101
125
|
def initialize(event_ptr)
|
|
102
|
-
@matching_acls=[]
|
|
126
|
+
@matching_acls = []
|
|
103
127
|
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
|
104
128
|
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
|
105
|
-
if @result_error ==
|
|
129
|
+
if @result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
106
130
|
acl_describe_result = Rdkafka::Bindings.rd_kafka_event_DescribeAcls_result(event_ptr)
|
|
107
131
|
# Get the number of matching acls
|
|
108
132
|
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
|
@@ -112,15 +136,19 @@ module Rdkafka
|
|
|
112
136
|
end
|
|
113
137
|
end
|
|
114
138
|
|
|
139
|
+
# Extracts attributes of rd_kafka_DescribeConfigs_result_t
|
|
140
|
+
#
|
|
141
|
+
# @private
|
|
115
142
|
class DescribeConfigsResult
|
|
116
143
|
attr_reader :result_error, :error_string, :results, :results_count
|
|
117
144
|
|
|
145
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
118
146
|
def initialize(event_ptr)
|
|
119
|
-
@results=[]
|
|
147
|
+
@results = []
|
|
120
148
|
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
|
121
149
|
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
|
122
150
|
|
|
123
|
-
if @result_error ==
|
|
151
|
+
if @result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
124
152
|
configs_describe_result = Rdkafka::Bindings.rd_kafka_event_DescribeConfigs_result(event_ptr)
|
|
125
153
|
# Get the number of matching acls
|
|
126
154
|
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
|
@@ -130,15 +158,19 @@ module Rdkafka
|
|
|
130
158
|
end
|
|
131
159
|
end
|
|
132
160
|
|
|
161
|
+
# Extracts attributes of rd_kafka_IncrementalAlterConfigs_result_t
|
|
162
|
+
#
|
|
163
|
+
# @private
|
|
133
164
|
class IncrementalAlterConfigsResult
|
|
134
165
|
attr_reader :result_error, :error_string, :results, :results_count
|
|
135
166
|
|
|
167
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
136
168
|
def initialize(event_ptr)
|
|
137
|
-
@results=[]
|
|
169
|
+
@results = []
|
|
138
170
|
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
|
139
171
|
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
|
140
172
|
|
|
141
|
-
if @result_error ==
|
|
173
|
+
if @result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
142
174
|
incremental_alter_result = Rdkafka::Bindings.rd_kafka_event_IncrementalAlterConfigs_result(event_ptr)
|
|
143
175
|
# Get the number of matching acls
|
|
144
176
|
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
|
@@ -148,9 +180,34 @@ module Rdkafka
|
|
|
148
180
|
end
|
|
149
181
|
end
|
|
150
182
|
|
|
183
|
+
# Extracts attributes of rd_kafka_ListOffsets_result_t
|
|
184
|
+
#
|
|
185
|
+
# @private
|
|
186
|
+
class ListOffsetsResult
|
|
187
|
+
attr_reader :result_error, :error_string, :result_infos, :result_count
|
|
188
|
+
|
|
189
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
190
|
+
def initialize(event_ptr)
|
|
191
|
+
@result_infos = FFI::Pointer::NULL
|
|
192
|
+
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
|
193
|
+
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
|
194
|
+
|
|
195
|
+
if @result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
196
|
+
list_offsets_result = Rdkafka::Bindings.rd_kafka_event_ListOffsets_result(event_ptr)
|
|
197
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
|
|
198
|
+
@result_infos = Rdkafka::Bindings.rd_kafka_ListOffsets_result_infos(list_offsets_result, pointer_to_size_t)
|
|
199
|
+
@result_count = pointer_to_size_t.read(:size_t)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
151
204
|
# @private
|
|
152
205
|
class BackgroundEventCallback
|
|
153
|
-
|
|
206
|
+
# Handles background events from librdkafka
|
|
207
|
+
# @param _client_ptr [FFI::Pointer] unused client pointer
|
|
208
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
209
|
+
# @param _opaque_ptr [FFI::Pointer] unused opaque pointer
|
|
210
|
+
def self.call(_client_ptr, event_ptr, _opaque_ptr)
|
|
154
211
|
case Rdkafka::Bindings.rd_kafka_event_type(event_ptr)
|
|
155
212
|
when Rdkafka::Bindings::RD_KAFKA_EVENT_CREATETOPICS_RESULT
|
|
156
213
|
process_create_topic(event_ptr)
|
|
@@ -170,11 +227,15 @@ module Rdkafka
|
|
|
170
227
|
process_describe_acl(event_ptr)
|
|
171
228
|
when Rdkafka::Bindings::RD_KAFKA_EVENT_DELETEGROUPS_RESULT
|
|
172
229
|
process_delete_groups(event_ptr)
|
|
230
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_LISTOFFSETS_RESULT
|
|
231
|
+
process_list_offsets(event_ptr)
|
|
173
232
|
end
|
|
174
233
|
end
|
|
175
234
|
|
|
176
235
|
private
|
|
177
236
|
|
|
237
|
+
# Processes create topic result event
|
|
238
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
178
239
|
def self.process_create_topic(event_ptr)
|
|
179
240
|
create_topics_result = Rdkafka::Bindings.rd_kafka_event_CreateTopics_result(event_ptr)
|
|
180
241
|
|
|
@@ -193,6 +254,8 @@ module Rdkafka
|
|
|
193
254
|
end
|
|
194
255
|
end
|
|
195
256
|
|
|
257
|
+
# Processes describe configs result event
|
|
258
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
196
259
|
def self.process_describe_configs(event_ptr)
|
|
197
260
|
describe_configs = DescribeConfigsResult.new(event_ptr)
|
|
198
261
|
describe_configs_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
|
@@ -202,7 +265,7 @@ module Rdkafka
|
|
|
202
265
|
describe_configs_handle[:response_string] = describe_configs.error_string
|
|
203
266
|
describe_configs_handle[:pending] = false
|
|
204
267
|
|
|
205
|
-
if describe_configs.result_error ==
|
|
268
|
+
if describe_configs.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
206
269
|
describe_configs_handle[:config_entries] = describe_configs.results
|
|
207
270
|
describe_configs_handle[:entry_count] = describe_configs.results_count
|
|
208
271
|
end
|
|
@@ -211,6 +274,8 @@ module Rdkafka
|
|
|
211
274
|
end
|
|
212
275
|
end
|
|
213
276
|
|
|
277
|
+
# Processes incremental alter configs result event
|
|
278
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
214
279
|
def self.process_incremental_alter_configs(event_ptr)
|
|
215
280
|
incremental_alter = IncrementalAlterConfigsResult.new(event_ptr)
|
|
216
281
|
incremental_alter_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
|
@@ -220,7 +285,7 @@ module Rdkafka
|
|
|
220
285
|
incremental_alter_handle[:response_string] = incremental_alter.error_string
|
|
221
286
|
incremental_alter_handle[:pending] = false
|
|
222
287
|
|
|
223
|
-
if incremental_alter.result_error ==
|
|
288
|
+
if incremental_alter.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
224
289
|
incremental_alter_handle[:config_entries] = incremental_alter.results
|
|
225
290
|
incremental_alter_handle[:entry_count] = incremental_alter.results_count
|
|
226
291
|
end
|
|
@@ -229,6 +294,8 @@ module Rdkafka
|
|
|
229
294
|
end
|
|
230
295
|
end
|
|
231
296
|
|
|
297
|
+
# Processes delete groups result event
|
|
298
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
232
299
|
def self.process_delete_groups(event_ptr)
|
|
233
300
|
delete_groups_result = Rdkafka::Bindings.rd_kafka_event_DeleteGroups_result(event_ptr)
|
|
234
301
|
|
|
@@ -247,6 +314,8 @@ module Rdkafka
|
|
|
247
314
|
end
|
|
248
315
|
end
|
|
249
316
|
|
|
317
|
+
# Processes delete topic result event
|
|
318
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
250
319
|
def self.process_delete_topic(event_ptr)
|
|
251
320
|
delete_topics_result = Rdkafka::Bindings.rd_kafka_event_DeleteTopics_result(event_ptr)
|
|
252
321
|
|
|
@@ -265,6 +334,8 @@ module Rdkafka
|
|
|
265
334
|
end
|
|
266
335
|
end
|
|
267
336
|
|
|
337
|
+
# Processes create partitions result event
|
|
338
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
268
339
|
def self.process_create_partitions(event_ptr)
|
|
269
340
|
create_partitionss_result = Rdkafka::Bindings.rd_kafka_event_CreatePartitions_result(event_ptr)
|
|
270
341
|
|
|
@@ -283,6 +354,8 @@ module Rdkafka
|
|
|
283
354
|
end
|
|
284
355
|
end
|
|
285
356
|
|
|
357
|
+
# Processes create ACL result event
|
|
358
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
286
359
|
def self.process_create_acl(event_ptr)
|
|
287
360
|
create_acls_result = Rdkafka::Bindings.rd_kafka_event_CreateAcls_result(event_ptr)
|
|
288
361
|
|
|
@@ -300,6 +373,8 @@ module Rdkafka
|
|
|
300
373
|
end
|
|
301
374
|
end
|
|
302
375
|
|
|
376
|
+
# Processes delete ACL result event
|
|
377
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
303
378
|
def self.process_delete_acl(event_ptr)
|
|
304
379
|
delete_acls_result = Rdkafka::Bindings.rd_kafka_event_DeleteAcls_result(event_ptr)
|
|
305
380
|
|
|
@@ -313,7 +388,7 @@ module Rdkafka
|
|
|
313
388
|
delete_acl_handle[:response] = delete_acl_results[0].result_error
|
|
314
389
|
delete_acl_handle[:response_string] = delete_acl_results[0].error_string
|
|
315
390
|
|
|
316
|
-
if delete_acl_results[0].result_error ==
|
|
391
|
+
if delete_acl_results[0].result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
317
392
|
delete_acl_handle[:matching_acls] = delete_acl_results[0].matching_acls
|
|
318
393
|
delete_acl_handle[:matching_acls_count] = delete_acl_results[0].matching_acls_count
|
|
319
394
|
end
|
|
@@ -322,6 +397,8 @@ module Rdkafka
|
|
|
322
397
|
end
|
|
323
398
|
end
|
|
324
399
|
|
|
400
|
+
# Processes describe ACL result event
|
|
401
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
325
402
|
def self.process_describe_acl(event_ptr)
|
|
326
403
|
describe_acl = DescribeAclResult.new(event_ptr)
|
|
327
404
|
describe_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
|
@@ -330,7 +407,7 @@ module Rdkafka
|
|
|
330
407
|
describe_acl_handle[:response] = describe_acl.result_error
|
|
331
408
|
describe_acl_handle[:response_string] = describe_acl.error_string
|
|
332
409
|
|
|
333
|
-
if describe_acl.result_error ==
|
|
410
|
+
if describe_acl.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
334
411
|
describe_acl_handle[:acls] = describe_acl.matching_acls
|
|
335
412
|
describe_acl_handle[:acls_count] = describe_acl.matching_acls_count
|
|
336
413
|
end
|
|
@@ -338,11 +415,35 @@ module Rdkafka
|
|
|
338
415
|
describe_acl_handle.unlock
|
|
339
416
|
end
|
|
340
417
|
end
|
|
418
|
+
|
|
419
|
+
# Processes list offsets result event
|
|
420
|
+
# @param event_ptr [FFI::Pointer] pointer to the event
|
|
421
|
+
def self.process_list_offsets(event_ptr)
|
|
422
|
+
list_offsets = ListOffsetsResult.new(event_ptr)
|
|
423
|
+
list_offsets_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
|
424
|
+
|
|
425
|
+
if list_offsets_handle = Rdkafka::Admin::ListOffsetsHandle.remove(list_offsets_handle_ptr.address)
|
|
426
|
+
list_offsets_handle[:response] = list_offsets.result_error
|
|
427
|
+
list_offsets_handle[:response_string] = list_offsets.error_string
|
|
428
|
+
list_offsets_handle[:pending] = false
|
|
429
|
+
|
|
430
|
+
if list_offsets.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
431
|
+
list_offsets_handle[:result_infos] = list_offsets.result_infos
|
|
432
|
+
list_offsets_handle[:result_count] = list_offsets.result_count
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
list_offsets_handle.unlock
|
|
436
|
+
end
|
|
437
|
+
end
|
|
341
438
|
end
|
|
342
439
|
|
|
343
440
|
# @private
|
|
344
441
|
class DeliveryCallback
|
|
345
|
-
|
|
442
|
+
# Handles message delivery callbacks
|
|
443
|
+
# @param _client_ptr [FFI::Pointer] unused client pointer
|
|
444
|
+
# @param message_ptr [FFI::Pointer] pointer to the delivered message
|
|
445
|
+
# @param opaque_ptr [FFI::Pointer] pointer to the opaque object for callback context
|
|
446
|
+
def self.call(_client_ptr, message_ptr, opaque_ptr)
|
|
346
447
|
message = Rdkafka::Bindings::Message.new(message_ptr)
|
|
347
448
|
delivery_handle_ptr_address = message[:_private].address
|
|
348
449
|
if delivery_handle = Rdkafka::Producer::DeliveryHandle.remove(delivery_handle_ptr_address)
|
|
@@ -373,7 +474,9 @@ module Rdkafka
|
|
|
373
474
|
end
|
|
374
475
|
end
|
|
375
476
|
|
|
477
|
+
# @private
|
|
376
478
|
@@mutex = Mutex.new
|
|
479
|
+
# @private
|
|
377
480
|
@@current_pid = nil
|
|
378
481
|
|
|
379
482
|
class << self
|
|
@@ -392,14 +495,14 @@ module Rdkafka
|
|
|
392
495
|
|
|
393
496
|
# FFI Function used for Create Topic and Delete Topic callbacks
|
|
394
497
|
background_event_callback_function = FFI::Function.new(
|
|
395
|
-
|
|
498
|
+
:void, [:pointer, :pointer, :pointer]
|
|
396
499
|
) do |client_ptr, event_ptr, opaque_ptr|
|
|
397
500
|
BackgroundEventCallback.call(client_ptr, event_ptr, opaque_ptr)
|
|
398
501
|
end
|
|
399
502
|
|
|
400
503
|
# FFI Function used for Message Delivery callbacks
|
|
401
504
|
delivery_callback_function = FFI::Function.new(
|
|
402
|
-
|
|
505
|
+
:void, [:pointer, :pointer, :pointer]
|
|
403
506
|
) do |client_ptr, message_ptr, opaque_ptr|
|
|
404
507
|
DeliveryCallback.call(client_ptr, message_ptr, opaque_ptr)
|
|
405
508
|
end
|
data/lib/rdkafka/config.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Rdkafka
|
|
|
6
6
|
# configuration options is available on https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md.
|
|
7
7
|
class Config
|
|
8
8
|
# @private
|
|
9
|
-
@@logger = Logger.new(
|
|
9
|
+
@@logger = Logger.new($stdout)
|
|
10
10
|
# @private
|
|
11
11
|
@@statistics_callback = nil
|
|
12
12
|
# @private
|
|
@@ -33,7 +33,7 @@ module Rdkafka
|
|
|
33
33
|
# Makes sure that there is a thread for consuming logs
|
|
34
34
|
# We do not spawn thread immediately and we need to check if it operates to support forking
|
|
35
35
|
def self.ensure_log_thread
|
|
36
|
-
return if @@log_thread
|
|
36
|
+
return if @@log_thread&.alive?
|
|
37
37
|
|
|
38
38
|
@@log_mutex.synchronize do
|
|
39
39
|
# Restart if dead (fork, crash)
|
|
@@ -71,11 +71,10 @@ module Rdkafka
|
|
|
71
71
|
# You can configure if and how often this happens using `statistics.interval.ms`.
|
|
72
72
|
# The callback is called with a hash that's documented here: https://github.com/confluentinc/librdkafka/blob/master/STATISTICS.md
|
|
73
73
|
#
|
|
74
|
-
# @param callback [Proc, #call]
|
|
75
|
-
#
|
|
74
|
+
# @param callback [Proc, #call, nil] callable object or nil to clear
|
|
76
75
|
# @return [nil]
|
|
77
76
|
def self.statistics_callback=(callback)
|
|
78
|
-
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback
|
|
77
|
+
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback.nil?
|
|
79
78
|
@@statistics_callback = callback
|
|
80
79
|
end
|
|
81
80
|
|
|
@@ -90,11 +89,10 @@ module Rdkafka
|
|
|
90
89
|
# If this callback is not set, global errors such as brokers becoming unavailable will only be sent to the logger, as defined by librdkafka.
|
|
91
90
|
# The callback is called with an instance of RdKafka::Error.
|
|
92
91
|
#
|
|
93
|
-
# @param callback [Proc, #call]
|
|
94
|
-
#
|
|
92
|
+
# @param callback [Proc, #call, nil] callable object to handle errors or nil to clear
|
|
95
93
|
# @return [nil]
|
|
96
94
|
def self.error_callback=(callback)
|
|
97
|
-
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call)
|
|
95
|
+
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback.nil?
|
|
98
96
|
@@error_callback = callback
|
|
99
97
|
end
|
|
100
98
|
|
|
@@ -108,11 +106,10 @@ module Rdkafka
|
|
|
108
106
|
# Sets the SASL/OAUTHBEARER token refresh callback.
|
|
109
107
|
# This callback will be triggered when it is time to refresh the client's OAUTHBEARER token
|
|
110
108
|
#
|
|
111
|
-
# @param callback [Proc, #call]
|
|
112
|
-
#
|
|
109
|
+
# @param callback [Proc, #call, nil] callable object to handle token refresh or nil to clear
|
|
113
110
|
# @return [nil]
|
|
114
111
|
def self.oauthbearer_token_refresh_callback=(callback)
|
|
115
|
-
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback
|
|
112
|
+
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback.nil?
|
|
116
113
|
@@oauthbearer_token_refresh_callback = callback
|
|
117
114
|
end
|
|
118
115
|
|
|
@@ -129,15 +126,12 @@ module Rdkafka
|
|
|
129
126
|
end
|
|
130
127
|
|
|
131
128
|
# Default config that can be overwritten.
|
|
132
|
-
DEFAULT_CONFIG = {
|
|
133
|
-
# Request api version so advanced features work
|
|
134
|
-
:"api.version.request" => true
|
|
135
|
-
}.freeze
|
|
129
|
+
DEFAULT_CONFIG = {}.freeze
|
|
136
130
|
|
|
137
131
|
# Required config that cannot be overwritten.
|
|
138
132
|
REQUIRED_CONFIG = {
|
|
139
133
|
# Enable log queues so we get callbacks in our own Ruby threads
|
|
140
|
-
|
|
134
|
+
"log.queue": true
|
|
141
135
|
}.freeze
|
|
142
136
|
|
|
143
137
|
# Returns a new config with the provided options which are merged with {DEFAULT_CONFIG}.
|
|
@@ -174,10 +168,8 @@ module Rdkafka
|
|
|
174
168
|
|
|
175
169
|
# Get notifications on partition assignment/revocation for the subscribed topics
|
|
176
170
|
#
|
|
177
|
-
# @
|
|
178
|
-
|
|
179
|
-
@consumer_rebalance_listener = listener
|
|
180
|
-
end
|
|
171
|
+
# @return [Object, #on_partitions_assigned, #on_partitions_revoked] listener instance
|
|
172
|
+
attr_writer :consumer_rebalance_listener
|
|
181
173
|
|
|
182
174
|
# Should we use a single queue for the underlying consumer and events.
|
|
183
175
|
#
|
|
@@ -190,10 +182,8 @@ module Rdkafka
|
|
|
190
182
|
# It is recommended to use the defaults and only set it to `false` in advance multi-threaded
|
|
191
183
|
# and complex cases where granular events handling control is needed.
|
|
192
184
|
#
|
|
193
|
-
# @
|
|
194
|
-
|
|
195
|
-
@consumer_poll_set = poll_set
|
|
196
|
-
end
|
|
185
|
+
# @return [Boolean]
|
|
186
|
+
attr_writer :consumer_poll_set
|
|
197
187
|
|
|
198
188
|
# Creates a consumer with this configuration.
|
|
199
189
|
#
|
|
@@ -234,11 +224,13 @@ module Rdkafka
|
|
|
234
224
|
# @param native_kafka_auto_start [Boolean] should the native kafka operations be started
|
|
235
225
|
# automatically. Defaults to true. Set to false only when doing complex initialization.
|
|
236
226
|
# @param native_kafka_poll_timeout_ms [Integer] ms poll time of the native Kafka
|
|
227
|
+
# @param run_polling_thread [Boolean] should the background polling thread be started.
|
|
228
|
+
# Defaults to true. Set to false when using the FD API for fiber scheduler integration.
|
|
237
229
|
# @return [Producer] The created producer
|
|
238
230
|
#
|
|
239
231
|
# @raise [ConfigError] When the configuration contains invalid options
|
|
240
232
|
# @raise [ClientCreationError] When the native client cannot be created
|
|
241
|
-
def producer(native_kafka_auto_start: true, native_kafka_poll_timeout_ms:
|
|
233
|
+
def producer(native_kafka_auto_start: true, native_kafka_poll_timeout_ms: Defaults::NATIVE_KAFKA_POLL_TIMEOUT_MS, run_polling_thread: true)
|
|
242
234
|
# Create opaque
|
|
243
235
|
opaque = Opaque.new
|
|
244
236
|
# Create Kafka config
|
|
@@ -253,7 +245,7 @@ module Rdkafka
|
|
|
253
245
|
Rdkafka::Producer.new(
|
|
254
246
|
Rdkafka::NativeKafka.new(
|
|
255
247
|
kafka,
|
|
256
|
-
run_polling_thread:
|
|
248
|
+
run_polling_thread: run_polling_thread,
|
|
257
249
|
opaque: opaque,
|
|
258
250
|
auto_start: native_kafka_auto_start,
|
|
259
251
|
timeout_ms: native_kafka_poll_timeout_ms
|
|
@@ -269,11 +261,13 @@ module Rdkafka
|
|
|
269
261
|
# @param native_kafka_auto_start [Boolean] should the native kafka operations be started
|
|
270
262
|
# automatically. Defaults to true. Set to false only when doing complex initialization.
|
|
271
263
|
# @param native_kafka_poll_timeout_ms [Integer] ms poll time of the native Kafka
|
|
264
|
+
# @param run_polling_thread [Boolean] should the background polling thread be started.
|
|
265
|
+
# Defaults to true. Set to false when using the FD API for fiber scheduler integration.
|
|
272
266
|
# @return [Admin] The created admin instance
|
|
273
267
|
#
|
|
274
268
|
# @raise [ConfigError] When the configuration contains invalid options
|
|
275
269
|
# @raise [ClientCreationError] When the native client cannot be created
|
|
276
|
-
def admin(native_kafka_auto_start: true, native_kafka_poll_timeout_ms:
|
|
270
|
+
def admin(native_kafka_auto_start: true, native_kafka_poll_timeout_ms: Defaults::NATIVE_KAFKA_POLL_TIMEOUT_MS, run_polling_thread: true)
|
|
277
271
|
opaque = Opaque.new
|
|
278
272
|
config = native_config(opaque)
|
|
279
273
|
Rdkafka::Bindings.rd_kafka_conf_set_background_event_cb(config, Rdkafka::Callbacks::BackgroundEventCallbackFunction)
|
|
@@ -283,7 +277,7 @@ module Rdkafka
|
|
|
283
277
|
Rdkafka::Admin.new(
|
|
284
278
|
Rdkafka::NativeKafka.new(
|
|
285
279
|
kafka,
|
|
286
|
-
run_polling_thread:
|
|
280
|
+
run_polling_thread: run_polling_thread,
|
|
287
281
|
opaque: opaque,
|
|
288
282
|
auto_start: native_kafka_auto_start,
|
|
289
283
|
timeout_ms: native_kafka_poll_timeout_ms
|
|
@@ -291,6 +285,46 @@ module Rdkafka
|
|
|
291
285
|
)
|
|
292
286
|
end
|
|
293
287
|
|
|
288
|
+
# Returns all configuration properties and their current values for this config.
|
|
289
|
+
#
|
|
290
|
+
# Uses `rd_kafka_conf_dump` to retrieve every property (including defaults and
|
|
291
|
+
# internal properties like `client.software.name`) as a flat Hash.
|
|
292
|
+
#
|
|
293
|
+
# @note The librdkafka C API does not distinguish between producer-only, consumer-only,
|
|
294
|
+
# and global properties at the configuration level. All properties are returned
|
|
295
|
+
# regardless of the intended client type.
|
|
296
|
+
#
|
|
297
|
+
# @note The returned Hash may include sensitive values such as authentication
|
|
298
|
+
# credentials and key passwords. Do not log or serialize the returned data
|
|
299
|
+
# unless you have explicitly redacted secret entries.
|
|
300
|
+
#
|
|
301
|
+
# @return [Hash{Symbol => String}] property names mapped to their current values
|
|
302
|
+
#
|
|
303
|
+
# @raise [ConfigError] When the configuration contains invalid options
|
|
304
|
+
def describe_properties
|
|
305
|
+
config = nil
|
|
306
|
+
dump_ptr = nil
|
|
307
|
+
count = 0
|
|
308
|
+
|
|
309
|
+
config = native_config
|
|
310
|
+
count_ptr = Rdkafka::Bindings::SizePtr.new
|
|
311
|
+
dump_ptr = Rdkafka::Bindings.rd_kafka_conf_dump(config, count_ptr)
|
|
312
|
+
|
|
313
|
+
count = count_ptr[:value]
|
|
314
|
+
result = {}
|
|
315
|
+
|
|
316
|
+
(0...count).step(2) do |i|
|
|
317
|
+
key = dump_ptr.get_pointer(i * FFI::Pointer.size).read_string
|
|
318
|
+
value = dump_ptr.get_pointer((i + 1) * FFI::Pointer.size).read_string
|
|
319
|
+
result[key.to_sym] = value
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
result
|
|
323
|
+
ensure
|
|
324
|
+
Rdkafka::Bindings.rd_kafka_conf_dump_free(dump_ptr, count) if dump_ptr
|
|
325
|
+
Rdkafka::Bindings.rd_kafka_conf_destroy(config) if config
|
|
326
|
+
end
|
|
327
|
+
|
|
294
328
|
# Error that is returned by the underlying rdkafka error if an invalid configuration option is present.
|
|
295
329
|
class ConfigError < RuntimeError; end
|
|
296
330
|
|
|
@@ -304,6 +338,9 @@ module Rdkafka
|
|
|
304
338
|
|
|
305
339
|
# This method is only intended to be used to create a client,
|
|
306
340
|
# using it in another way will leak memory.
|
|
341
|
+
#
|
|
342
|
+
# @param opaque [Object, nil] optional opaque pointer for callbacks
|
|
343
|
+
# @return [FFI::Pointer] native rdkafka configuration pointer
|
|
307
344
|
def native_config(opaque = nil)
|
|
308
345
|
Rdkafka::Bindings.rd_kafka_conf_new.tap do |config|
|
|
309
346
|
# Create config
|
|
@@ -348,6 +385,11 @@ module Rdkafka
|
|
|
348
385
|
end
|
|
349
386
|
end
|
|
350
387
|
|
|
388
|
+
# Creates a native Kafka handle
|
|
389
|
+
# @param config [FFI::Pointer] pointer to the native config
|
|
390
|
+
# @param type [Symbol] type of client (:rd_kafka_producer or :rd_kafka_consumer)
|
|
391
|
+
# @return [FFI::Pointer] pointer to the native Kafka handle
|
|
392
|
+
# @private
|
|
351
393
|
def native_kafka(config, type)
|
|
352
394
|
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
|
353
395
|
handle = Rdkafka::Bindings.rd_kafka_new(
|
|
@@ -362,10 +404,9 @@ module Rdkafka
|
|
|
362
404
|
end
|
|
363
405
|
|
|
364
406
|
# Redirect log to handle's queue
|
|
365
|
-
Rdkafka::Bindings.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
)
|
|
407
|
+
main_queue = Rdkafka::Bindings.rd_kafka_queue_get_main(handle)
|
|
408
|
+
Rdkafka::Bindings.rd_kafka_set_log_queue(handle, main_queue)
|
|
409
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(main_queue)
|
|
369
410
|
|
|
370
411
|
# Return handle which should be closed using rd_kafka_destroy after usage.
|
|
371
412
|
handle
|
|
@@ -377,10 +418,15 @@ module Rdkafka
|
|
|
377
418
|
attr_accessor :producer
|
|
378
419
|
attr_accessor :consumer_rebalance_listener
|
|
379
420
|
|
|
421
|
+
# Invokes the delivery callback on the producer if one is set
|
|
422
|
+
# @param delivery_report [Rdkafka::Producer::DeliveryReport] the delivery report
|
|
423
|
+
# @param delivery_handle [Rdkafka::Producer::DeliveryHandle] the delivery handle
|
|
380
424
|
def call_delivery_callback(delivery_report, delivery_handle)
|
|
381
|
-
producer
|
|
425
|
+
producer&.call_delivery_callback(delivery_report, delivery_handle)
|
|
382
426
|
end
|
|
383
427
|
|
|
428
|
+
# Invokes the on_partitions_assigned callback on the rebalance listener if set
|
|
429
|
+
# @param list [Rdkafka::Consumer::TopicPartitionList] the assigned partitions
|
|
384
430
|
def call_on_partitions_assigned(list)
|
|
385
431
|
return unless consumer_rebalance_listener
|
|
386
432
|
return unless consumer_rebalance_listener.respond_to?(:on_partitions_assigned)
|
|
@@ -388,6 +434,8 @@ module Rdkafka
|
|
|
388
434
|
consumer_rebalance_listener.on_partitions_assigned(list)
|
|
389
435
|
end
|
|
390
436
|
|
|
437
|
+
# Invokes the on_partitions_revoked callback on the rebalance listener if set
|
|
438
|
+
# @param list [Rdkafka::Consumer::TopicPartitionList] the revoked partitions
|
|
391
439
|
def call_on_partitions_revoked(list)
|
|
392
440
|
return unless consumer_rebalance_listener
|
|
393
441
|
return unless consumer_rebalance_listener.respond_to?(:on_partitions_revoked)
|
|
@@ -4,6 +4,7 @@ module Rdkafka
|
|
|
4
4
|
class Consumer
|
|
5
5
|
# Interface to return headers for a consumer message
|
|
6
6
|
module Headers
|
|
7
|
+
# Empty frozen hash used when there are no headers
|
|
7
8
|
EMPTY_HEADERS = {}.freeze
|
|
8
9
|
|
|
9
10
|
# Reads a librdkafka native message's headers and returns them as a Ruby Hash
|
|
@@ -12,8 +13,8 @@ module Rdkafka
|
|
|
12
13
|
#
|
|
13
14
|
# @private
|
|
14
15
|
#
|
|
15
|
-
# @param [Rdkafka::Bindings::Message]
|
|
16
|
-
# @return [Hash
|
|
16
|
+
# @param native_message [Rdkafka::Bindings::Message] the native message to read headers from
|
|
17
|
+
# @return [Hash{String => String, Array<String>}] headers Hash for the native_message
|
|
17
18
|
# @raise [Rdkafka::RdkafkaError] when fail to read headers
|
|
18
19
|
def self.from_native(native_message)
|
|
19
20
|
headers_ptrptr = FFI::MemoryPointer.new(:pointer)
|