karafka-rdkafka 0.27.2-aarch64-linux-gnu → 0.28.0-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 +33 -0
- data/README.md +1 -0
- data/docker-compose-ssl.yml +1 -1
- data/docker-compose.yml +1 -1
- data/ext/librdkafka.so +0 -0
- data/karafka-rdkafka.gemspec +1 -0
- data/lib/rdkafka/abstract_handle.rb +37 -4
- data/lib/rdkafka/admin/config_binding_result.rb +1 -1
- data/lib/rdkafka/admin/create_acl_handle.rb +2 -8
- data/lib/rdkafka/admin/create_partitions_handle.rb +1 -20
- data/lib/rdkafka/admin/create_topic_handle.rb +1 -20
- data/lib/rdkafka/admin/delete_acl_handle.rb +2 -10
- data/lib/rdkafka/admin/delete_groups_handle.rb +3 -11
- data/lib/rdkafka/admin/delete_topic_handle.rb +1 -20
- data/lib/rdkafka/admin/describe_acl_handle.rb +2 -10
- data/lib/rdkafka/admin/describe_configs_handle.rb +2 -13
- data/lib/rdkafka/admin/describe_configs_report.rb +5 -6
- data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +2 -13
- data/lib/rdkafka/admin/incremental_alter_configs_report.rb +5 -6
- data/lib/rdkafka/admin/list_offsets_handle.rb +2 -13
- data/lib/rdkafka/admin/list_offsets_report.rb +5 -2
- data/lib/rdkafka/admin.rb +56 -137
- data/lib/rdkafka/bindings.rb +12 -3
- data/lib/rdkafka/callbacks/base_handler.rb +62 -0
- data/lib/rdkafka/callbacks/create_acl_handler.rb +37 -0
- data/lib/rdkafka/callbacks/create_partitions_handler.rb +37 -0
- data/lib/rdkafka/callbacks/create_topic_handler.rb +37 -0
- data/lib/rdkafka/callbacks/delete_acl_handler.rb +42 -0
- data/lib/rdkafka/callbacks/delete_groups_handler.rb +37 -0
- data/lib/rdkafka/callbacks/delete_topic_handler.rb +37 -0
- data/lib/rdkafka/callbacks/describe_acl_handler.rb +35 -0
- data/lib/rdkafka/callbacks/describe_configs_handler.rb +42 -0
- data/lib/rdkafka/callbacks/incremental_alter_configs_handler.rb +42 -0
- data/lib/rdkafka/callbacks/list_offsets_handler.rb +42 -0
- data/lib/rdkafka/callbacks.rb +56 -244
- data/lib/rdkafka/config.rb +50 -33
- data/lib/rdkafka/consumer/headers.rb +19 -5
- data/lib/rdkafka/consumer/topic_partition_list.rb +43 -33
- data/lib/rdkafka/consumer.rb +164 -23
- data/lib/rdkafka/defaults.rb +21 -1
- data/lib/rdkafka/error.rb +12 -4
- data/lib/rdkafka/helpers/list_offsets.rb +127 -0
- data/lib/rdkafka/helpers/metadata.rb +29 -0
- data/lib/rdkafka/metadata.rb +84 -19
- data/lib/rdkafka/producer/delivery_handle.rb +3 -3
- data/lib/rdkafka/producer/partitions_count_cache.rb +24 -38
- data/lib/rdkafka/producer.rb +72 -51
- data/lib/rdkafka/version.rb +3 -3
- data/lib/rdkafka.rb +13 -0
- data/package-lock.json +6 -6
- data/renovate.json +11 -1
- metadata +14 -4
- data/Gemfile +0 -13
- data/Gemfile.lint +0 -14
- data/Gemfile.lint.lock +0 -123
data/lib/rdkafka/metadata.rb
CHANGED
|
@@ -23,12 +23,55 @@ module Rdkafka
|
|
|
23
23
|
# @param timeout_ms [Integer] timeout in milliseconds
|
|
24
24
|
# @raise [RdkafkaError] when metadata fetch fails
|
|
25
25
|
def initialize(native_client, topic_name = nil, timeout_ms = Defaults::METADATA_TIMEOUT_MS)
|
|
26
|
-
attempt
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
attempt = 0
|
|
27
|
+
deadline = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) +
|
|
28
|
+
Defaults::METADATA_RETRY_BUDGET_MS / 1_000.0
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
attempt += 1
|
|
32
|
+
fetch_metadata(native_client, topic_name, timeout_ms)
|
|
33
|
+
rescue ::Rdkafka::RdkafkaError => e
|
|
34
|
+
raise unless RETRIED_ERRORS.include?(e.code)
|
|
35
|
+
raise if attempt > Defaults::METADATA_MAX_RETRIES
|
|
36
|
+
|
|
37
|
+
# Stop once the wall-clock retry budget is spent, but only after at least
|
|
38
|
+
# METADATA_MIN_ATTEMPTS tries so a slow broker (whose requests each consume the full
|
|
39
|
+
# timeout) still gets a few tries rather than being cut off after one or two.
|
|
40
|
+
raise if attempt >= Defaults::METADATA_MIN_ATTEMPTS &&
|
|
41
|
+
::Process.clock_gettime(::Process::CLOCK_MONOTONIC) >= deadline
|
|
42
|
+
|
|
43
|
+
# Exponential backoff between attempts, capped so a long retry sequence cannot block for
|
|
44
|
+
# minutes. The request timeout (`timeout_ms`) is intentionally left unchanged: it used to be
|
|
45
|
+
# overwritten with the backoff value, which shrank the first retries below the configured
|
|
46
|
+
# timeout (near-guaranteeing another timeout) and then inflated later ones to ~100s.
|
|
47
|
+
backoff_ms = [
|
|
48
|
+
(2**attempt) * Defaults::METADATA_RETRY_BACKOFF_BASE_MS,
|
|
49
|
+
Defaults::METADATA_RETRY_BACKOFF_MAX_MS
|
|
50
|
+
].min
|
|
51
|
+
|
|
52
|
+
sleep(backoff_ms / 1_000.0)
|
|
53
|
+
|
|
54
|
+
retry
|
|
31
55
|
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# Performs a single metadata fetch attempt and frees its native resources before returning.
|
|
61
|
+
#
|
|
62
|
+
# This is intentionally separate from the retry loop in {#initialize}: `retry` restarts the
|
|
63
|
+
# `begin` block without running its `ensure`, so cleaning up here (rather than in an `ensure`
|
|
64
|
+
# around the loop) guarantees every attempt destroys its own native topic handle and metadata
|
|
65
|
+
# struct instead of leaking all but the last one.
|
|
66
|
+
#
|
|
67
|
+
# @param native_client [FFI::Pointer] pointer to the native Kafka client
|
|
68
|
+
# @param topic_name [String, nil] specific topic to fetch metadata for, or nil for all topics
|
|
69
|
+
# @param timeout_ms [Integer] timeout in milliseconds
|
|
70
|
+
def fetch_metadata(native_client, topic_name, timeout_ms)
|
|
71
|
+
native_topic = nil
|
|
72
|
+
metadata_ptr = nil
|
|
73
|
+
|
|
74
|
+
native_topic = Rdkafka::Bindings.rd_kafka_topic_new(native_client, topic_name, nil) if topic_name
|
|
32
75
|
|
|
33
76
|
ptr = FFI::MemoryPointer.new(:pointer)
|
|
34
77
|
|
|
@@ -41,24 +84,16 @@ module Rdkafka
|
|
|
41
84
|
|
|
42
85
|
Rdkafka::RdkafkaError.validate!(result)
|
|
43
86
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
raise if attempt > Defaults::METADATA_MAX_RETRIES
|
|
87
|
+
# rd_kafka_metadata only allocates the struct on success, so we read the pointer to destroy
|
|
88
|
+
# only after validate! has confirmed the call succeeded.
|
|
89
|
+
metadata_ptr = ptr.read_pointer
|
|
48
90
|
|
|
49
|
-
|
|
50
|
-
timeout_ms = backoff_factor * Defaults::METADATA_RETRY_BACKOFF_BASE_MS
|
|
51
|
-
|
|
52
|
-
sleep(timeout_ms / 1_000.0)
|
|
53
|
-
|
|
54
|
-
retry
|
|
91
|
+
metadata_from_native(metadata_ptr)
|
|
55
92
|
ensure
|
|
56
|
-
Rdkafka::Bindings.rd_kafka_topic_destroy(native_topic) if
|
|
57
|
-
Rdkafka::Bindings.rd_kafka_metadata_destroy(
|
|
93
|
+
Rdkafka::Bindings.rd_kafka_topic_destroy(native_topic) if native_topic
|
|
94
|
+
Rdkafka::Bindings.rd_kafka_metadata_destroy(metadata_ptr) if metadata_ptr && !metadata_ptr.null?
|
|
58
95
|
end
|
|
59
96
|
|
|
60
|
-
private
|
|
61
|
-
|
|
62
97
|
# Extracts metadata from native pointer
|
|
63
98
|
# @param ptr [FFI::Pointer] pointer to native metadata
|
|
64
99
|
def metadata_from_native(ptr)
|
|
@@ -134,6 +169,36 @@ module Rdkafka
|
|
|
134
169
|
:replicas, :pointer,
|
|
135
170
|
:in_sync_replica_brokers, :int,
|
|
136
171
|
:isrs, :pointer
|
|
172
|
+
|
|
173
|
+
# The base `#to_h` skips FFI pointer members, which would drop the replica and in-sync
|
|
174
|
+
# replica assignments entirely. We dereference those pointers here so the partition hash
|
|
175
|
+
# exposes the broker ids backing the partition (needed e.g. to plan replication changes).
|
|
176
|
+
#
|
|
177
|
+
# @return [Hash{Symbol => Integer, Array<Integer>}] partition metadata:
|
|
178
|
+
# * +:partition_id+ (Integer) - partition id
|
|
179
|
+
# * +:leader+ (Integer) - broker id of the partition leader
|
|
180
|
+
# * +:replica_count+ (Integer) - number of assigned replicas
|
|
181
|
+
# * +:in_sync_replica_brokers+ (Integer) - number of in-sync replicas
|
|
182
|
+
# * +:replicas+ (Array<Integer>) - broker ids of the assigned replicas
|
|
183
|
+
# * +:isrs+ (Array<Integer>) - broker ids of the in-sync replicas
|
|
184
|
+
def to_h
|
|
185
|
+
super.merge(
|
|
186
|
+
replicas: read_broker_ids(self[:replicas], self[:replica_count]),
|
|
187
|
+
isrs: read_broker_ids(self[:isrs], self[:in_sync_replica_brokers])
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
|
|
193
|
+
# Reads `count` broker ids (int32) from a replicas/isrs pointer.
|
|
194
|
+
# @param pointer [FFI::Pointer] pointer to the broker ids array
|
|
195
|
+
# @param count [Integer] number of broker ids to read
|
|
196
|
+
# @return [Array<Integer>] broker ids (empty when there are none)
|
|
197
|
+
def read_broker_ids(pointer, count)
|
|
198
|
+
return [] if count.zero? || pointer.null?
|
|
199
|
+
|
|
200
|
+
pointer.read_array_of_int32(count)
|
|
201
|
+
end
|
|
137
202
|
end
|
|
138
203
|
end
|
|
139
204
|
end
|
|
@@ -8,14 +8,14 @@ module Rdkafka
|
|
|
8
8
|
layout :pending, :bool,
|
|
9
9
|
:response, :int,
|
|
10
10
|
:partition, :int,
|
|
11
|
-
:offset, :int64
|
|
12
|
-
:topic_name, :pointer
|
|
11
|
+
:offset, :int64
|
|
13
12
|
|
|
14
13
|
# @return [Object, nil] label set during message production or nil by default
|
|
15
14
|
attr_accessor :label
|
|
16
15
|
|
|
17
16
|
# @return [String] topic where we are trying to send the message
|
|
18
|
-
#
|
|
17
|
+
# Set in `#produce`, where the topic is known upfront. Keeping it as a Ruby attribute
|
|
18
|
+
# spares a per-message native string copy in the delivery callback.
|
|
19
19
|
attr_accessor :topic
|
|
20
20
|
|
|
21
21
|
# @return [String] the name of the operation (e.g. "delivery")
|
|
@@ -37,12 +37,11 @@ module Rdkafka
|
|
|
37
37
|
# contention in multi-threaded environments while ensuring data consistency.
|
|
38
38
|
#
|
|
39
39
|
# 6. Topic recreation handling
|
|
40
|
-
# If a topic is deleted and recreated with fewer partitions, the cache
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# This also aligns with the previous cache implementation.
|
|
40
|
+
# If a topic is deleted and recreated with fewer partitions, the cache keeps reporting the
|
|
41
|
+
# higher count only until the entry's TTL expires. The first refresh after expiry performs
|
|
42
|
+
# an authoritative metadata read and adopts the lower count. Within the TTL window a lower
|
|
43
|
+
# value is still ignored, so a transient or racy lower read cannot clobber a correct higher
|
|
44
|
+
# count.
|
|
46
45
|
class PartitionsCountCache
|
|
47
46
|
include Helpers::Time
|
|
48
47
|
|
|
@@ -91,28 +90,14 @@ module Rdkafka
|
|
|
91
90
|
current_info = @counts[topic]
|
|
92
91
|
|
|
93
92
|
if current_info.nil? || expired?(current_info[0])
|
|
93
|
+
# The cached entry is missing or expired, so the block performs an authoritative metadata
|
|
94
|
+
# read. We hand it to `set`, which adopts a higher count always and a lower count once the
|
|
95
|
+
# entry has expired (e.g. the topic was recreated with fewer partitions). We then return
|
|
96
|
+
# whatever `set` settled on so a concurrent refresh that wrote a higher value still wins.
|
|
94
97
|
new_count = yield
|
|
98
|
+
set(topic, new_count)
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
# No existing data, create a new entry with mutex
|
|
98
|
-
set(topic, new_count)
|
|
99
|
-
|
|
100
|
-
return new_count
|
|
101
|
-
else
|
|
102
|
-
current_count = current_info[1]
|
|
103
|
-
|
|
104
|
-
if new_count > current_count
|
|
105
|
-
# Higher value needs mutex to update both timestamp and count
|
|
106
|
-
set(topic, new_count)
|
|
107
|
-
|
|
108
|
-
return new_count
|
|
109
|
-
else
|
|
110
|
-
# Same or lower value, just update timestamp without mutex
|
|
111
|
-
refresh_timestamp(topic)
|
|
112
|
-
|
|
113
|
-
return current_count
|
|
114
|
-
end
|
|
115
|
-
end
|
|
100
|
+
return @counts[topic][1]
|
|
116
101
|
end
|
|
117
102
|
|
|
118
103
|
current_info[1]
|
|
@@ -133,8 +118,11 @@ module Rdkafka
|
|
|
133
118
|
# First check outside mutex to avoid unnecessary locking
|
|
134
119
|
current_info = @counts[topic]
|
|
135
120
|
|
|
136
|
-
#
|
|
137
|
-
|
|
121
|
+
# Within the TTL window a lower value is treated as a stale/racy read and ignored, since
|
|
122
|
+
# partition counts only grow during normal operation. Once the entry has expired a lower
|
|
123
|
+
# value is an authoritative refresh (e.g. the topic was recreated with fewer partitions),
|
|
124
|
+
# so we fall through and adopt it below.
|
|
125
|
+
if current_info && new_count < current_info[1] && !expired?(current_info[0])
|
|
138
126
|
refresh_timestamp(topic)
|
|
139
127
|
|
|
140
128
|
return
|
|
@@ -148,17 +136,15 @@ module Rdkafka
|
|
|
148
136
|
if current_info.nil?
|
|
149
137
|
# Create new entry
|
|
150
138
|
@counts[topic] = [monotonic_now_ms, new_count]
|
|
139
|
+
elsif new_count > current_info[1] || expired?(current_info[0])
|
|
140
|
+
# A higher count always wins; a lower count is accepted only when the existing entry
|
|
141
|
+
# has expired, so a concurrent fresh higher value (which reset the timestamp) is never
|
|
142
|
+
# clobbered by a stale lower one.
|
|
143
|
+
current_info[0] = monotonic_now_ms
|
|
144
|
+
current_info[1] = new_count
|
|
151
145
|
else
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if new_count > current_count
|
|
155
|
-
# Update to higher count value
|
|
156
|
-
current_info[0] = monotonic_now_ms
|
|
157
|
-
current_info[1] = new_count
|
|
158
|
-
else
|
|
159
|
-
# Same or lower count, update timestamp only
|
|
160
|
-
current_info[0] = monotonic_now_ms
|
|
161
|
-
end
|
|
146
|
+
# Same or lower count within the TTL window: refresh the timestamp only
|
|
147
|
+
current_info[0] = monotonic_now_ms
|
|
162
148
|
end
|
|
163
149
|
end
|
|
164
150
|
end
|
data/lib/rdkafka/producer.rb
CHANGED
|
@@ -5,6 +5,7 @@ module Rdkafka
|
|
|
5
5
|
class Producer
|
|
6
6
|
include Helpers::Time
|
|
7
7
|
include Helpers::OAuth
|
|
8
|
+
include Helpers::Metadata
|
|
8
9
|
|
|
9
10
|
# @private
|
|
10
11
|
@@partitions_count_cache = PartitionsCountCache.new
|
|
@@ -94,6 +95,12 @@ module Rdkafka
|
|
|
94
95
|
)
|
|
95
96
|
|
|
96
97
|
unless result == :config_ok
|
|
98
|
+
# rd_kafka_topic_new has not been called yet, so librdkafka has not taken
|
|
99
|
+
# ownership of the config. Destroy it ourselves before raising, otherwise the
|
|
100
|
+
# partially built rd_kafka_topic_conf_t leaks. (On the rd_kafka_topic_new path
|
|
101
|
+
# librdkafka frees the conf on both success and failure, so we never destroy it
|
|
102
|
+
# there.)
|
|
103
|
+
Rdkafka::Bindings.rd_kafka_topic_conf_destroy(topic_config)
|
|
97
104
|
raise Config::ConfigError.new(error_buffer.read_string)
|
|
98
105
|
end
|
|
99
106
|
end
|
|
@@ -388,9 +395,11 @@ module Rdkafka
|
|
|
388
395
|
# @note We cache the partition count for a given topic for given time. If statistics are
|
|
389
396
|
# enabled for any producer or consumer, it will take precedence over per instance fetching.
|
|
390
397
|
#
|
|
391
|
-
# This prevents us in case someone uses `partition_key
|
|
392
|
-
# each message.
|
|
393
|
-
#
|
|
398
|
+
# This prevents us, in case someone uses `partition_key`, from querying for the count with
|
|
399
|
+
# each message. A missing topic (`unknown_topic_or_part`) is cached as
|
|
400
|
+
# `RD_KAFKA_PARTITION_UA` too, so producing to a not-yet-created topic does not run a
|
|
401
|
+
# blocking metadata query on every message; the cache TTL still bounds how long that result
|
|
402
|
+
# is reused before we look again.
|
|
394
403
|
def partition_count(topic)
|
|
395
404
|
closed_producer_check(__method__)
|
|
396
405
|
|
|
@@ -402,14 +411,15 @@ module Rdkafka
|
|
|
402
411
|
end
|
|
403
412
|
|
|
404
413
|
topic_metadata ? topic_metadata[:partition_count] : Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
414
|
+
rescue Rdkafka::RdkafkaError => e
|
|
415
|
+
# A missing topic is an expected, cacheable outcome (the topic may be auto-created on
|
|
416
|
+
# produce, or simply not exist yet). Returning RD_KAFKA_PARTITION_UA from inside the block
|
|
417
|
+
# caches it, so we don't re-run a blocking metadata query on every produce(partition_key:)
|
|
418
|
+
# to that topic. Anything else is a real error and is re-raised.
|
|
419
|
+
raise(e) unless e.code == :unknown_topic_or_part
|
|
420
|
+
|
|
421
|
+
Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
405
422
|
end
|
|
406
|
-
rescue Rdkafka::RdkafkaError => e
|
|
407
|
-
# If the topic does not exist, it will be created or if not allowed another error will be
|
|
408
|
-
# raised. We here return RD_KAFKA_PARTITION_UA so this can happen without early error
|
|
409
|
-
# happening on metadata discovery.
|
|
410
|
-
return Rdkafka::Bindings::RD_KAFKA_PARTITION_UA if e.code == :unknown_topic_or_part
|
|
411
|
-
|
|
412
|
-
raise(e)
|
|
413
423
|
end
|
|
414
424
|
|
|
415
425
|
# Produces a message to a Kafka topic. The message is added to rdkafka's queue, call {DeliveryHandle#wait wait} on the returned delivery handle to make sure it is delivered.
|
|
@@ -511,24 +521,39 @@ module Rdkafka
|
|
|
511
521
|
delivery_handle[:offset] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
|
|
512
522
|
DeliveryHandle.register(delivery_handle)
|
|
513
523
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
524
|
+
# Everything between registration and the successful return must remove the handle from the
|
|
525
|
+
# process-global registry if it raises. Otherwise a failure after registration (a concurrent
|
|
526
|
+
# close making `with_inner` raise `ClosedInnerError`, or a header value whose `#to_s` raises)
|
|
527
|
+
# would orphan the handle in the registry forever, since nothing else will ever resolve it.
|
|
528
|
+
begin
|
|
529
|
+
args = [
|
|
530
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_RKT, :pointer, topic_ref,
|
|
531
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_MSGFLAGS, :int, Rdkafka::Bindings::RD_KAFKA_MSG_F_COPY,
|
|
532
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_VALUE, :buffer_in, payload, :size_t, payload_size,
|
|
533
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_KEY, :buffer_in, key, :size_t, key_size,
|
|
534
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_PARTITION, :int32, partition,
|
|
535
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_TIMESTAMP, :int64, raw_timestamp,
|
|
536
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_OPAQUE, :pointer, delivery_handle
|
|
537
|
+
]
|
|
538
|
+
|
|
539
|
+
if headers && !headers.empty?
|
|
540
|
+
headers.each do |key0, value0|
|
|
541
|
+
key = key0.to_s
|
|
542
|
+
case value0
|
|
543
|
+
when Array
|
|
544
|
+
# Handle array of values per KIP-82
|
|
545
|
+
value0.each do |v|
|
|
546
|
+
value = v.to_s
|
|
547
|
+
args.push(
|
|
548
|
+
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER,
|
|
549
|
+
:string, key,
|
|
550
|
+
:pointer, value,
|
|
551
|
+
:size_t, value.bytesize
|
|
552
|
+
)
|
|
553
|
+
end
|
|
554
|
+
else
|
|
555
|
+
# Handle single value
|
|
556
|
+
value = value0.to_s
|
|
532
557
|
args.push(
|
|
533
558
|
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER,
|
|
534
559
|
:string, key,
|
|
@@ -536,36 +561,31 @@ module Rdkafka
|
|
|
536
561
|
:size_t, value.bytesize
|
|
537
562
|
)
|
|
538
563
|
end
|
|
539
|
-
else
|
|
540
|
-
# Handle single value
|
|
541
|
-
value = value0.to_s
|
|
542
|
-
args.push(
|
|
543
|
-
:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_HEADER,
|
|
544
|
-
:string, key,
|
|
545
|
-
:pointer, value,
|
|
546
|
-
:size_t, value.bytesize
|
|
547
|
-
)
|
|
548
564
|
end
|
|
549
565
|
end
|
|
550
|
-
end
|
|
551
566
|
|
|
552
|
-
|
|
567
|
+
args.push(:int, Rdkafka::Bindings::RD_KAFKA_VTYPE_END)
|
|
553
568
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
569
|
+
# Produce the message
|
|
570
|
+
response = @native_kafka.with_inner do |inner|
|
|
571
|
+
Rdkafka::Bindings.rd_kafka_producev(
|
|
572
|
+
inner,
|
|
573
|
+
*args
|
|
574
|
+
)
|
|
575
|
+
end
|
|
561
576
|
|
|
562
|
-
|
|
563
|
-
|
|
577
|
+
# Raise error if the produce call was not successful. On a successful enqueue the handle
|
|
578
|
+
# stays registered on purpose: the delivery callback resolves and removes it once librdkafka
|
|
579
|
+
# reports the delivery.
|
|
580
|
+
if response != Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
|
|
581
|
+
@native_kafka.with_inner do |inner|
|
|
582
|
+
Rdkafka::RdkafkaError.validate!(response, client_ptr: inner)
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
rescue Exception
|
|
564
586
|
DeliveryHandle.remove(delivery_handle.to_ptr.address)
|
|
565
587
|
|
|
566
|
-
|
|
567
|
-
Rdkafka::RdkafkaError.validate!(response, client_ptr: inner)
|
|
568
|
-
end
|
|
588
|
+
raise
|
|
569
589
|
end
|
|
570
590
|
|
|
571
591
|
delivery_handle
|
|
@@ -607,5 +627,6 @@ module Rdkafka
|
|
|
607
627
|
def closed_producer_check(method)
|
|
608
628
|
raise Rdkafka::ClosedProducerError.new(method) if closed?
|
|
609
629
|
end
|
|
630
|
+
alias_method :closed_check, :closed_producer_check
|
|
610
631
|
end
|
|
611
632
|
end
|
data/lib/rdkafka/version.rb
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Rdkafka
|
|
4
4
|
# Current rdkafka-ruby gem version
|
|
5
|
-
VERSION = "0.
|
|
5
|
+
VERSION = "0.28.0"
|
|
6
6
|
# Target librdkafka version to be used
|
|
7
|
-
LIBRDKAFKA_VERSION = "2.14.
|
|
7
|
+
LIBRDKAFKA_VERSION = "2.14.2"
|
|
8
8
|
# SHA256 hash of the librdkafka source tarball for verification
|
|
9
|
-
LIBRDKAFKA_SOURCE_SHA256 = "
|
|
9
|
+
LIBRDKAFKA_SOURCE_SHA256 = "d7eec9c31c817fa44402f679c252dfbf97e4c338a849a25c3579a31fd127beb8"
|
|
10
10
|
end
|
data/lib/rdkafka.rb
CHANGED
|
@@ -9,6 +9,8 @@ require "rdkafka/version"
|
|
|
9
9
|
require "rdkafka/defaults"
|
|
10
10
|
require "rdkafka/helpers/time"
|
|
11
11
|
require "rdkafka/helpers/oauth"
|
|
12
|
+
require "rdkafka/helpers/metadata"
|
|
13
|
+
require "rdkafka/helpers/list_offsets"
|
|
12
14
|
require "rdkafka/abstract_handle"
|
|
13
15
|
require "rdkafka/admin"
|
|
14
16
|
require "rdkafka/admin/create_topic_handle"
|
|
@@ -36,6 +38,17 @@ require "rdkafka/admin/config_binding_result"
|
|
|
36
38
|
require "rdkafka/admin/config_resource_binding_result"
|
|
37
39
|
require "rdkafka/bindings"
|
|
38
40
|
require "rdkafka/callbacks"
|
|
41
|
+
require "rdkafka/callbacks/base_handler"
|
|
42
|
+
require "rdkafka/callbacks/create_topic_handler"
|
|
43
|
+
require "rdkafka/callbacks/delete_topic_handler"
|
|
44
|
+
require "rdkafka/callbacks/create_partitions_handler"
|
|
45
|
+
require "rdkafka/callbacks/delete_groups_handler"
|
|
46
|
+
require "rdkafka/callbacks/create_acl_handler"
|
|
47
|
+
require "rdkafka/callbacks/delete_acl_handler"
|
|
48
|
+
require "rdkafka/callbacks/describe_acl_handler"
|
|
49
|
+
require "rdkafka/callbacks/describe_configs_handler"
|
|
50
|
+
require "rdkafka/callbacks/incremental_alter_configs_handler"
|
|
51
|
+
require "rdkafka/callbacks/list_offsets_handler"
|
|
39
52
|
require "rdkafka/config"
|
|
40
53
|
require "rdkafka/consumer"
|
|
41
54
|
require "rdkafka/consumer/headers"
|
data/package-lock.json
CHANGED
|
@@ -286,9 +286,9 @@
|
|
|
286
286
|
}
|
|
287
287
|
},
|
|
288
288
|
"node_modules/smol-toml": {
|
|
289
|
-
"version": "1.
|
|
290
|
-
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.
|
|
291
|
-
"integrity": "sha512-
|
|
289
|
+
"version": "1.7.0",
|
|
290
|
+
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz",
|
|
291
|
+
"integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==",
|
|
292
292
|
"dev": true,
|
|
293
293
|
"license": "BSD-3-Clause",
|
|
294
294
|
"engines": {
|
|
@@ -312,9 +312,9 @@
|
|
|
312
312
|
}
|
|
313
313
|
},
|
|
314
314
|
"node_modules/yaml": {
|
|
315
|
-
"version": "2.
|
|
316
|
-
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.
|
|
317
|
-
"integrity": "sha512-
|
|
315
|
+
"version": "2.9.0",
|
|
316
|
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
|
|
317
|
+
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
|
|
318
318
|
"dev": true,
|
|
319
319
|
"license": "ISC",
|
|
320
320
|
"bin": {
|
data/renovate.json
CHANGED
|
@@ -87,12 +87,22 @@
|
|
|
87
87
|
],
|
|
88
88
|
"groupName": "ruby setup",
|
|
89
89
|
"internalChecksFilter": "strict"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"description": "Let setup-ruby pass age gate before ruby so it is ready when the group PR is created",
|
|
93
|
+
"matchPackageNames": [
|
|
94
|
+
"ruby/setup-ruby"
|
|
95
|
+
],
|
|
96
|
+
"minimumReleaseAge": "5 days"
|
|
90
97
|
}
|
|
91
98
|
],
|
|
92
99
|
"labels": [
|
|
93
100
|
"dependencies"
|
|
94
101
|
],
|
|
95
102
|
"lockFileMaintenance": {
|
|
96
|
-
"enabled": true
|
|
103
|
+
"enabled": true,
|
|
104
|
+
"schedule": [
|
|
105
|
+
"before 4am on the first day of the month"
|
|
106
|
+
]
|
|
97
107
|
}
|
|
98
108
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: karafka-rdkafka
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.28.0
|
|
5
5
|
platform: aarch64-linux-gnu
|
|
6
6
|
authors:
|
|
7
7
|
- Thijs Cadier
|
|
@@ -88,9 +88,6 @@ extensions: []
|
|
|
88
88
|
extra_rdoc_files: []
|
|
89
89
|
files:
|
|
90
90
|
- CHANGELOG.md
|
|
91
|
-
- Gemfile
|
|
92
|
-
- Gemfile.lint
|
|
93
|
-
- Gemfile.lint.lock
|
|
94
91
|
- MIT-LICENSE
|
|
95
92
|
- README.md
|
|
96
93
|
- Rakefile
|
|
@@ -127,6 +124,17 @@ files:
|
|
|
127
124
|
- lib/rdkafka/admin/list_offsets_report.rb
|
|
128
125
|
- lib/rdkafka/bindings.rb
|
|
129
126
|
- lib/rdkafka/callbacks.rb
|
|
127
|
+
- lib/rdkafka/callbacks/base_handler.rb
|
|
128
|
+
- lib/rdkafka/callbacks/create_acl_handler.rb
|
|
129
|
+
- lib/rdkafka/callbacks/create_partitions_handler.rb
|
|
130
|
+
- lib/rdkafka/callbacks/create_topic_handler.rb
|
|
131
|
+
- lib/rdkafka/callbacks/delete_acl_handler.rb
|
|
132
|
+
- lib/rdkafka/callbacks/delete_groups_handler.rb
|
|
133
|
+
- lib/rdkafka/callbacks/delete_topic_handler.rb
|
|
134
|
+
- lib/rdkafka/callbacks/describe_acl_handler.rb
|
|
135
|
+
- lib/rdkafka/callbacks/describe_configs_handler.rb
|
|
136
|
+
- lib/rdkafka/callbacks/incremental_alter_configs_handler.rb
|
|
137
|
+
- lib/rdkafka/callbacks/list_offsets_handler.rb
|
|
130
138
|
- lib/rdkafka/config.rb
|
|
131
139
|
- lib/rdkafka/consumer.rb
|
|
132
140
|
- lib/rdkafka/consumer/headers.rb
|
|
@@ -135,6 +143,8 @@ files:
|
|
|
135
143
|
- lib/rdkafka/consumer/topic_partition_list.rb
|
|
136
144
|
- lib/rdkafka/defaults.rb
|
|
137
145
|
- lib/rdkafka/error.rb
|
|
146
|
+
- lib/rdkafka/helpers/list_offsets.rb
|
|
147
|
+
- lib/rdkafka/helpers/metadata.rb
|
|
138
148
|
- lib/rdkafka/helpers/oauth.rb
|
|
139
149
|
- lib/rdkafka/helpers/time.rb
|
|
140
150
|
- lib/rdkafka/metadata.rb
|
data/Gemfile
DELETED
data/Gemfile.lint
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
source "https://rubygems.org"
|
|
4
|
-
|
|
5
|
-
# Documentation linting
|
|
6
|
-
gem "yard-lint"
|
|
7
|
-
|
|
8
|
-
# Code style (StandardRB via RuboCop)
|
|
9
|
-
gem "standard"
|
|
10
|
-
gem "standard-performance"
|
|
11
|
-
gem "rubocop-performance"
|
|
12
|
-
gem "rubocop-rspec"
|
|
13
|
-
gem "standard-rspec"
|
|
14
|
-
gem "rubocop-thread_safety"
|