karafka-rdkafka 0.30.0 → 0.30.1
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 +3 -0
- data/lib/rdkafka/bindings.rb +12 -0
- data/lib/rdkafka/share_consumer.rb +20 -5
- data/lib/rdkafka/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a0e958e572e7b8e0c56325da653e4635b1dc296868d531f237ec1d275c75d207
|
|
4
|
+
data.tar.gz: 2ca9f29779c17216cc815ec759cf2a04a0f8c631718f530810aa13b76183cadc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6d1fa15d28c82fb010b8c2a435285a39358a44973f022c6e0a6cbde422dcacf5ef79ac8ccd92a1dc91c17da799c147413e1555f5450a555e6401b9e2f2fcac75
|
|
7
|
+
data.tar.gz: 1523595543d9af2b27194492cf88bf2c37bda387009b49d3c9293c00efdb9d6db425657c60184739535ec89bd30dc86102b88cc6b24d26640e73021f36cf0760
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Rdkafka Changelog
|
|
2
2
|
|
|
3
|
+
## 0.30.1 (2026-09-30)
|
|
4
|
+
- [Fix] Derive `ShareConsumer#name` from the native handle at creation (mirroring `Consumer#name`) instead of leaving it `nil` until an OAuthBearer callback happened to set it. A `nil` name meant downstreams that route the global statistics and error callbacks by client name (e.g. Karafka) silently dropped every share-consumer statistic and background error.
|
|
5
|
+
|
|
3
6
|
## 0.30.0 (2026-09-25)
|
|
4
7
|
- [Fix] Register share consumers in `Rdkafka::Clients` and destroy the native handle when `Config#share_consumer` fails part-way. Share consumers own the native handle directly rather than a `NativeKafka` wrapper, so they bypass `build_native_client` and were missed by the `at_exit` shutdown hook, leaving librdkafka to be unloaded with a live share handle.
|
|
5
8
|
- [Feature] Add preview support for KIP-932 share groups ("Queues for Kafka") via `Rdkafka::ShareConsumer`, created with `Config#share_consumer`. Members consume the same partitions cooperatively with per-record acknowledgements (`:accept`, `:release`, `:reject`) instead of committed offsets. Like the regular `Consumer`, `ShareConsumer` is a thin binding that exposes the librdkafka share primitives (`#subscribe`/`#unsubscribe`/`#subscription`, batch `#poll`, `#acknowledge`, `#commit_sync`, `#commit_async`, `#acknowledgement_commit_callback=`, `#close`) but drives none of them itself - there is no built-in poll loop, acknowledgement strategy or offset/lifecycle orchestration, leaving that to a higher layer such as Karafka. The handle is single-threaded by design, servicing log, statistics and error callbacks from within `#poll`. Requires a broker with share groups enabled (Apache Kafka 4.2.0+); librdkafka marks the feature as preview and not production-ready.
|
data/lib/rdkafka/bindings.rb
CHANGED
|
@@ -517,6 +517,18 @@ module Rdkafka
|
|
|
517
517
|
# rd_kafka_share_consumer_new instead of rd_kafka_new. It is single-threaded by design and
|
|
518
518
|
# librdkafka itself rejects concurrent access with RD_KAFKA_RESP_ERR__CONFLICT.
|
|
519
519
|
|
|
520
|
+
# Minimal mirror of the head of librdkafka's `struct rd_kafka_share_s`, whose first member is
|
|
521
|
+
# the wrapped `rd_kafka_t` (`rkshare_rk`). `rd_kafka_share_t` has no public accessors of its
|
|
522
|
+
# own - not even for the client name - but the handle it wraps is a normal `rd_kafka_t` and is
|
|
523
|
+
# the very handle librdkafka passes to the statistics, error and OAuthBearer callbacks. Reading
|
|
524
|
+
# it lets a share consumer report a name that matches its statistics `name` field, which
|
|
525
|
+
# `rd_kafka_name` cannot do when handed the `rd_kafka_share_t` directly (it would read an
|
|
526
|
+
# unrelated field and return garbage). This mirrors how the gem already maps other librdkafka
|
|
527
|
+
# structs by layout for the pinned librdkafka version.
|
|
528
|
+
class NativeShareConsumer < FFI::Struct
|
|
529
|
+
layout :rkshare_rk, :pointer
|
|
530
|
+
end
|
|
531
|
+
|
|
520
532
|
# Acknowledge types for share consumer records
|
|
521
533
|
RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_ACCEPT = 1
|
|
522
534
|
RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_RELEASE = 2
|
|
@@ -57,14 +57,17 @@ module Rdkafka
|
|
|
57
57
|
private_constant :State
|
|
58
58
|
|
|
59
59
|
# The client name librdkafka reports for this consumer (e.g. "rdkafka#consumer-1"), used to
|
|
60
|
-
# correlate global callbacks (
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
60
|
+
# correlate the global callbacks (statistics, error and the OAuthBearer token refresh
|
|
61
|
+
# callback, all of which carry the client name) with this instance. Captured from the native
|
|
62
|
+
# handle when the consumer is created, so it is available immediately - before the first
|
|
63
|
+
# {#poll} and without OAuth configured - and stays readable after the consumer is closed or
|
|
64
|
+
# inherited by a forked child.
|
|
65
|
+
# @return [String] the librdkafka client name
|
|
64
66
|
attr_reader :name
|
|
65
67
|
|
|
66
68
|
# @private
|
|
67
|
-
#
|
|
69
|
+
# Lets the OAuthBearer token refresh callback set the name from its callback context. It
|
|
70
|
+
# carries the same `rd_kafka_name` value already captured at creation, so both paths agree.
|
|
68
71
|
attr_writer :name
|
|
69
72
|
|
|
70
73
|
# @private
|
|
@@ -80,6 +83,18 @@ module Rdkafka
|
|
|
80
83
|
# every teardown path can skip the native destroy in a forked child (librdkafka is not
|
|
81
84
|
# fork-safe).
|
|
82
85
|
@state = State.new(native, nil, Process.pid)
|
|
86
|
+
# Capture the librdkafka client name up front. It is needed to correlate this consumer with
|
|
87
|
+
# the global statistics and error callbacks (which carry the client name) - the common
|
|
88
|
+
# downstream pattern (e.g. Karafka) filters those broadcast callbacks by matching `name`.
|
|
89
|
+
#
|
|
90
|
+
# `rd_kafka_name` has no `rd_kafka_share_t` overload: handing it the share handle reads an
|
|
91
|
+
# unrelated field and returns garbage. The share handle's first member is the `rd_kafka_t`
|
|
92
|
+
# it wraps (`rkshare_rk`), which is the same handle librdkafka passes to those callbacks, so
|
|
93
|
+
# the name read from it matches the statistics `name` field. Capturing it here (rather than
|
|
94
|
+
# lazily like the regular consumer) keeps it available before the first poll, without OAuth,
|
|
95
|
+
# and after close or in a forked child, where the native handle must not be touched.
|
|
96
|
+
# librdkafka assigns the name at creation, so no broker connection is required.
|
|
97
|
+
@name = Rdkafka::Bindings.rd_kafka_name(Rdkafka::Bindings::NativeShareConsumer.new(native)[:rkshare_rk])
|
|
83
98
|
# Guards handle teardown against in-flight calls: increments happen under this mutex and
|
|
84
99
|
# close holds it while draining and destroying (mirrors NativeKafka's approach)
|
|
85
100
|
@access_mutex = Mutex.new
|
data/lib/rdkafka/version.rb
CHANGED