@ohos-ports/confluentinc-kafka-javascript 1.10.0-beta.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.
- package/CHANGELOG.md +457 -0
- package/LICENSE.kafkajs +31 -0
- package/LICENSE.node-rdkafka +25 -0
- package/LICENSE.txt +20 -0
- package/README.md +133 -0
- package/binding.gyp +184 -0
- package/build/Release/confluent-kafka-javascript.node +0 -0
- package/build/deps/librdkafka++.so.1 +0 -0
- package/build/deps/librdkafka.Makefile +6 -0
- package/build/deps/librdkafka.so.1 +0 -0
- package/build/deps/librdkafka.target.mk +55 -0
- package/deps/librdkafka/.clang-format +136 -0
- package/deps/librdkafka/.clang-format-cpp +103 -0
- package/deps/librdkafka/.dir-locals.el +10 -0
- package/deps/librdkafka/.formatignore +35 -0
- package/deps/librdkafka/.gdbmacros +19 -0
- package/deps/librdkafka/CHANGELOG.md +2477 -0
- package/deps/librdkafka/CMakeLists.txt +291 -0
- package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
- package/deps/librdkafka/CONFIGURATION.md +212 -0
- package/deps/librdkafka/CONTRIBUTING.md +431 -0
- package/deps/librdkafka/Doxyfile +2375 -0
- package/deps/librdkafka/INTRODUCTION.md +2752 -0
- package/deps/librdkafka/LICENSE +26 -0
- package/deps/librdkafka/LICENSE.cjson +22 -0
- package/deps/librdkafka/LICENSE.crc32c +28 -0
- package/deps/librdkafka/LICENSE.fnv1a +18 -0
- package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
- package/deps/librdkafka/LICENSE.lz4 +26 -0
- package/deps/librdkafka/LICENSE.murmur2 +25 -0
- package/deps/librdkafka/LICENSE.nanopb +22 -0
- package/deps/librdkafka/LICENSE.opentelemetry +203 -0
- package/deps/librdkafka/LICENSE.pycrc +23 -0
- package/deps/librdkafka/LICENSE.queue +31 -0
- package/deps/librdkafka/LICENSE.regexp +5 -0
- package/deps/librdkafka/LICENSE.snappy +36 -0
- package/deps/librdkafka/LICENSE.tinycthread +26 -0
- package/deps/librdkafka/LICENSE.wingetopt +49 -0
- package/deps/librdkafka/LICENSES.txt +625 -0
- package/deps/librdkafka/Makefile +125 -0
- package/deps/librdkafka/README.md +201 -0
- package/deps/librdkafka/README.win32 +26 -0
- package/deps/librdkafka/STATISTICS.md +624 -0
- package/deps/librdkafka/configure +214 -0
- package/deps/librdkafka/configure.self +341 -0
- package/deps/librdkafka/dev-conf.sh +123 -0
- package/deps/librdkafka/lds-gen.py +73 -0
- package/deps/librdkafka/mainpage.doxy +40 -0
- package/deps/librdkafka/mklove/Makefile.base +329 -0
- package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
- package/deps/librdkafka/mklove/modules/configure.base +2484 -0
- package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
- package/deps/librdkafka/mklove/modules/configure.cc +186 -0
- package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
- package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
- package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
- package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
- package/deps/librdkafka/mklove/modules/configure.host +132 -0
- package/deps/librdkafka/mklove/modules/configure.lib +49 -0
- package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
- package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
- package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
- package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
- package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
- package/deps/librdkafka/mklove/modules/configure.pic +16 -0
- package/deps/librdkafka/mklove/modules/configure.socket +20 -0
- package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
- package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
- package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
- package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
- package/deps/librdkafka/service.yml +182 -0
- package/deps/librdkafka/src/CMakeLists.txt +379 -0
- package/deps/librdkafka/src/Makefile +105 -0
- package/deps/librdkafka/src/README.lz4.md +30 -0
- package/deps/librdkafka/src/cJSON.c +3191 -0
- package/deps/librdkafka/src/cJSON.h +306 -0
- package/deps/librdkafka/src/crc32c.c +430 -0
- package/deps/librdkafka/src/crc32c.h +38 -0
- package/deps/librdkafka/src/generate_proto.sh +66 -0
- package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
- package/deps/librdkafka/src/lz4.c +2727 -0
- package/deps/librdkafka/src/lz4.h +842 -0
- package/deps/librdkafka/src/lz4frame.c +2078 -0
- package/deps/librdkafka/src/lz4frame.h +692 -0
- package/deps/librdkafka/src/lz4frame_static.h +47 -0
- package/deps/librdkafka/src/lz4hc.c +1631 -0
- package/deps/librdkafka/src/lz4hc.h +413 -0
- package/deps/librdkafka/src/nanopb/pb.h +917 -0
- package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
- package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
- package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
- package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
- package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
- package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
- package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
- package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
- package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
- package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
- package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
- package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
- package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
- package/deps/librdkafka/src/queue.h +850 -0
- package/deps/librdkafka/src/rd.h +592 -0
- package/deps/librdkafka/src/rdaddr.c +255 -0
- package/deps/librdkafka/src/rdaddr.h +202 -0
- package/deps/librdkafka/src/rdatomic.h +262 -0
- package/deps/librdkafka/src/rdavg.h +260 -0
- package/deps/librdkafka/src/rdavl.c +210 -0
- package/deps/librdkafka/src/rdavl.h +250 -0
- package/deps/librdkafka/src/rdbase64.c +200 -0
- package/deps/librdkafka/src/rdbase64.h +43 -0
- package/deps/librdkafka/src/rdbuf.c +1884 -0
- package/deps/librdkafka/src/rdbuf.h +375 -0
- package/deps/librdkafka/src/rdcrc32.c +114 -0
- package/deps/librdkafka/src/rdcrc32.h +170 -0
- package/deps/librdkafka/src/rddl.c +179 -0
- package/deps/librdkafka/src/rddl.h +43 -0
- package/deps/librdkafka/src/rdendian.h +175 -0
- package/deps/librdkafka/src/rdfloat.h +67 -0
- package/deps/librdkafka/src/rdfnv1a.c +113 -0
- package/deps/librdkafka/src/rdfnv1a.h +35 -0
- package/deps/librdkafka/src/rdgz.c +120 -0
- package/deps/librdkafka/src/rdgz.h +46 -0
- package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
- package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
- package/deps/librdkafka/src/rdhttp.c +831 -0
- package/deps/librdkafka/src/rdhttp.h +101 -0
- package/deps/librdkafka/src/rdinterval.h +177 -0
- package/deps/librdkafka/src/rdkafka.c +7287 -0
- package/deps/librdkafka/src/rdkafka.h +11795 -0
- package/deps/librdkafka/src/rdkafka_admin.c +10165 -0
- package/deps/librdkafka/src/rdkafka_admin.h +658 -0
- package/deps/librdkafka/src/rdkafka_assignment.c +1282 -0
- package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
- package/deps/librdkafka/src/rdkafka_assignor.c +1800 -0
- package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
- package/deps/librdkafka/src/rdkafka_aux.c +409 -0
- package/deps/librdkafka/src/rdkafka_aux.h +174 -0
- package/deps/librdkafka/src/rdkafka_background.c +222 -0
- package/deps/librdkafka/src/rdkafka_broker.c +6736 -0
- package/deps/librdkafka/src/rdkafka_broker.h +851 -0
- package/deps/librdkafka/src/rdkafka_buf.c +543 -0
- package/deps/librdkafka/src/rdkafka_buf.h +1525 -0
- package/deps/librdkafka/src/rdkafka_cert.c +576 -0
- package/deps/librdkafka/src/rdkafka_cert.h +62 -0
- package/deps/librdkafka/src/rdkafka_cgrp.c +8310 -0
- package/deps/librdkafka/src/rdkafka_cgrp.h +589 -0
- package/deps/librdkafka/src/rdkafka_conf.c +5177 -0
- package/deps/librdkafka/src/rdkafka_conf.h +746 -0
- package/deps/librdkafka/src/rdkafka_confval.h +97 -0
- package/deps/librdkafka/src/rdkafka_coord.c +623 -0
- package/deps/librdkafka/src/rdkafka_coord.h +132 -0
- package/deps/librdkafka/src/rdkafka_error.c +228 -0
- package/deps/librdkafka/src/rdkafka_error.h +80 -0
- package/deps/librdkafka/src/rdkafka_event.c +502 -0
- package/deps/librdkafka/src/rdkafka_event.h +126 -0
- package/deps/librdkafka/src/rdkafka_feature.c +898 -0
- package/deps/librdkafka/src/rdkafka_feature.h +104 -0
- package/deps/librdkafka/src/rdkafka_fetcher.c +3820 -0
- package/deps/librdkafka/src/rdkafka_fetcher.h +62 -0
- package/deps/librdkafka/src/rdkafka_header.c +220 -0
- package/deps/librdkafka/src/rdkafka_header.h +76 -0
- package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
- package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
- package/deps/librdkafka/src/rdkafka_int.h +1505 -0
- package/deps/librdkafka/src/rdkafka_interceptor.c +842 -0
- package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
- package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
- package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
- package/deps/librdkafka/src/rdkafka_metadata.c +2347 -0
- package/deps/librdkafka/src/rdkafka_metadata.h +350 -0
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
- package/deps/librdkafka/src/rdkafka_mock.c +4514 -0
- package/deps/librdkafka/src/rdkafka_mock.h +867 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1877 -0
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +5255 -0
- package/deps/librdkafka/src/rdkafka_mock_int.h +1005 -0
- package/deps/librdkafka/src/rdkafka_mock_sharegrp.c +1207 -0
- package/deps/librdkafka/src/rdkafka_msg.c +2619 -0
- package/deps/librdkafka/src/rdkafka_msg.h +629 -0
- package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
- package/deps/librdkafka/src/rdkafka_msgset.h +105 -0
- package/deps/librdkafka/src/rdkafka_msgset_reader.c +2099 -0
- package/deps/librdkafka/src/rdkafka_msgset_writer.c +1474 -0
- package/deps/librdkafka/src/rdkafka_offset.c +1565 -0
- package/deps/librdkafka/src/rdkafka_offset.h +150 -0
- package/deps/librdkafka/src/rdkafka_op.c +1219 -0
- package/deps/librdkafka/src/rdkafka_op.h +1065 -0
- package/deps/librdkafka/src/rdkafka_partition.c +5109 -0
- package/deps/librdkafka/src/rdkafka_partition.h +1215 -0
- package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
- package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
- package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
- package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
- package/deps/librdkafka/src/rdkafka_proto.h +739 -0
- package/deps/librdkafka/src/rdkafka_protocol.h +131 -0
- package/deps/librdkafka/src/rdkafka_queue.c +1351 -0
- package/deps/librdkafka/src/rdkafka_queue.h +1235 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
- package/deps/librdkafka/src/rdkafka_request.c +7298 -0
- package/deps/librdkafka/src/rdkafka_request.h +761 -0
- package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
- package/deps/librdkafka/src/rdkafka_sasl.c +589 -0
- package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
- package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
- package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1833 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1827 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +52 -0
- package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
- package/deps/librdkafka/src/rdkafka_sasl_scram.c +858 -0
- package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
- package/deps/librdkafka/src/rdkafka_share_acknowledgement.c +1445 -0
- package/deps/librdkafka/src/rdkafka_share_acknowledgement.h +373 -0
- package/deps/librdkafka/src/rdkafka_ssl.c +2235 -0
- package/deps/librdkafka/src/rdkafka_ssl.h +86 -0
- package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4785 -0
- package/deps/librdkafka/src/rdkafka_subscription.c +411 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +761 -0
- package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1307 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +1309 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +459 -0
- package/deps/librdkafka/src/rdkafka_timer.c +407 -0
- package/deps/librdkafka/src/rdkafka_timer.h +117 -0
- package/deps/librdkafka/src/rdkafka_topic.c +2382 -0
- package/deps/librdkafka/src/rdkafka_topic.h +369 -0
- package/deps/librdkafka/src/rdkafka_transport.c +1309 -0
- package/deps/librdkafka/src/rdkafka_transport.h +99 -0
- package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.c +3256 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
- package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
- package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
- package/deps/librdkafka/src/rdlist.c +593 -0
- package/deps/librdkafka/src/rdlist.h +444 -0
- package/deps/librdkafka/src/rdlog.c +89 -0
- package/deps/librdkafka/src/rdlog.h +41 -0
- package/deps/librdkafka/src/rdmap.c +508 -0
- package/deps/librdkafka/src/rdmap.h +492 -0
- package/deps/librdkafka/src/rdmurmur2.c +167 -0
- package/deps/librdkafka/src/rdmurmur2.h +35 -0
- package/deps/librdkafka/src/rdports.c +61 -0
- package/deps/librdkafka/src/rdports.h +38 -0
- package/deps/librdkafka/src/rdposix.h +250 -0
- package/deps/librdkafka/src/rdrand.c +151 -0
- package/deps/librdkafka/src/rdrand.h +72 -0
- package/deps/librdkafka/src/rdregex.c +156 -0
- package/deps/librdkafka/src/rdregex.h +43 -0
- package/deps/librdkafka/src/rdsignal.h +57 -0
- package/deps/librdkafka/src/rdstring.c +645 -0
- package/deps/librdkafka/src/rdstring.h +98 -0
- package/deps/librdkafka/src/rdsysqueue.h +404 -0
- package/deps/librdkafka/src/rdtime.h +356 -0
- package/deps/librdkafka/src/rdtypes.h +86 -0
- package/deps/librdkafka/src/rdunittest.c +564 -0
- package/deps/librdkafka/src/rdunittest.h +232 -0
- package/deps/librdkafka/src/rdunittest_acknowledge.c +1177 -0
- package/deps/librdkafka/src/rdunittest_fetcher.c +1211 -0
- package/deps/librdkafka/src/rdunittest_msgset_errors.c +1521 -0
- package/deps/librdkafka/src/rdvarint.c +134 -0
- package/deps/librdkafka/src/rdvarint.h +165 -0
- package/deps/librdkafka/src/rdwin32.h +382 -0
- package/deps/librdkafka/src/rdxxhash.c +1030 -0
- package/deps/librdkafka/src/rdxxhash.h +328 -0
- package/deps/librdkafka/src/regexp.c +1352 -0
- package/deps/librdkafka/src/regexp.h +41 -0
- package/deps/librdkafka/src/snappy.c +1866 -0
- package/deps/librdkafka/src/snappy.h +62 -0
- package/deps/librdkafka/src/snappy_compat.h +138 -0
- package/deps/librdkafka/src/statistics_schema.json +444 -0
- package/deps/librdkafka/src/tinycthread.c +932 -0
- package/deps/librdkafka/src/tinycthread.h +503 -0
- package/deps/librdkafka/src/tinycthread_extra.c +210 -0
- package/deps/librdkafka/src/tinycthread_extra.h +218 -0
- package/deps/librdkafka/src/win32_config.h +58 -0
- package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
- package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
- package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
- package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
- package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
- package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
- package/deps/librdkafka/src-cpp/Makefile +55 -0
- package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
- package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
- package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
- package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
- package/deps/librdkafka/src-cpp/README.md +16 -0
- package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
- package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
- package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
- package/deps/librdkafka/src-cpp/rdkafkacpp.h +3797 -0
- package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
- package/deps/librdkafka/tests/0000-unittests.c +72 -0
- package/deps/librdkafka/tests/0001-multiobj.c +102 -0
- package/deps/librdkafka/tests/0002-unkpart.c +244 -0
- package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
- package/deps/librdkafka/tests/0004-conf.c +934 -0
- package/deps/librdkafka/tests/0005-order.c +133 -0
- package/deps/librdkafka/tests/0006-symbols.c +163 -0
- package/deps/librdkafka/tests/0007-autotopic.c +136 -0
- package/deps/librdkafka/tests/0008-reqacks.c +179 -0
- package/deps/librdkafka/tests/0009-mock_cluster.c +272 -0
- package/deps/librdkafka/tests/0011-produce_batch.c +753 -0
- package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
- package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
- package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
- package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
- package/deps/librdkafka/tests/0016-client_swname.c +181 -0
- package/deps/librdkafka/tests/0017-compression.c +140 -0
- package/deps/librdkafka/tests/0018-cgrp_term.c +444 -0
- package/deps/librdkafka/tests/0019-list_groups.c +289 -0
- package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
- package/deps/librdkafka/tests/0021-rkt_destroy.c +72 -0
- package/deps/librdkafka/tests/0022-consume_batch.c +331 -0
- package/deps/librdkafka/tests/0025-timers.c +147 -0
- package/deps/librdkafka/tests/0026-consume_pause.c +547 -0
- package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
- package/deps/librdkafka/tests/0029-assign_offset.c +202 -0
- package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
- package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
- package/deps/librdkafka/tests/0033-regex_subscribe.c +536 -0
- package/deps/librdkafka/tests/0034-offset_reset.c +398 -0
- package/deps/librdkafka/tests/0035-api_version.c +73 -0
- package/deps/librdkafka/tests/0036-partial_fetch.c +87 -0
- package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
- package/deps/librdkafka/tests/0038-performance.c +121 -0
- package/deps/librdkafka/tests/0039-event.c +284 -0
- package/deps/librdkafka/tests/0040-io_event.c +257 -0
- package/deps/librdkafka/tests/0041-fetch_max_bytes.c +97 -0
- package/deps/librdkafka/tests/0042-many_topics.c +252 -0
- package/deps/librdkafka/tests/0043-no_connection.c +77 -0
- package/deps/librdkafka/tests/0044-partition_cnt.c +94 -0
- package/deps/librdkafka/tests/0045-subscribe_update.c +1010 -0
- package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
- package/deps/librdkafka/tests/0047-partial_buf_tmout.c +98 -0
- package/deps/librdkafka/tests/0048-partitioner.c +283 -0
- package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
- package/deps/librdkafka/tests/0050-subscribe_adds.c +145 -0
- package/deps/librdkafka/tests/0051-assign_adds.c +126 -0
- package/deps/librdkafka/tests/0052-msg_timestamps.c +238 -0
- package/deps/librdkafka/tests/0053-stats_cb.cpp +527 -0
- package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
- package/deps/librdkafka/tests/0055-producer_latency.c +539 -0
- package/deps/librdkafka/tests/0056-balanced_group_mt.c +315 -0
- package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
- package/deps/librdkafka/tests/0058-log.cpp +123 -0
- package/deps/librdkafka/tests/0059-bsearch.cpp +241 -0
- package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
- package/deps/librdkafka/tests/0061-consumer_lag.cpp +295 -0
- package/deps/librdkafka/tests/0062-stats_event.c +126 -0
- package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
- package/deps/librdkafka/tests/0064-interceptors.c +529 -0
- package/deps/librdkafka/tests/0065-yield.cpp +140 -0
- package/deps/librdkafka/tests/0066-plugins.cpp +143 -0
- package/deps/librdkafka/tests/0067-empty_topic.cpp +151 -0
- package/deps/librdkafka/tests/0068-produce_timeout.c +136 -0
- package/deps/librdkafka/tests/0069-consumer_add_parts.c +119 -0
- package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
- package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
- package/deps/librdkafka/tests/0073-headers.c +381 -0
- package/deps/librdkafka/tests/0074-producev.c +87 -0
- package/deps/librdkafka/tests/0075-retry.c +290 -0
- package/deps/librdkafka/tests/0076-produce_retry.c +452 -0
- package/deps/librdkafka/tests/0077-compaction.c +366 -0
- package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
- package/deps/librdkafka/tests/0079-fork.c +93 -0
- package/deps/librdkafka/tests/0080-admin_ut.c +3095 -0
- package/deps/librdkafka/tests/0081-admin.c +5633 -0
- package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +137 -0
- package/deps/librdkafka/tests/0083-cb_event.c +233 -0
- package/deps/librdkafka/tests/0084-destroy_flags.c +208 -0
- package/deps/librdkafka/tests/0085-headers.cpp +392 -0
- package/deps/librdkafka/tests/0086-purge.c +368 -0
- package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
- package/deps/librdkafka/tests/0089-max_poll_interval.c +511 -0
- package/deps/librdkafka/tests/0090-idempotence.c +171 -0
- package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +295 -0
- package/deps/librdkafka/tests/0092-mixed_msgver.c +103 -0
- package/deps/librdkafka/tests/0093-holb.c +200 -0
- package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +231 -0
- package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
- package/deps/librdkafka/tests/0097-ssl_verify.cpp +674 -0
- package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
- package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
- package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
- package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
- package/deps/librdkafka/tests/0102-static_group_rebalance.c +836 -0
- package/deps/librdkafka/tests/0103-transactions.c +1383 -0
- package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +625 -0
- package/deps/librdkafka/tests/0105-transactions_mock.c +3930 -0
- package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +318 -0
- package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
- package/deps/librdkafka/tests/0109-auto_create_topics.cpp +278 -0
- package/deps/librdkafka/tests/0110-batch_size.cpp +182 -0
- package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
- package/deps/librdkafka/tests/0112-assign_unknown_part.c +87 -0
- package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3473 -0
- package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
- package/deps/librdkafka/tests/0115-producer_auth.cpp +182 -0
- package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +216 -0
- package/deps/librdkafka/tests/0117-mock_errors.c +331 -0
- package/deps/librdkafka/tests/0118-commit_rebalance.c +154 -0
- package/deps/librdkafka/tests/0119-consumer_auth.cpp +167 -0
- package/deps/librdkafka/tests/0120-asymmetric_subscription.c +185 -0
- package/deps/librdkafka/tests/0121-clusterid.c +115 -0
- package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
- package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
- package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
- package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
- package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +1164 -0
- package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
- package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +217 -0
- package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +79 -0
- package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
- package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
- package/deps/librdkafka/tests/0132-strategy_ordering.c +179 -0
- package/deps/librdkafka/tests/0133-ssl_keys.c +150 -0
- package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
- package/deps/librdkafka/tests/0135-sasl_credentials.cpp +279 -0
- package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +752 -0
- package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
- package/deps/librdkafka/tests/0139-offset_validation_mock.c +950 -0
- package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
- package/deps/librdkafka/tests/0142-reauthentication.c +931 -0
- package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +552 -0
- package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
- package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
- package/deps/librdkafka/tests/0146-metadata_mock.c +505 -0
- package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +1210 -0
- package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +569 -0
- package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
- package/deps/librdkafka/tests/0150-telemetry_mock.c +651 -0
- package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
- package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
- package/deps/librdkafka/tests/0153-memberid.c +128 -0
- package/deps/librdkafka/tests/0155-share_group_heartbeat_mock.c +2695 -0
- package/deps/librdkafka/tests/0156-share_consumer_fetch_mock.c +1551 -0
- package/deps/librdkafka/tests/0157-share_consumer_ack_mock.c +1788 -0
- package/deps/librdkafka/tests/0158-share_consumer_transactions_mock.c +467 -0
- package/deps/librdkafka/tests/0170-share_consumer_subscription.c +2192 -0
- package/deps/librdkafka/tests/0171-share_consumer_consume.c +2150 -0
- package/deps/librdkafka/tests/0172-share_consumer_acknowledge.c +1919 -0
- package/deps/librdkafka/tests/0173-share_consumer_commit_async.c +2735 -0
- package/deps/librdkafka/tests/0174-share_consumer_concurrency.c +1434 -0
- package/deps/librdkafka/tests/0175-share_consumer_groups.c +574 -0
- package/deps/librdkafka/tests/0176-share_consumer_commit_sync.c +2986 -0
- package/deps/librdkafka/tests/0177-share_consumer_transactions.c +1815 -0
- package/deps/librdkafka/tests/0178-share_consumer_close.c +2102 -0
- package/deps/librdkafka/tests/0179-share_consumer_destroy.c +2482 -0
- package/deps/librdkafka/tests/0180-share_consumer_config.c +1677 -0
- package/deps/librdkafka/tests/0181-share_consumer_topic_delete.c +354 -0
- package/deps/librdkafka/tests/0182-share_consumer_error_handling_mock.c +3358 -0
- package/deps/librdkafka/tests/0183-share_consumer_leader_change_mock.c +1234 -0
- package/deps/librdkafka/tests/0184-share_consumer_topic_recreate.c +1356 -0
- package/deps/librdkafka/tests/0185-share_consumer_max_poll_interval.c +557 -0
- package/deps/librdkafka/tests/0186-share_consumer_fatal_error.c +360 -0
- package/deps/librdkafka/tests/0190-share_consumer_telemetry.c +387 -0
- package/deps/librdkafka/tests/1000-unktopic.c +164 -0
- package/deps/librdkafka/tests/8000-idle.cpp +60 -0
- package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
- package/deps/librdkafka/tests/CMakeLists.txt +193 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
- package/deps/librdkafka/tests/Makefile +182 -0
- package/deps/librdkafka/tests/README.md +514 -0
- package/deps/librdkafka/tests/autotest.sh +33 -0
- package/deps/librdkafka/tests/backtrace.gdb +30 -0
- package/deps/librdkafka/tests/broker_version_tests.py +315 -0
- package/deps/librdkafka/tests/buildbox.sh +17 -0
- package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
- package/deps/librdkafka/tests/cluster_testing.py +203 -0
- package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
- package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
- package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
- package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +50 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +168 -0
- package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
- package/deps/librdkafka/tests/fuzzers/README.md +31 -0
- package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
- package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
- package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
- package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
- package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
- package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
- package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
- package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
- package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
- package/deps/librdkafka/tests/java/Makefile +13 -0
- package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
- package/deps/librdkafka/tests/java/README.md +14 -0
- package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
- package/deps/librdkafka/tests/java/run-class.sh +11 -0
- package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
- package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
- package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
- package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
- package/deps/librdkafka/tests/performance_plot.py +115 -0
- package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
- package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
- package/deps/librdkafka/tests/requirements.txt +2 -0
- package/deps/librdkafka/tests/run-all-tests.sh +81 -0
- package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
- package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
- package/deps/librdkafka/tests/run-test-batches.py +157 -0
- package/deps/librdkafka/tests/run-test.sh +141 -0
- package/deps/librdkafka/tests/rusage.c +249 -0
- package/deps/librdkafka/tests/sasl_test.py +289 -0
- package/deps/librdkafka/tests/scenarios/README.md +6 -0
- package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
- package/deps/librdkafka/tests/scenarios/default.json +5 -0
- package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
- package/deps/librdkafka/tests/share_telemetry_verify/share-otel-collector-config.yaml +28 -0
- package/deps/librdkafka/tests/sockem.c +801 -0
- package/deps/librdkafka/tests/sockem.h +85 -0
- package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
- package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
- package/deps/librdkafka/tests/test.c +8376 -0
- package/deps/librdkafka/tests/test.conf.example +27 -0
- package/deps/librdkafka/tests/test.h +1150 -0
- package/deps/librdkafka/tests/testcpp.cpp +131 -0
- package/deps/librdkafka/tests/testcpp.h +388 -0
- package/deps/librdkafka/tests/testshared.h +416 -0
- package/deps/librdkafka/tests/tools/README.md +4 -0
- package/deps/librdkafka/tests/tools/stats/README.md +21 -0
- package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
- package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
- package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
- package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
- package/deps/librdkafka/tests/trivup/trivup-0.15.0.tar.gz +0 -0
- package/deps/librdkafka/tests/until-fail.sh +87 -0
- package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
- package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
- package/deps/librdkafka/vcpkg.json +23 -0
- package/deps/librdkafka/win32/README.md +5 -0
- package/deps/librdkafka/win32/build-package.bat +3 -0
- package/deps/librdkafka/win32/build.bat +19 -0
- package/deps/librdkafka/win32/common.vcxproj +84 -0
- package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
- package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
- package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
- package/deps/librdkafka/win32/librdkafka.sln +226 -0
- package/deps/librdkafka/win32/librdkafka.vcxproj +282 -0
- package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
- package/deps/librdkafka/win32/msbuild.ps1 +58 -0
- package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
- package/deps/librdkafka/win32/package-zip.ps1 +46 -0
- package/deps/librdkafka/win32/packages/repositories.config +4 -0
- package/deps/librdkafka/win32/push-package.bat +4 -0
- package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
- package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
- package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
- package/deps/librdkafka/win32/setup-msys2.ps1 +47 -0
- package/deps/librdkafka/win32/setup-vcpkg.ps1 +34 -0
- package/deps/librdkafka/win32/tests/test.conf.example +25 -0
- package/deps/librdkafka/win32/tests/tests.vcxproj +278 -0
- package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
- package/deps/librdkafka/win32/wingetopt.c +564 -0
- package/deps/librdkafka/win32/wingetopt.h +101 -0
- package/deps/librdkafka/win32/wintime.h +33 -0
- package/deps/librdkafka.gyp +83 -0
- package/deps/windows-install.py +80 -0
- package/index.d.ts +3 -0
- package/lib/admin.js +732 -0
- package/lib/client.js +679 -0
- package/lib/error.js +501 -0
- package/lib/index.js +8 -0
- package/lib/kafka-consumer-stream.js +399 -0
- package/lib/kafka-consumer.js +798 -0
- package/lib/kafkajs/_admin.js +1052 -0
- package/lib/kafkajs/_common.js +887 -0
- package/lib/kafkajs/_consumer.js +2156 -0
- package/lib/kafkajs/_consumer_cache.js +310 -0
- package/lib/kafkajs/_error.js +298 -0
- package/lib/kafkajs/_kafka.js +125 -0
- package/lib/kafkajs/_linked-list.js +220 -0
- package/lib/kafkajs/_producer.js +863 -0
- package/lib/kafkajs/index.js +5 -0
- package/lib/producer/high-level-producer.js +400 -0
- package/lib/producer-stream.js +337 -0
- package/lib/producer.js +405 -0
- package/lib/rdkafka.js +44 -0
- package/lib/tools/ref-counter.js +53 -0
- package/lib/topic-partition.js +91 -0
- package/lib/topic.js +43 -0
- package/lib/util.js +55 -0
- package/librdkafka.js +12 -0
- package/package.json +85 -0
- package/shim/source_location +54 -0
- package/src/admin.cc +1597 -0
- package/src/admin.h +112 -0
- package/src/binding.cc +76 -0
- package/src/binding.h +25 -0
- package/src/callbacks.cc +676 -0
- package/src/callbacks.h +302 -0
- package/src/common.cc +1628 -0
- package/src/common.h +192 -0
- package/src/config.cc +219 -0
- package/src/config.h +61 -0
- package/src/connection.cc +703 -0
- package/src/connection.h +117 -0
- package/src/errors.cc +119 -0
- package/src/errors.h +60 -0
- package/src/kafka-consumer.cc +1539 -0
- package/src/kafka-consumer.h +147 -0
- package/src/producer.cc +917 -0
- package/src/producer.h +124 -0
- package/src/topic.cc +173 -0
- package/src/topic.h +54 -0
- package/src/workers.cc +1714 -0
- package/src/workers.h +690 -0
- package/types/config.d.ts +1269 -0
- package/types/errors.d.ts +373 -0
- package/types/kafkajs.d.ts +568 -0
- package/types/rdkafka.d.ts +571 -0
- package/util/configure.js +32 -0
- package/util/generate-docs.sh +18 -0
- package/util/get-env.js +6 -0
- package/util/test-compile.js +11 -0
- package/util/test-producer-delivery.js +100 -0
|
@@ -0,0 +1,1445 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* librdkafka - The Apache Kafka C/C++ library
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2026, Confluent Inc.
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer.
|
|
12
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
* and/or other materials provided with the distribution.
|
|
15
|
+
*
|
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
19
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
20
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
21
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
22
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
23
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
24
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
25
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
26
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
#include "rdkafka_int.h"
|
|
29
|
+
#include "rdkafka_metadata.h"
|
|
30
|
+
#include "rdkafka_share_acknowledgement.h"
|
|
31
|
+
|
|
32
|
+
rd_kafka_share_ack_batch_entry_t *
|
|
33
|
+
rd_kafka_share_ack_batch_entry_new(int64_t start_offset,
|
|
34
|
+
int64_t end_offset,
|
|
35
|
+
int32_t types_cnt,
|
|
36
|
+
int16_t delivery_count) {
|
|
37
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
38
|
+
|
|
39
|
+
entry = rd_calloc(1, sizeof(*entry));
|
|
40
|
+
entry->start_offset = start_offset;
|
|
41
|
+
entry->end_offset = end_offset;
|
|
42
|
+
entry->size = end_offset - start_offset + 1;
|
|
43
|
+
entry->types_cnt = types_cnt;
|
|
44
|
+
entry->delivery_count = delivery_count;
|
|
45
|
+
entry->types =
|
|
46
|
+
rd_calloc((size_t)types_cnt,
|
|
47
|
+
sizeof(rd_kafka_share_internal_acknowledgement_type));
|
|
48
|
+
return entry;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
void rd_kafka_share_ack_batch_entry_destroy(
|
|
52
|
+
rd_kafka_share_ack_batch_entry_t *entry) {
|
|
53
|
+
if (!entry)
|
|
54
|
+
return;
|
|
55
|
+
rd_free(entry->types);
|
|
56
|
+
rd_free(entry);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void rd_kafka_share_ack_batch_entry_destroy_free(void *ptr) {
|
|
60
|
+
rd_kafka_share_ack_batch_entry_destroy(
|
|
61
|
+
(rd_kafka_share_ack_batch_entry_t *)ptr);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
rd_bool_t
|
|
65
|
+
rd_kafka_share_acknowledgement_mode_is_implicit(rd_kafka_share_t *rkshare) {
|
|
66
|
+
return rkshare->rkshare_rk->rk_conf.share.share_acknowledgement_mode &&
|
|
67
|
+
!strcmp(rkshare->rkshare_rk->rk_conf.share
|
|
68
|
+
.share_acknowledgement_mode,
|
|
69
|
+
"implicit");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
rd_bool_t
|
|
73
|
+
rd_kafka_share_acknowledgement_mode_is_explicit(rd_kafka_share_t *rkshare) {
|
|
74
|
+
return rkshare->rkshare_rk->rk_conf.share.share_acknowledgement_mode &&
|
|
75
|
+
!strcmp(rkshare->rkshare_rk->rk_conf.share
|
|
76
|
+
.share_acknowledgement_mode,
|
|
77
|
+
"explicit");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
void rd_kafka_share_acknowledge_all_if_implicit(rd_kafka_share_t *rkshare) {
|
|
81
|
+
if (rd_kafka_share_acknowledgement_mode_is_implicit(rkshare))
|
|
82
|
+
rd_kafka_share_ack_all(rkshare);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
rd_kafka_error_t *
|
|
86
|
+
rd_kafka_share_ensure_all_acknowledged_if_explicit(rd_kafka_share_t *rkshare) {
|
|
87
|
+
if (rd_kafka_share_acknowledgement_mode_is_explicit(rkshare) &&
|
|
88
|
+
rkshare->rkshare_unacked_cnt > 0)
|
|
89
|
+
return rd_kafka_error_new(
|
|
90
|
+
RD_KAFKA_RESP_ERR__STATE,
|
|
91
|
+
"%" PRId64
|
|
92
|
+
" records from previous poll have not "
|
|
93
|
+
"been acknowledged",
|
|
94
|
+
rkshare->rkshare_unacked_cnt);
|
|
95
|
+
return NULL;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
rd_kafka_share_ack_batch_entry_t *rd_kafka_share_ack_batch_entry_copy(
|
|
99
|
+
const rd_kafka_share_ack_batch_entry_t *src) {
|
|
100
|
+
rd_kafka_share_ack_batch_entry_t *dst;
|
|
101
|
+
|
|
102
|
+
dst = rd_kafka_share_ack_batch_entry_new(
|
|
103
|
+
src->start_offset, src->end_offset, src->types_cnt,
|
|
104
|
+
src->delivery_count);
|
|
105
|
+
memcpy(dst->types, src->types,
|
|
106
|
+
(size_t)src->types_cnt *
|
|
107
|
+
sizeof(rd_kafka_share_internal_acknowledgement_type));
|
|
108
|
+
return dst;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static void *rd_kafka_share_ack_batch_entry_copy_void(const void *elem,
|
|
112
|
+
void *opaque) {
|
|
113
|
+
return rd_kafka_share_ack_batch_entry_copy(
|
|
114
|
+
(const rd_kafka_share_ack_batch_entry_t *)elem);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
rd_kafka_share_ack_batches_t *rd_kafka_share_ack_batches_new_empty(void) {
|
|
118
|
+
return rd_kafka_share_ack_batches_new(NULL, 0, 0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
rd_kafka_share_ack_batches_t *
|
|
122
|
+
rd_kafka_share_ack_batches_new(rd_kafka_topic_partition_t *rktpar,
|
|
123
|
+
int32_t response_leader_id,
|
|
124
|
+
int64_t response_acquired_offsets_count) {
|
|
125
|
+
rd_kafka_share_ack_batches_t *batches;
|
|
126
|
+
|
|
127
|
+
batches = rd_calloc(1, sizeof(*batches));
|
|
128
|
+
batches->rktpar = rktpar;
|
|
129
|
+
batches->response_leader_id = response_leader_id;
|
|
130
|
+
batches->response_acquired_offsets_count =
|
|
131
|
+
response_acquired_offsets_count;
|
|
132
|
+
rd_list_init(&batches->entries, 0,
|
|
133
|
+
rd_kafka_share_ack_batch_entry_destroy_free);
|
|
134
|
+
return batches;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void rd_kafka_share_ack_batches_destroy(rd_kafka_share_ack_batches_t *batches) {
|
|
138
|
+
rd_list_destroy(&batches->entries);
|
|
139
|
+
if (batches->rktpar)
|
|
140
|
+
rd_kafka_topic_partition_destroy(batches->rktpar);
|
|
141
|
+
rd_free(batches);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
void rd_kafka_share_ack_batches_destroy_free(void *ptr) {
|
|
145
|
+
rd_kafka_share_ack_batches_destroy((rd_kafka_share_ack_batches_t *)ptr);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
rd_kafka_share_ack_batches_t *
|
|
149
|
+
rd_kafka_share_ack_batches_copy(const rd_kafka_share_ack_batches_t *src) {
|
|
150
|
+
rd_kafka_share_ack_batches_t *dst;
|
|
151
|
+
|
|
152
|
+
dst = rd_kafka_share_ack_batches_new(
|
|
153
|
+
src->rktpar ? rd_kafka_topic_partition_copy(src->rktpar) : NULL,
|
|
154
|
+
src->response_leader_id, src->response_acquired_offsets_count);
|
|
155
|
+
|
|
156
|
+
/* Deep copy all entries and preserve flags (e.g., RD_LIST_F_SORTED) */
|
|
157
|
+
rd_list_copy_to(&dst->entries, &src->entries,
|
|
158
|
+
rd_kafka_share_ack_batch_entry_copy_void, NULL);
|
|
159
|
+
dst->entries.rl_flags = src->entries.rl_flags;
|
|
160
|
+
return dst;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void *rd_kafka_share_ack_batches_copy_void(const void *elem, void *opaque) {
|
|
164
|
+
return rd_kafka_share_ack_batches_copy(
|
|
165
|
+
(const rd_kafka_share_ack_batches_t *)elem);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @brief Transfer inflight acks from response RKO into rkshare's inflight map.
|
|
170
|
+
*
|
|
171
|
+
* Takes each batch from the response's inflight_acks list and stores it in
|
|
172
|
+
* the map (key = topic-partition). Ownership is transferred; the response
|
|
173
|
+
* RKO must not free these when destroyed.
|
|
174
|
+
* In the future, the map will be cleared per partition after acks are sent.
|
|
175
|
+
*
|
|
176
|
+
* @param rkshare Share consumer handle
|
|
177
|
+
* @param response_rko The share fetch response RKO containing inflight_acks
|
|
178
|
+
*/
|
|
179
|
+
void rd_kafka_share_build_inflight_acks_map(rd_kafka_share_t *rkshare,
|
|
180
|
+
rd_kafka_op_t *response_rko) {
|
|
181
|
+
rd_list_t *list =
|
|
182
|
+
response_rko->rko_u.share_fetch_response.inflight_acks;
|
|
183
|
+
|
|
184
|
+
while (rd_list_cnt(list) > 0) {
|
|
185
|
+
rd_kafka_share_ack_batches_t *batches = rd_list_pop(list);
|
|
186
|
+
rd_kafka_topic_partition_t *key;
|
|
187
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
188
|
+
int i, k;
|
|
189
|
+
|
|
190
|
+
rd_dassert(batches->rktpar != NULL);
|
|
191
|
+
|
|
192
|
+
key = rd_kafka_topic_partition_new_with_id_and_name(
|
|
193
|
+
rd_kafka_topic_partition_get_topic_id(batches->rktpar),
|
|
194
|
+
batches->rktpar->topic, batches->rktpar->partition);
|
|
195
|
+
|
|
196
|
+
/* Each topic-partition is always a new entry (no overwrites).
|
|
197
|
+
*/
|
|
198
|
+
RD_MAP_SET(&rkshare->rkshare_inflight_acks, key, batches);
|
|
199
|
+
|
|
200
|
+
/* Count ACQUIRED types for unacked tracking */
|
|
201
|
+
RD_LIST_FOREACH(entry, &batches->entries, i) {
|
|
202
|
+
for (k = 0; k < entry->types_cnt; k++) {
|
|
203
|
+
if (entry->types[k] ==
|
|
204
|
+
RD_KAFKA_SHARE_INTERNAL_ACK_ACQUIRED)
|
|
205
|
+
rkshare->rkshare_unacked_cnt++;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @brief Create a new collated batch entry with a single acknowledgement type.
|
|
213
|
+
*
|
|
214
|
+
* Creates an entry where size=1 and types[0] holds the single ack type
|
|
215
|
+
* for the entire offset range [start_offset, end_offset].
|
|
216
|
+
*
|
|
217
|
+
* @param start_offset First offset in the range
|
|
218
|
+
* @param end_offset Last offset in the range (inclusive)
|
|
219
|
+
* @param type The acknowledgement type for the entire range
|
|
220
|
+
*
|
|
221
|
+
* @returns Newly allocated collated entry (caller must free)
|
|
222
|
+
*/
|
|
223
|
+
static rd_kafka_share_ack_batch_entry_t *
|
|
224
|
+
rd_kafka_share_ack_batch_entry_collated_new(
|
|
225
|
+
int64_t start_offset,
|
|
226
|
+
int64_t end_offset,
|
|
227
|
+
rd_kafka_share_internal_acknowledgement_type type,
|
|
228
|
+
int16_t delivery_count) {
|
|
229
|
+
rd_kafka_share_ack_batch_entry_t *entry =
|
|
230
|
+
rd_kafka_share_ack_batch_entry_new(start_offset, end_offset, 1,
|
|
231
|
+
delivery_count);
|
|
232
|
+
entry->types[0] = type;
|
|
233
|
+
return entry;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @brief Implicit acknowledgement: convert all ACQUIRED types to ACCEPT.
|
|
238
|
+
*
|
|
239
|
+
* In implicit ack mode, all records delivered to the application are
|
|
240
|
+
* automatically acknowledged as ACCEPT on the next poll(). This function
|
|
241
|
+
* walks through all entries in the inflight map and changes ACQUIRED
|
|
242
|
+
* types to ACCEPT so that rd_kafka_share_build_ack_details() will
|
|
243
|
+
* extract them for sending to the broker.
|
|
244
|
+
*
|
|
245
|
+
* @param rkshare Share consumer handle
|
|
246
|
+
*/
|
|
247
|
+
void rd_kafka_share_ack_all(rd_kafka_share_t *rkshare) {
|
|
248
|
+
const rd_kafka_topic_partition_t *tp_key;
|
|
249
|
+
rd_kafka_share_ack_batches_t *inflight_batches;
|
|
250
|
+
|
|
251
|
+
RD_MAP_FOREACH(tp_key, inflight_batches,
|
|
252
|
+
&rkshare->rkshare_inflight_acks) {
|
|
253
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
254
|
+
int i;
|
|
255
|
+
rd_kafka_dbg(rkshare->rkshare_rk, CGRP, "SHAREACK",
|
|
256
|
+
"Implicit ack: converting ACQUIRED to ACCEPT "
|
|
257
|
+
"for %s [%" PRId32 "]",
|
|
258
|
+
tp_key->topic, tp_key->partition);
|
|
259
|
+
RD_LIST_FOREACH(entry, &inflight_batches->entries, i) {
|
|
260
|
+
int k;
|
|
261
|
+
for (k = 0; k < entry->types_cnt; k++) {
|
|
262
|
+
if (entry->types[k] ==
|
|
263
|
+
RD_KAFKA_SHARE_INTERNAL_ACK_ACQUIRED)
|
|
264
|
+
entry->types[k] =
|
|
265
|
+
RD_KAFKA_SHARE_INTERNAL_ACK_ACCEPT;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @brief Free an ack details batch, its entries, and its owned rktpar.
|
|
273
|
+
*
|
|
274
|
+
* Used as rd_list_t free callback for ack_details output lists where
|
|
275
|
+
* each batch owns a copy of its rktpar.
|
|
276
|
+
*/
|
|
277
|
+
static void rd_kafka_share_ack_details_batch_destroy(void *ptr) {
|
|
278
|
+
rd_kafka_share_ack_batches_t *batch = ptr;
|
|
279
|
+
rd_kafka_share_ack_batches_destroy(batch);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @brief Find an existing ack batch for the same topic-partition in a list.
|
|
284
|
+
*
|
|
285
|
+
* @param ack_list List of rd_kafka_share_ack_batches_t*
|
|
286
|
+
* @param rktpar Topic-partition to match (by topic id and partition)
|
|
287
|
+
*
|
|
288
|
+
* @returns Matching batch, or NULL if not found.
|
|
289
|
+
* @locality main thread
|
|
290
|
+
*/
|
|
291
|
+
rd_kafka_share_ack_batches_t *
|
|
292
|
+
rd_kafka_share_find_ack_batch(rd_list_t *ack_list,
|
|
293
|
+
const rd_kafka_topic_partition_t *rktpar) {
|
|
294
|
+
rd_kafka_share_ack_batches_t *existing;
|
|
295
|
+
int i;
|
|
296
|
+
|
|
297
|
+
RD_LIST_FOREACH(existing, ack_list, i) {
|
|
298
|
+
if (rd_kafka_topic_partition_by_id_cmp(existing->rktpar,
|
|
299
|
+
rktpar) == 0)
|
|
300
|
+
return existing;
|
|
301
|
+
}
|
|
302
|
+
return NULL;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @brief Find an existing ack batch by topic id and partition.
|
|
307
|
+
*
|
|
308
|
+
* Same as rd_kafka_share_find_ack_batch but takes topic_id and
|
|
309
|
+
* partition directly to avoid allocating a temporary
|
|
310
|
+
* rd_kafka_topic_partition_t for the lookup.
|
|
311
|
+
*
|
|
312
|
+
* TODO KIP-932: Merge this with rd_kafka_share_find_ack_batch and use
|
|
313
|
+
* rd_list_find with binary search once ack_list is kept sorted.
|
|
314
|
+
*
|
|
315
|
+
* @param ack_list List of rd_kafka_share_ack_batches_t*.
|
|
316
|
+
* @param topic_id Topic UUID to match.
|
|
317
|
+
* @param partition Partition id to match.
|
|
318
|
+
*
|
|
319
|
+
* @returns Matching batch, or NULL if not found.
|
|
320
|
+
*/
|
|
321
|
+
rd_kafka_share_ack_batches_t *
|
|
322
|
+
rd_kafka_share_find_ack_batch_by_id(rd_list_t *ack_list,
|
|
323
|
+
rd_kafka_Uuid_t topic_id,
|
|
324
|
+
int32_t partition) {
|
|
325
|
+
rd_kafka_share_ack_batches_t *existing;
|
|
326
|
+
int i;
|
|
327
|
+
|
|
328
|
+
RD_LIST_FOREACH(existing, ack_list, i) {
|
|
329
|
+
if (existing->rktpar->partition == partition &&
|
|
330
|
+
!rd_kafka_Uuid_cmp(
|
|
331
|
+
rd_kafka_topic_partition_get_topic_id(existing->rktpar),
|
|
332
|
+
topic_id))
|
|
333
|
+
return existing;
|
|
334
|
+
}
|
|
335
|
+
return NULL;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* @brief Reply to a SHARE_FETCH op with an error, propagating the
|
|
340
|
+
* error to each batch in ack_details.
|
|
341
|
+
*
|
|
342
|
+
* On top-level error (err != 0):
|
|
343
|
+
* - If err is BAD_MSG / __UNDERFLOW (wire-level parse failure):
|
|
344
|
+
* override every batch with INVALID_RECORD_STATE so the consumer
|
|
345
|
+
* treats these as "outcome unknown" and re-acquires; any
|
|
346
|
+
* per-partition err the parser may have written before failing
|
|
347
|
+
* could be a misaligned read and is no longer trustworthy.
|
|
348
|
+
* - Otherwise: propagate err to each batch still at _IN_PROGRESS,
|
|
349
|
+
* preserving any deliberately pre-set err and any per-partition
|
|
350
|
+
* err already written by the parser.
|
|
351
|
+
*
|
|
352
|
+
* On success (err == 0), the per-partition errors have already been
|
|
353
|
+
* set by the response parser and we leave ack_details untouched.
|
|
354
|
+
*/
|
|
355
|
+
void rd_kafka_share_fetch_op_reply_and_update_ack_details_with_err(
|
|
356
|
+
rd_kafka_op_t *rko,
|
|
357
|
+
rd_kafka_resp_err_t err) {
|
|
358
|
+
if (err && rko->rko_u.share_fetch.ack_details) {
|
|
359
|
+
rd_kafka_share_ack_batches_t *batch;
|
|
360
|
+
int i;
|
|
361
|
+
|
|
362
|
+
if (likely(err != RD_KAFKA_RESP_ERR__BAD_MSG &&
|
|
363
|
+
err != RD_KAFKA_RESP_ERR__UNDERFLOW)) {
|
|
364
|
+
|
|
365
|
+
/* Propagate top-level err to each batch in
|
|
366
|
+
* ack_details, but only override the _IN_PROGRESS
|
|
367
|
+
* sentinel. This preserves:
|
|
368
|
+
* - Deliberately pre-set err (e.g.
|
|
369
|
+
* INVALID_SHARE_SESSION_EPOCH from the
|
|
370
|
+
* epoch-0 strip path).
|
|
371
|
+
* - Per-partition err already written by the
|
|
372
|
+
* parser. */
|
|
373
|
+
RD_LIST_FOREACH(batch,
|
|
374
|
+
rko->rko_u.share_fetch.ack_details, i) {
|
|
375
|
+
if (batch->rktpar->err ==
|
|
376
|
+
RD_KAFKA_RESP_ERR__IN_PROGRESS)
|
|
377
|
+
batch->rktpar->err = err;
|
|
378
|
+
}
|
|
379
|
+
} else {
|
|
380
|
+
/* Wire-level parse failure: response framing is
|
|
381
|
+
* untrusted, so any per-partition err the parser
|
|
382
|
+
* may have written before failing could be a
|
|
383
|
+
* misaligned read. */
|
|
384
|
+
RD_LIST_FOREACH(batch,
|
|
385
|
+
rko->rko_u.share_fetch.ack_details, i) {
|
|
386
|
+
batch->rktpar->err = err;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
rd_kafka_op_reply(rko, err);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* @brief Whether the leader cached for the partition has diverged
|
|
395
|
+
* from the leader at which \p batch's records were acquired.
|
|
396
|
+
*/
|
|
397
|
+
static rd_bool_t
|
|
398
|
+
rd_kafka_share_ack_batch_leader_stale(rd_kafka_share_ack_batches_t *batch,
|
|
399
|
+
int32_t current_leader_id) {
|
|
400
|
+
return current_leader_id != batch->response_leader_id;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* @brief Resolve the leader broker for an ack batch, or fail the
|
|
405
|
+
* batch locally with the appropriate error code.
|
|
406
|
+
*
|
|
407
|
+
* Snapshots (rktp_leader, rktp_leader_id) under rktp_lock to
|
|
408
|
+
* avoid racing with concurrent leader-state clearing on the
|
|
409
|
+
* broker thread. On success, returns a kept broker handle;
|
|
410
|
+
* the caller MUST rd_kafka_broker_destroy() it after use.
|
|
411
|
+
* On failure returns NULL with \p *errp set.
|
|
412
|
+
*
|
|
413
|
+
* @locality main thread
|
|
414
|
+
*/
|
|
415
|
+
static rd_kafka_broker_t *rd_kafka_share_ack_batch_resolve_leader_or_fail_acks(
|
|
416
|
+
rd_kafka_t *rk,
|
|
417
|
+
rd_kafka_share_ack_batches_t *batch,
|
|
418
|
+
rd_kafka_resp_err_t *errp) {
|
|
419
|
+
rd_kafka_toppar_t *rktp;
|
|
420
|
+
rd_kafka_broker_t *leader_rkb;
|
|
421
|
+
int32_t leader_id;
|
|
422
|
+
|
|
423
|
+
rktp = rd_kafka_topic_partition_toppar(rk, batch->rktpar);
|
|
424
|
+
|
|
425
|
+
/* Defensive: in production the rktp is always attached to the
|
|
426
|
+
* batch by the ShareFetch reply parser via toppar_keep, so
|
|
427
|
+
* this branch should never fire. Trigger a cluster-wide
|
|
428
|
+
* metadata refresh to recover if it ever does. */
|
|
429
|
+
if (unlikely(!rktp)) {
|
|
430
|
+
rd_kafka_dbg(rk, CGRP, "SHARE",
|
|
431
|
+
"Ack batch for partition %" PRId32
|
|
432
|
+
" dropped: toppar not found "
|
|
433
|
+
"(should be unreachable)",
|
|
434
|
+
batch->rktpar->partition);
|
|
435
|
+
rd_kafka_metadata_refresh_known_topics(
|
|
436
|
+
rk, NULL, rd_false /*don't force*/,
|
|
437
|
+
"shareack toppar not found");
|
|
438
|
+
*errp = RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART;
|
|
439
|
+
return NULL;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* Snapshot (rktp_leader, rktp_leader_id) under rktp_lock to
|
|
443
|
+
* avoid racing with concurrent leader-state clearing on the
|
|
444
|
+
* broker thread. */
|
|
445
|
+
rd_kafka_toppar_lock(rktp);
|
|
446
|
+
leader_rkb = rktp->rktp_leader;
|
|
447
|
+
leader_id = rktp->rktp_leader_id;
|
|
448
|
+
if (leader_rkb)
|
|
449
|
+
rd_kafka_broker_keep(leader_rkb);
|
|
450
|
+
rd_kafka_toppar_unlock(rktp);
|
|
451
|
+
|
|
452
|
+
/* Cached leader differs from the leader at which records
|
|
453
|
+
* were acquired. The session for these records lives on the
|
|
454
|
+
* original broker which no longer leads this partition. No
|
|
455
|
+
* metadata refresh - the cached current leader is already
|
|
456
|
+
* the new one (that's how this check fired). */
|
|
457
|
+
if (unlikely(rd_kafka_share_ack_batch_leader_stale(batch, leader_id))) {
|
|
458
|
+
rd_kafka_dbg(rk, CGRP, "SHARE",
|
|
459
|
+
"Ack batch for %s [%" PRId32
|
|
460
|
+
"] dropped locally: leader changed "
|
|
461
|
+
"since records were acquired "
|
|
462
|
+
"(was %" PRId32 ", now %" PRId32 ")",
|
|
463
|
+
batch->rktpar->topic, batch->rktpar->partition,
|
|
464
|
+
batch->response_leader_id, leader_id);
|
|
465
|
+
if (leader_rkb)
|
|
466
|
+
rd_kafka_broker_destroy(leader_rkb);
|
|
467
|
+
*errp = RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER;
|
|
468
|
+
return NULL;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Defensive: no cached leader. Unreachable in practice
|
|
472
|
+
* because leader-stale fires first when the cached leader id
|
|
473
|
+
* is -1, but kept to make the intent explicit and survive
|
|
474
|
+
* future invariant changes. Trigger a metadata refresh and
|
|
475
|
+
* surface NOT_LEADER_OR_FOLLOWER. */
|
|
476
|
+
if (unlikely(!leader_rkb)) {
|
|
477
|
+
rd_kafka_dbg(rk, CGRP, "SHARE",
|
|
478
|
+
"Ack batch for %s [%" PRId32
|
|
479
|
+
"] dropped: no cached leader, "
|
|
480
|
+
"triggering metadata refresh",
|
|
481
|
+
batch->rktpar->topic, batch->rktpar->partition);
|
|
482
|
+
rd_kafka_toppar_leader_unavailable(
|
|
483
|
+
rktp, "shareack", RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER);
|
|
484
|
+
*errp = RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER;
|
|
485
|
+
return NULL;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/* Cached leader broker is being decommissioned or the
|
|
489
|
+
* instance is terminating. Surface NOT_LEADER_OR_FOLLOWER and
|
|
490
|
+
* trigger a metadata refresh so the next request finds the
|
|
491
|
+
* new leader. */
|
|
492
|
+
if (unlikely(rd_kafka_broker_or_instance_terminating(leader_rkb))) {
|
|
493
|
+
rd_kafka_dbg(
|
|
494
|
+
rk, CGRP, "SHARE",
|
|
495
|
+
"Ack batch for %s [%" PRId32 "] dropped: broker %" PRId32
|
|
496
|
+
" is terminating, "
|
|
497
|
+
"triggering metadata refresh",
|
|
498
|
+
batch->rktpar->topic, batch->rktpar->partition, leader_id);
|
|
499
|
+
rd_kafka_toppar_leader_unavailable(
|
|
500
|
+
rktp, "shareack", RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER);
|
|
501
|
+
rd_kafka_broker_destroy(leader_rkb);
|
|
502
|
+
*errp = RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER;
|
|
503
|
+
return NULL;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
*errp = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
507
|
+
return leader_rkb;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* @brief Segregate sync ack batches by partition leader into
|
|
513
|
+
* each broker's pending_commit_sync list.
|
|
514
|
+
*
|
|
515
|
+
* Phase 1 of sync dispatch: puts ALL acks into rkb_pending_commit_sync
|
|
516
|
+
* regardless of whether the broker is free or busy. Updates the
|
|
517
|
+
* commit_sync results for partitions with no available leader.
|
|
518
|
+
*
|
|
519
|
+
* @param rk Client instance.
|
|
520
|
+
* @param rkcg Consumer group handle.
|
|
521
|
+
* @param ack_batches List of ack batches from the SYNC_FANOUT op.
|
|
522
|
+
* Elements are moved to broker lists; container destroyed.
|
|
523
|
+
* @param abs_timeout Absolute timeout for the commit_sync request.
|
|
524
|
+
*
|
|
525
|
+
* @locality main thread
|
|
526
|
+
*/
|
|
527
|
+
void rd_kafka_share_segregate_sync_acks_by_leader(rd_kafka_t *rk,
|
|
528
|
+
rd_kafka_cgrp_t *rkcg,
|
|
529
|
+
rd_list_t *ack_batches,
|
|
530
|
+
rd_ts_t abs_timeout) {
|
|
531
|
+
rd_kafka_share_ack_batches_t *batch;
|
|
532
|
+
int batch_cnt = rd_list_cnt(ack_batches);
|
|
533
|
+
|
|
534
|
+
while ((batch = rd_list_pop(ack_batches))) {
|
|
535
|
+
rd_kafka_broker_t *leader_rkb;
|
|
536
|
+
rd_kafka_share_ack_batches_t *existing;
|
|
537
|
+
rd_kafka_topic_partition_t *result_rktpar;
|
|
538
|
+
rd_kafka_resp_err_t fail_err;
|
|
539
|
+
|
|
540
|
+
leader_rkb =
|
|
541
|
+
rd_kafka_share_ack_batch_resolve_leader_or_fail_acks(
|
|
542
|
+
rk, batch, &fail_err);
|
|
543
|
+
if (!leader_rkb) {
|
|
544
|
+
result_rktpar = rd_kafka_topic_partition_list_find(
|
|
545
|
+
rkcg->rkcg_commit_sync_request.results,
|
|
546
|
+
batch->rktpar->topic, batch->rktpar->partition);
|
|
547
|
+
if (result_rktpar)
|
|
548
|
+
result_rktpar->err = fail_err;
|
|
549
|
+
else
|
|
550
|
+
rd_kafka_dbg(rk, CGRP, "SHARE",
|
|
551
|
+
"Sync ack batch for %s [%" PRId32
|
|
552
|
+
"]: partition not found in "
|
|
553
|
+
"commit_sync results",
|
|
554
|
+
batch->rktpar->topic,
|
|
555
|
+
batch->rktpar->partition);
|
|
556
|
+
|
|
557
|
+
rd_kafka_share_enqueue_ack_commit_cb_op(rk, batch,
|
|
558
|
+
fail_err);
|
|
559
|
+
rd_kafka_share_ack_batches_destroy(batch);
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* Put all acks into pending_commit_sync */
|
|
564
|
+
if (!leader_rkb->rkb_pending_commit_sync.sync_ack_details)
|
|
565
|
+
leader_rkb->rkb_pending_commit_sync.sync_ack_details =
|
|
566
|
+
rd_list_new(
|
|
567
|
+
batch_cnt,
|
|
568
|
+
rd_kafka_share_ack_batches_destroy_free);
|
|
569
|
+
|
|
570
|
+
existing = rd_kafka_share_find_ack_batch(
|
|
571
|
+
leader_rkb->rkb_pending_commit_sync.sync_ack_details,
|
|
572
|
+
batch->rktpar);
|
|
573
|
+
if (existing) {
|
|
574
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
575
|
+
int j;
|
|
576
|
+
RD_LIST_FOREACH(entry, &batch->entries, j) {
|
|
577
|
+
rd_list_add(
|
|
578
|
+
&existing->entries,
|
|
579
|
+
rd_kafka_share_ack_batch_entry_copy(entry));
|
|
580
|
+
}
|
|
581
|
+
rd_list_sort(&existing->entries,
|
|
582
|
+
rd_kafka_share_ack_entries_sort_cmp_ptr);
|
|
583
|
+
rd_kafka_share_ack_batches_destroy(batch);
|
|
584
|
+
} else {
|
|
585
|
+
rd_list_add(leader_rkb->rkb_pending_commit_sync
|
|
586
|
+
.sync_ack_details,
|
|
587
|
+
batch);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
leader_rkb->rkb_pending_commit_sync.abs_timeout = abs_timeout;
|
|
591
|
+
leader_rkb->rkb_pending_commit_sync.commit_sync_request_id =
|
|
592
|
+
rkcg->rkcg_commit_sync_request.id;
|
|
593
|
+
|
|
594
|
+
rd_kafka_broker_destroy(leader_rkb);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
rd_list_destroy(ack_batches);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* @brief Segregate ack batches from a FANOUT op by partition leader.
|
|
603
|
+
*
|
|
604
|
+
* For each ack batch, looks up the current leader broker via the
|
|
605
|
+
* toppar reference in batch->rktpar, and merges the batch into that
|
|
606
|
+
* broker's rkb_share_async_ack_details list. If the broker already
|
|
607
|
+
* has cached acks for the same topic-partition, the entries are
|
|
608
|
+
* appended to the existing batch.
|
|
609
|
+
*
|
|
610
|
+
* @param rk Client instance
|
|
611
|
+
* @param ack_batches List of rd_kafka_share_ack_batches_t* from FANOUT op.
|
|
612
|
+
* Elements whose leader is found are moved to broker
|
|
613
|
+
* ack_details; remaining elements are not freed.
|
|
614
|
+
*
|
|
615
|
+
* @locality main thread
|
|
616
|
+
*/
|
|
617
|
+
void rd_kafka_share_segregate_acks_by_leader(rd_kafka_t *rk,
|
|
618
|
+
rd_list_t *ack_batches) {
|
|
619
|
+
rd_kafka_share_ack_batches_t *batch;
|
|
620
|
+
int batch_cnt = rd_list_cnt(ack_batches);
|
|
621
|
+
|
|
622
|
+
while ((batch = rd_list_pop(ack_batches))) {
|
|
623
|
+
rd_kafka_broker_t *leader_rkb;
|
|
624
|
+
rd_kafka_share_ack_batches_t *existing;
|
|
625
|
+
rd_kafka_resp_err_t fail_err;
|
|
626
|
+
|
|
627
|
+
leader_rkb =
|
|
628
|
+
rd_kafka_share_ack_batch_resolve_leader_or_fail_acks(
|
|
629
|
+
rk, batch, &fail_err);
|
|
630
|
+
if (!leader_rkb) {
|
|
631
|
+
rd_kafka_share_enqueue_ack_commit_cb_op(rk, batch,
|
|
632
|
+
fail_err);
|
|
633
|
+
rd_kafka_share_ack_batches_destroy(batch);
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/* Allocate list on first use with incoming batch count
|
|
638
|
+
* as initial capacity hint */
|
|
639
|
+
if (!leader_rkb->rkb_share_async_ack_details)
|
|
640
|
+
leader_rkb->rkb_share_async_ack_details = rd_list_new(
|
|
641
|
+
batch_cnt, rd_kafka_share_ack_batches_destroy_free);
|
|
642
|
+
|
|
643
|
+
/* Check if there's already a batch for this topic-partition.
|
|
644
|
+
* If so, merge entries; otherwise add as new. */
|
|
645
|
+
existing = rd_kafka_share_find_ack_batch(
|
|
646
|
+
leader_rkb->rkb_share_async_ack_details, batch->rktpar);
|
|
647
|
+
|
|
648
|
+
if (existing) {
|
|
649
|
+
/* Merge: deep-copy entries from new batch into
|
|
650
|
+
* existing, preserving order. The source batch
|
|
651
|
+
* is then fully destroyed (freeing its entries). */
|
|
652
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
653
|
+
int j;
|
|
654
|
+
RD_LIST_FOREACH(entry, &batch->entries, j) {
|
|
655
|
+
rd_list_add(
|
|
656
|
+
&existing->entries,
|
|
657
|
+
rd_kafka_share_ack_batch_entry_copy(entry));
|
|
658
|
+
}
|
|
659
|
+
rd_kafka_share_ack_batches_destroy(batch);
|
|
660
|
+
} else {
|
|
661
|
+
rd_list_add(leader_rkb->rkb_share_async_ack_details,
|
|
662
|
+
batch);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
rd_kafka_broker_destroy(leader_rkb);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* @brief Extract acknowledged (non-ACQUIRED) records from inflight map.
|
|
671
|
+
*
|
|
672
|
+
* Iterates through the inflight acknowledgement map and separates each
|
|
673
|
+
* entry's per-offset types into:
|
|
674
|
+
* - Non-ACQUIRED offsets: collated into ack_details for sending to broker
|
|
675
|
+
* (consecutive same-type offsets merged into single entry with 1 type)
|
|
676
|
+
* - ACQUIRED offsets: kept in the map as new entries (per-offset types)
|
|
677
|
+
*
|
|
678
|
+
* Map entries with no remaining ACQUIRED offsets are removed.
|
|
679
|
+
* If the map becomes empty after processing, it is cleared.
|
|
680
|
+
*
|
|
681
|
+
* @param rkshare Share consumer handle
|
|
682
|
+
* @returns Allocated list of rd_kafka_share_ack_batches_t*, or NULL if
|
|
683
|
+
* there are no ack details to send. Caller must destroy.
|
|
684
|
+
* TODO KIP-932: Change name.
|
|
685
|
+
*/
|
|
686
|
+
rd_list_t *rd_kafka_share_build_ack_details(rd_kafka_share_t *rkshare) {
|
|
687
|
+
const rd_kafka_topic_partition_t *tp_key;
|
|
688
|
+
rd_kafka_share_ack_batches_t *inflight_batches;
|
|
689
|
+
rd_list_t keys_to_delete;
|
|
690
|
+
rd_list_t *ack_details = NULL;
|
|
691
|
+
int i;
|
|
692
|
+
rd_kafka_topic_partition_t *del_key;
|
|
693
|
+
|
|
694
|
+
rd_list_init(&keys_to_delete, 0, NULL);
|
|
695
|
+
|
|
696
|
+
rkshare->rkshare_unacked_cnt = 0;
|
|
697
|
+
|
|
698
|
+
RD_MAP_FOREACH(tp_key, inflight_batches,
|
|
699
|
+
&rkshare->rkshare_inflight_acks) {
|
|
700
|
+
rd_kafka_share_ack_batches_t *ack_batch = NULL;
|
|
701
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
702
|
+
rd_list_t new_entries;
|
|
703
|
+
int ei;
|
|
704
|
+
|
|
705
|
+
rd_kafka_dbg(rkshare->rkshare_rk, CGRP, "SHAREACK",
|
|
706
|
+
"Building ack details for %s [%" PRId32 "]",
|
|
707
|
+
tp_key->topic, tp_key->partition);
|
|
708
|
+
|
|
709
|
+
rd_list_init(&new_entries, 0,
|
|
710
|
+
rd_kafka_share_ack_batch_entry_destroy_free);
|
|
711
|
+
|
|
712
|
+
RD_LIST_FOREACH(entry, &inflight_batches->entries, ei) {
|
|
713
|
+
int64_t j = 0;
|
|
714
|
+
|
|
715
|
+
while (j < entry->types_cnt) {
|
|
716
|
+
rd_kafka_share_internal_acknowledgement_type
|
|
717
|
+
run_type = entry->types[j];
|
|
718
|
+
int64_t run_start = entry->start_offset + j;
|
|
719
|
+
int64_t k = j + 1;
|
|
720
|
+
|
|
721
|
+
/* Find end of consecutive same-type run */
|
|
722
|
+
while (k < entry->types_cnt &&
|
|
723
|
+
entry->types[k] == run_type)
|
|
724
|
+
k++;
|
|
725
|
+
|
|
726
|
+
int64_t run_end = entry->start_offset + k - 1;
|
|
727
|
+
|
|
728
|
+
if (run_type ==
|
|
729
|
+
RD_KAFKA_SHARE_INTERNAL_ACK_ACQUIRED) {
|
|
730
|
+
/* ACQUIRED: keep in map */
|
|
731
|
+
int32_t cnt = (int32_t)(k - j);
|
|
732
|
+
rd_kafka_share_ack_batch_entry_t
|
|
733
|
+
*new_entry =
|
|
734
|
+
rd_kafka_share_ack_batch_entry_new(
|
|
735
|
+
run_start, run_end, cnt,
|
|
736
|
+
entry->delivery_count);
|
|
737
|
+
int32_t m;
|
|
738
|
+
for (m = 0; m < cnt; m++)
|
|
739
|
+
new_entry->types[m] =
|
|
740
|
+
RD_KAFKA_SHARE_INTERNAL_ACK_ACQUIRED;
|
|
741
|
+
rd_list_add(&new_entries, new_entry);
|
|
742
|
+
rkshare->rkshare_unacked_cnt += cnt;
|
|
743
|
+
} else {
|
|
744
|
+
/* Non-ACQUIRED: add to ack_details
|
|
745
|
+
*/
|
|
746
|
+
if (!ack_batch) {
|
|
747
|
+
ack_batch =
|
|
748
|
+
rd_kafka_share_ack_batches_new(
|
|
749
|
+
rd_kafka_topic_partition_copy(
|
|
750
|
+
inflight_batches
|
|
751
|
+
->rktpar),
|
|
752
|
+
inflight_batches
|
|
753
|
+
->response_leader_id,
|
|
754
|
+
0);
|
|
755
|
+
/* Sentinel: no reply path
|
|
756
|
+
* has touched this batch
|
|
757
|
+
* yet. Distinct from
|
|
758
|
+
* INVALID_RECORD_STATE
|
|
759
|
+
* (set in buf callback)
|
|
760
|
+
* which means "reply
|
|
761
|
+
* received but partition
|
|
762
|
+
* missing from response".
|
|
763
|
+
* Defensive check in main
|
|
764
|
+
* reply handler converts
|
|
765
|
+
* any remaining
|
|
766
|
+
* _IN_PROGRESS to the
|
|
767
|
+
* top-level rko_err so
|
|
768
|
+
* silent-destroy paths
|
|
769
|
+
* (q_enq disabled queue,
|
|
770
|
+
* helper bypassed) don't
|
|
771
|
+
* leak the sentinel to
|
|
772
|
+
* the app. */
|
|
773
|
+
ack_batch->rktpar->err =
|
|
774
|
+
RD_KAFKA_RESP_ERR__IN_PROGRESS;
|
|
775
|
+
}
|
|
776
|
+
rd_kafka_dbg(
|
|
777
|
+
rkshare->rkshare_rk, CGRP,
|
|
778
|
+
"SHAREACK",
|
|
779
|
+
" Adding ack detail for offsets "
|
|
780
|
+
"[%" PRId64 " - %" PRId64
|
|
781
|
+
"] with type %d",
|
|
782
|
+
run_start, run_end, run_type);
|
|
783
|
+
/* Collated: 1 type for entire
|
|
784
|
+
* range */
|
|
785
|
+
rd_list_add(
|
|
786
|
+
&ack_batch->entries,
|
|
787
|
+
rd_kafka_share_ack_batch_entry_collated_new(
|
|
788
|
+
run_start, run_end, run_type,
|
|
789
|
+
entry->delivery_count));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
j = k;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* TODO KIP-932: Check if it can be optimized as these are
|
|
798
|
+
* internal thread operations and they should
|
|
799
|
+
* be as fast as possible as this will be called
|
|
800
|
+
* again and again.
|
|
801
|
+
*/
|
|
802
|
+
if (rd_list_is_sorted(&new_entries,
|
|
803
|
+
rd_kafka_share_ack_entries_sort_cmp_ptr))
|
|
804
|
+
new_entries.rl_flags |= RD_LIST_F_SORTED;
|
|
805
|
+
|
|
806
|
+
/* Replace inflight entries with ACQUIRED-only entries */
|
|
807
|
+
rd_list_destroy(&inflight_batches->entries);
|
|
808
|
+
inflight_batches->entries = new_entries;
|
|
809
|
+
|
|
810
|
+
/* If no ACQUIRED offsets remain, mark for removal */
|
|
811
|
+
if (rd_list_cnt(&inflight_batches->entries) == 0) {
|
|
812
|
+
rd_kafka_topic_partition_t *del_key =
|
|
813
|
+
rd_kafka_topic_partition_new_with_id_and_name(
|
|
814
|
+
rd_kafka_topic_partition_get_topic_id(
|
|
815
|
+
inflight_batches->rktpar),
|
|
816
|
+
inflight_batches->rktpar->topic,
|
|
817
|
+
inflight_batches->rktpar->partition);
|
|
818
|
+
rd_list_add(&keys_to_delete, del_key);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (ack_batch) {
|
|
822
|
+
if (!ack_details)
|
|
823
|
+
ack_details = rd_list_new(
|
|
824
|
+
0,
|
|
825
|
+
rd_kafka_share_ack_details_batch_destroy);
|
|
826
|
+
rd_list_add(ack_details, ack_batch);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/* Remove map entries with no remaining ACQUIRED offsets */
|
|
831
|
+
RD_LIST_FOREACH(del_key, &keys_to_delete, i) {
|
|
832
|
+
RD_MAP_DELETE(&rkshare->rkshare_inflight_acks, del_key);
|
|
833
|
+
rd_kafka_topic_partition_destroy(del_key);
|
|
834
|
+
}
|
|
835
|
+
rd_list_destroy(&keys_to_delete);
|
|
836
|
+
|
|
837
|
+
/* Clear map if empty */
|
|
838
|
+
if (RD_MAP_CNT(&rkshare->rkshare_inflight_acks) == 0)
|
|
839
|
+
RD_MAP_CLEAR(&rkshare->rkshare_inflight_acks);
|
|
840
|
+
|
|
841
|
+
return ack_details;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* @brief Update acknowledgement type for a specific offset within an entry.
|
|
846
|
+
*
|
|
847
|
+
* Handles the transition from ACQUIRED state by decrementing the unacked count.
|
|
848
|
+
*
|
|
849
|
+
* @param rkshare Share consumer handle.
|
|
850
|
+
* @param entry The batch entry containing the offset.
|
|
851
|
+
* @param idx Index within the entry's types array.
|
|
852
|
+
* @param type New acknowledgement type.
|
|
853
|
+
*/
|
|
854
|
+
static void rd_kafka_share_update_acknowledgement_type(
|
|
855
|
+
rd_kafka_share_t *rkshare,
|
|
856
|
+
rd_kafka_share_ack_batch_entry_t *entry,
|
|
857
|
+
int64_t idx,
|
|
858
|
+
rd_kafka_share_AcknowledgeType_t type) {
|
|
859
|
+
/* Decrement unacked count when transitioning from ACQUIRED */
|
|
860
|
+
if (entry->types[idx] == RD_KAFKA_SHARE_INTERNAL_ACK_ACQUIRED)
|
|
861
|
+
rkshare->rkshare_unacked_cnt--;
|
|
862
|
+
|
|
863
|
+
/* Update the type */
|
|
864
|
+
entry->types[idx] = (rd_kafka_share_internal_acknowledgement_type)type;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* @brief Comparator for sorting/checking entries by start_offset.
|
|
869
|
+
*
|
|
870
|
+
* Used with rd_list_sort() and rd_list_is_sorted().
|
|
871
|
+
*/
|
|
872
|
+
int rd_kafka_share_ack_entries_sort_cmp_ptr(const void *_a, const void *_b) {
|
|
873
|
+
const rd_kafka_share_ack_batch_entry_t *a =
|
|
874
|
+
(const rd_kafka_share_ack_batch_entry_t *)_a;
|
|
875
|
+
const rd_kafka_share_ack_batch_entry_t *b =
|
|
876
|
+
(const rd_kafka_share_ack_batch_entry_t *)_b;
|
|
877
|
+
|
|
878
|
+
if (a->start_offset < b->start_offset)
|
|
879
|
+
return -1;
|
|
880
|
+
if (a->start_offset > b->start_offset)
|
|
881
|
+
return 1;
|
|
882
|
+
return 0;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* @brief Comparator for finding an entry containing a given offset.
|
|
887
|
+
*
|
|
888
|
+
* Used with rd_list_find() for binary search when RD_LIST_F_SORTED is set.
|
|
889
|
+
*
|
|
890
|
+
* @param _offset Pointer to the offset being searched (int64_t *)
|
|
891
|
+
* @param _entry Pointer to the batch entry (rd_kafka_share_ack_batch_entry_t *)
|
|
892
|
+
*
|
|
893
|
+
* @returns negative if offset < entry->start_offset
|
|
894
|
+
* @returns positive if offset > entry->end_offset
|
|
895
|
+
* @returns 0 if offset is within [start_offset, end_offset]
|
|
896
|
+
*/
|
|
897
|
+
static int rd_kafka_share_ack_entries_offset_find_cmp_ptr(const void *_offset,
|
|
898
|
+
const void *_entry) {
|
|
899
|
+
const int64_t *offset = (const int64_t *)_offset;
|
|
900
|
+
const rd_kafka_share_ack_batch_entry_t *entry =
|
|
901
|
+
(const rd_kafka_share_ack_batch_entry_t *)_entry;
|
|
902
|
+
|
|
903
|
+
if (*offset < entry->start_offset)
|
|
904
|
+
return -1;
|
|
905
|
+
if (*offset > entry->end_offset)
|
|
906
|
+
return 1;
|
|
907
|
+
return 0;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* @brief Look up a batch entry containing the given offset.
|
|
912
|
+
*
|
|
913
|
+
* Finds the partition in the inflight_acks map and locates the entry
|
|
914
|
+
* containing the specified offset using binary search.
|
|
915
|
+
*
|
|
916
|
+
* @param rkshare Share consumer handle.
|
|
917
|
+
* @param topic Topic name.
|
|
918
|
+
* @param partition Partition id.
|
|
919
|
+
* @param offset Offset to find.
|
|
920
|
+
* @param entry_out Output parameter for the found entry.
|
|
921
|
+
* @param idx_out Output parameter for the index within the entry.
|
|
922
|
+
*
|
|
923
|
+
* @returns RD_KAFKA_RESP_ERR_NO_ERROR on success,
|
|
924
|
+
* RD_KAFKA_RESP_ERR__STATE if partition or offset not found.
|
|
925
|
+
*/
|
|
926
|
+
static rd_kafka_resp_err_t
|
|
927
|
+
rd_kafka_share_find_ack_entry(rd_kafka_share_t *rkshare,
|
|
928
|
+
const char *topic,
|
|
929
|
+
int32_t partition,
|
|
930
|
+
int64_t offset,
|
|
931
|
+
rd_kafka_share_ack_batch_entry_t **entry_out,
|
|
932
|
+
int64_t *idx_out) {
|
|
933
|
+
rd_kafka_topic_partition_t *lookup_key;
|
|
934
|
+
rd_kafka_share_ack_batches_t *batches;
|
|
935
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
936
|
+
|
|
937
|
+
/* Find partition in inflight_acks map */
|
|
938
|
+
lookup_key = rd_kafka_topic_partition_new(topic, partition);
|
|
939
|
+
batches = RD_MAP_GET(&rkshare->rkshare_inflight_acks, lookup_key);
|
|
940
|
+
rd_kafka_topic_partition_destroy(lookup_key);
|
|
941
|
+
if (!batches)
|
|
942
|
+
return RD_KAFKA_RESP_ERR__STATE;
|
|
943
|
+
|
|
944
|
+
/* Find entry containing offset using binary search.
|
|
945
|
+
* Entries are sorted by start_offset and don't overlap. */
|
|
946
|
+
entry = rd_list_find(&batches->entries, &offset,
|
|
947
|
+
rd_kafka_share_ack_entries_offset_find_cmp_ptr);
|
|
948
|
+
if (!entry)
|
|
949
|
+
return RD_KAFKA_RESP_ERR__STATE;
|
|
950
|
+
|
|
951
|
+
*entry_out = entry;
|
|
952
|
+
*idx_out = offset - entry->start_offset;
|
|
953
|
+
|
|
954
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* @brief Internal acknowledge-offset helper.
|
|
959
|
+
*
|
|
960
|
+
* Performs argument validation, inflight-map lookup, and type update.
|
|
961
|
+
* Does NOT take the share consumer access gate — callers must call
|
|
962
|
+
* rd_kafka_share_acquire() / rd_kafka_share_release() around this.
|
|
963
|
+
*/
|
|
964
|
+
static rd_kafka_resp_err_t
|
|
965
|
+
rd_kafka_share_acknowledge_offset0(rd_kafka_share_t *rkshare,
|
|
966
|
+
const char *topic,
|
|
967
|
+
int32_t partition,
|
|
968
|
+
int64_t offset,
|
|
969
|
+
rd_kafka_share_AcknowledgeType_t type) {
|
|
970
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
971
|
+
int64_t idx;
|
|
972
|
+
rd_kafka_resp_err_t err;
|
|
973
|
+
|
|
974
|
+
if (unlikely((err = rd_kafka_share_consumer_closed_err(rkshare))))
|
|
975
|
+
return err;
|
|
976
|
+
|
|
977
|
+
if (!topic || partition < 0 || offset < 0)
|
|
978
|
+
return RD_KAFKA_RESP_ERR__INVALID_ARG;
|
|
979
|
+
|
|
980
|
+
/* Explicit acknowledge APIs require explicit acknowledgement mode */
|
|
981
|
+
if (rd_kafka_share_acknowledgement_mode_is_implicit(rkshare))
|
|
982
|
+
return RD_KAFKA_RESP_ERR__STATE;
|
|
983
|
+
|
|
984
|
+
/* Validate type - ACCEPT, RELEASE, REJECT allowed */
|
|
985
|
+
if (type < RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_ACCEPT ||
|
|
986
|
+
type > RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_REJECT)
|
|
987
|
+
return RD_KAFKA_RESP_ERR__INVALID_ARG;
|
|
988
|
+
|
|
989
|
+
/* Find partition and entry containing the offset */
|
|
990
|
+
err = rd_kafka_share_find_ack_entry(rkshare, topic, partition, offset,
|
|
991
|
+
&entry, &idx);
|
|
992
|
+
if (err)
|
|
993
|
+
return err;
|
|
994
|
+
|
|
995
|
+
/* GAP records cannot be acknowledged */
|
|
996
|
+
if (entry->types[idx] == RD_KAFKA_SHARE_INTERNAL_ACK_GAP)
|
|
997
|
+
return RD_KAFKA_RESP_ERR__STATE;
|
|
998
|
+
|
|
999
|
+
rd_kafka_share_update_acknowledgement_type(rkshare, entry, idx, type);
|
|
1000
|
+
|
|
1001
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
rd_kafka_resp_err_t
|
|
1005
|
+
rd_kafka_share_acknowledge(rd_kafka_share_t *rkshare,
|
|
1006
|
+
const rd_kafka_message_t *rkmessage) {
|
|
1007
|
+
return rd_kafka_share_acknowledge_type(
|
|
1008
|
+
rkshare, rkmessage, RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_ACCEPT);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
rd_kafka_resp_err_t
|
|
1012
|
+
rd_kafka_share_acknowledge_type(rd_kafka_share_t *rkshare,
|
|
1013
|
+
const rd_kafka_message_t *rkmessage,
|
|
1014
|
+
rd_kafka_share_AcknowledgeType_t type) {
|
|
1015
|
+
rd_kafka_resp_err_t err;
|
|
1016
|
+
rd_kafka_error_t *error = NULL;
|
|
1017
|
+
|
|
1018
|
+
if (unlikely((error = rd_kafka_share_acquire(rkshare)) != NULL)) {
|
|
1019
|
+
err = rd_kafka_error_code(error);
|
|
1020
|
+
rd_kafka_error_destroy(error);
|
|
1021
|
+
return err;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
if (!rkmessage) {
|
|
1025
|
+
err = RD_KAFKA_RESP_ERR__INVALID_ARG;
|
|
1026
|
+
goto done;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
if (!rkmessage->rkt) {
|
|
1030
|
+
err = RD_KAFKA_RESP_ERR__STATE;
|
|
1031
|
+
goto done;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
err = rd_kafka_share_acknowledge_offset0(
|
|
1035
|
+
rkshare, rd_kafka_topic_name(rkmessage->rkt), rkmessage->partition,
|
|
1036
|
+
rkmessage->offset, type);
|
|
1037
|
+
|
|
1038
|
+
done:
|
|
1039
|
+
rd_kafka_share_release(rkshare);
|
|
1040
|
+
return err;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
rd_kafka_resp_err_t
|
|
1044
|
+
rd_kafka_share_acknowledge_offset(rd_kafka_share_t *rkshare,
|
|
1045
|
+
const char *topic,
|
|
1046
|
+
int32_t partition,
|
|
1047
|
+
int64_t offset,
|
|
1048
|
+
rd_kafka_share_AcknowledgeType_t type) {
|
|
1049
|
+
rd_kafka_resp_err_t err;
|
|
1050
|
+
rd_kafka_error_t *error = NULL;
|
|
1051
|
+
|
|
1052
|
+
if (unlikely((error = rd_kafka_share_acquire(rkshare)) != NULL)) {
|
|
1053
|
+
err = rd_kafka_error_code(error);
|
|
1054
|
+
rd_kafka_error_destroy(error);
|
|
1055
|
+
return err;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
err = rd_kafka_share_acknowledge_offset0(rkshare, topic, partition,
|
|
1059
|
+
offset, type);
|
|
1060
|
+
|
|
1061
|
+
rd_kafka_share_release(rkshare);
|
|
1062
|
+
return err;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* @brief Initialize a partition offsets element with topicid,topic, partition,
|
|
1068
|
+
* and offsets.
|
|
1069
|
+
*
|
|
1070
|
+
* @param topic_id Topic UUID.
|
|
1071
|
+
* @param topic Topic name (will be duplicated).
|
|
1072
|
+
* @param partition Partition id.
|
|
1073
|
+
* @param offsets_cnt Number of offsets to allocate space for.
|
|
1074
|
+
*/
|
|
1075
|
+
static rd_kafka_share_partition_offsets_t *
|
|
1076
|
+
rd_kafka_share_partition_offsets_new(rd_kafka_topic_partition_t *tp,
|
|
1077
|
+
size_t offsets_cnt) {
|
|
1078
|
+
rd_kafka_share_partition_offsets_t *elem;
|
|
1079
|
+
size_t size;
|
|
1080
|
+
|
|
1081
|
+
/* Allocate struct + flexible array in one allocation */
|
|
1082
|
+
size = sizeof(*elem) + (offsets_cnt * sizeof(int64_t));
|
|
1083
|
+
elem = rd_calloc(1, size);
|
|
1084
|
+
|
|
1085
|
+
elem->partition = rd_kafka_topic_partition_new_with_id_and_name(
|
|
1086
|
+
rd_kafka_topic_partition_get_topic_id(tp), tp->topic,
|
|
1087
|
+
tp->partition);
|
|
1088
|
+
elem->cnt = offsets_cnt;
|
|
1089
|
+
|
|
1090
|
+
return elem;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* @brief Destroy a partition offsets element.
|
|
1095
|
+
*
|
|
1096
|
+
* @param elem Element to destroy.
|
|
1097
|
+
*/
|
|
1098
|
+
static void rd_kafka_share_partition_offsets_destroy(
|
|
1099
|
+
rd_kafka_share_partition_offsets_t *elem) {
|
|
1100
|
+
if (!elem)
|
|
1101
|
+
return;
|
|
1102
|
+
rd_kafka_topic_partition_destroy(elem->partition);
|
|
1103
|
+
rd_free(elem);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @brief Allocate and initialize a partition offsets list with given capacity.
|
|
1108
|
+
*
|
|
1109
|
+
* @param capacity Number of elements to allocate space for.
|
|
1110
|
+
* @returns Newly allocated list, or NULL if capacity is 0.
|
|
1111
|
+
* Caller must destroy with
|
|
1112
|
+
* rd_kafka_share_partition_offsets_list_destroy().
|
|
1113
|
+
*/
|
|
1114
|
+
static rd_kafka_share_partition_offsets_list_t *
|
|
1115
|
+
rd_kafka_share_partition_offsets_list_new(size_t capacity) {
|
|
1116
|
+
rd_kafka_share_partition_offsets_list_t *list;
|
|
1117
|
+
size_t size;
|
|
1118
|
+
|
|
1119
|
+
/* Allocate list + flexible array in one allocation */
|
|
1120
|
+
size = sizeof(*list) +
|
|
1121
|
+
(capacity * sizeof(rd_kafka_share_partition_offsets_t *));
|
|
1122
|
+
list = rd_calloc(1, size);
|
|
1123
|
+
|
|
1124
|
+
return list;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
rd_kafka_share_partition_offsets_list_t *
|
|
1128
|
+
rd_kafka_share_build_partition_offsets_list(
|
|
1129
|
+
rd_kafka_share_ack_batches_t *batches) {
|
|
1130
|
+
rd_kafka_share_partition_offsets_list_t *list;
|
|
1131
|
+
rd_kafka_share_partition_offsets_t *elem;
|
|
1132
|
+
rd_kafka_share_ack_batch_entry_t *entry;
|
|
1133
|
+
int total_offsets = 0;
|
|
1134
|
+
int offset_idx = 0;
|
|
1135
|
+
int j;
|
|
1136
|
+
|
|
1137
|
+
/* Count total offsets */
|
|
1138
|
+
RD_LIST_FOREACH(entry, &batches->entries, j) {
|
|
1139
|
+
total_offsets +=
|
|
1140
|
+
(int)(entry->end_offset - entry->start_offset + 1);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
list = rd_kafka_share_partition_offsets_list_new(1);
|
|
1144
|
+
|
|
1145
|
+
/* Allocate elements */
|
|
1146
|
+
elem = rd_kafka_share_partition_offsets_new(batches->rktpar,
|
|
1147
|
+
total_offsets);
|
|
1148
|
+
|
|
1149
|
+
list->cnt = 1;
|
|
1150
|
+
list->elems[0] = elem;
|
|
1151
|
+
|
|
1152
|
+
/* Fill offsets array */
|
|
1153
|
+
RD_LIST_FOREACH(entry, &batches->entries, j) {
|
|
1154
|
+
int64_t off;
|
|
1155
|
+
for (off = entry->start_offset; off <= entry->end_offset;
|
|
1156
|
+
off++) {
|
|
1157
|
+
elem->offsets[offset_idx++] = off;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
return list;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
void rd_kafka_share_enqueue_ack_commit_cb_op(
|
|
1166
|
+
rd_kafka_t *rk,
|
|
1167
|
+
rd_kafka_share_ack_batches_t *batches,
|
|
1168
|
+
rd_kafka_resp_err_t err) {
|
|
1169
|
+
rd_kafka_op_t *cb_rko;
|
|
1170
|
+
rd_kafka_share_partition_offsets_list_t *partitions;
|
|
1171
|
+
|
|
1172
|
+
/* Check if a runtime callback is registered.
|
|
1173
|
+
* Locality: main thread - reads flag owned by main thread.
|
|
1174
|
+
* No race because the flag is only modified by the main thread
|
|
1175
|
+
* via RD_KAFKA_OP_SHARE_ACK_COMMIT_CB_REGISTER op handler. */
|
|
1176
|
+
if (!rk->rk_rkshare ||
|
|
1177
|
+
!rk->rk_share_consumer.acknowledgement_commit_cb_registered)
|
|
1178
|
+
return;
|
|
1179
|
+
|
|
1180
|
+
partitions = rd_kafka_share_build_partition_offsets_list(batches);
|
|
1181
|
+
|
|
1182
|
+
cb_rko = rd_kafka_op_new(RD_KAFKA_OP_SHARE_ACK_COMMIT_CB_EXECUTE);
|
|
1183
|
+
cb_rko->rko_err = err;
|
|
1184
|
+
cb_rko->rko_u.share_ack_commit_cb_execute.partitions = partitions;
|
|
1185
|
+
|
|
1186
|
+
rd_kafka_q_enq(rk->rk_rep, cb_rko);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
size_t rd_kafka_share_partition_offsets_list_count(
|
|
1191
|
+
const rd_kafka_share_partition_offsets_list_t *list) {
|
|
1192
|
+
return list->cnt;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
const rd_kafka_share_partition_offsets_t *
|
|
1197
|
+
rd_kafka_share_partition_offsets_list_get(
|
|
1198
|
+
const rd_kafka_share_partition_offsets_list_t *list,
|
|
1199
|
+
size_t index) {
|
|
1200
|
+
return list->elems[index];
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
void rd_kafka_share_partition_offsets_list_destroy(
|
|
1205
|
+
rd_kafka_share_partition_offsets_list_t *list) {
|
|
1206
|
+
size_t i;
|
|
1207
|
+
|
|
1208
|
+
if (!list)
|
|
1209
|
+
return;
|
|
1210
|
+
|
|
1211
|
+
/* Free each element */
|
|
1212
|
+
for (i = 0; i < list->cnt; i++) {
|
|
1213
|
+
rd_kafka_share_partition_offsets_destroy(list->elems[i]);
|
|
1214
|
+
}
|
|
1215
|
+
/* Free the list (elems array is inline via FAM) */
|
|
1216
|
+
rd_free(list);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
const rd_kafka_topic_partition_t *rd_kafka_share_partition_offsets_partition(
|
|
1221
|
+
const rd_kafka_share_partition_offsets_t *partition_offsets) {
|
|
1222
|
+
return partition_offsets->partition;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
const int64_t *rd_kafka_share_partition_offsets_offsets(
|
|
1227
|
+
const rd_kafka_share_partition_offsets_t *partition_offsets) {
|
|
1228
|
+
return partition_offsets->offsets;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
size_t rd_kafka_share_partition_offsets_offsets_cnt(
|
|
1233
|
+
const rd_kafka_share_partition_offsets_t *partition_offsets) {
|
|
1234
|
+
return partition_offsets->cnt;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* @brief Translate librdkafka-internal err sentinels into the broker-equivalent
|
|
1240
|
+
* codes the application is expected to handle.
|
|
1241
|
+
*/
|
|
1242
|
+
static rd_kafka_resp_err_t
|
|
1243
|
+
rd_kafka_share_translate_app_err(rd_kafka_resp_err_t err) {
|
|
1244
|
+
switch (err) {
|
|
1245
|
+
case RD_KAFKA_RESP_ERR__TIMED_OUT:
|
|
1246
|
+
case RD_KAFKA_RESP_ERR__TIMED_OUT_QUEUE:
|
|
1247
|
+
return RD_KAFKA_RESP_ERR_REQUEST_TIMED_OUT;
|
|
1248
|
+
case RD_KAFKA_RESP_ERR__DESTROY:
|
|
1249
|
+
case RD_KAFKA_RESP_ERR__DESTROY_BROKER:
|
|
1250
|
+
return RD_KAFKA_RESP_ERR__TRANSPORT;
|
|
1251
|
+
case RD_KAFKA_RESP_ERR__BAD_MSG:
|
|
1252
|
+
return RD_KAFKA_RESP_ERR_INVALID_MSG;
|
|
1253
|
+
case RD_KAFKA_RESP_ERR__AUTHENTICATION:
|
|
1254
|
+
return RD_KAFKA_RESP_ERR_SASL_AUTHENTICATION_FAILED;
|
|
1255
|
+
default:
|
|
1256
|
+
return err;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
void rd_kafka_share_dispatch_ack_callbacks(rd_kafka_t *rk,
|
|
1261
|
+
rd_list_t *ack_details) {
|
|
1262
|
+
rd_kafka_share_ack_batches_t *ack_batch;
|
|
1263
|
+
int k;
|
|
1264
|
+
|
|
1265
|
+
/* Locality: main thread - checks runtime-set registration flag. */
|
|
1266
|
+
/**
|
|
1267
|
+
* TODO KIP-932: Check if we want to send individual ops or 1 op.
|
|
1268
|
+
*/
|
|
1269
|
+
if (!rk->rk_share_consumer.acknowledgement_commit_cb_registered ||
|
|
1270
|
+
!ack_details || rd_list_cnt(ack_details) == 0)
|
|
1271
|
+
return;
|
|
1272
|
+
|
|
1273
|
+
/* Use per-partition error from each batch, translating internal
|
|
1274
|
+
* sentinels to their broker-equivalent codes before the app sees
|
|
1275
|
+
* them. */
|
|
1276
|
+
RD_LIST_FOREACH(ack_batch, ack_details, k) {
|
|
1277
|
+
ack_batch->rktpar->err =
|
|
1278
|
+
rd_kafka_share_translate_app_err(ack_batch->rktpar->err);
|
|
1279
|
+
rd_kafka_share_enqueue_ack_commit_cb_op(rk, ack_batch,
|
|
1280
|
+
ack_batch->rktpar->err);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
/**
|
|
1285
|
+
* @brief Send commit_sync response to the app thread and clear state.
|
|
1286
|
+
*
|
|
1287
|
+
* Creates a SHARE_COMMIT_SYNC_FANOUT reply op with the per-partition
|
|
1288
|
+
* results and enqueues it on the app thread's temp queue. Clears the
|
|
1289
|
+
* commit_sync request state.
|
|
1290
|
+
*
|
|
1291
|
+
* @param rkcg Consumer group handle.
|
|
1292
|
+
*
|
|
1293
|
+
* @locality main thread
|
|
1294
|
+
*/
|
|
1295
|
+
void rd_kafka_share_commit_sync_send_response(rd_kafka_cgrp_t *rkcg) {
|
|
1296
|
+
rd_kafka_op_t *rko_reply;
|
|
1297
|
+
rd_kafka_topic_partition_list_t *results =
|
|
1298
|
+
rkcg->rkcg_commit_sync_request.results;
|
|
1299
|
+
int i;
|
|
1300
|
+
|
|
1301
|
+
/* Translate internal sentinels to broker-equivalent codes before
|
|
1302
|
+
* the app sees them. This is the unique fan-in for every
|
|
1303
|
+
* commit_sync result: every writer (apply_result, segregate-fail,
|
|
1304
|
+
* api-timer-cb, broker decommission) lands its err in this list
|
|
1305
|
+
* before we ship it back to the caller. */
|
|
1306
|
+
for (i = 0; i < results->cnt; i++)
|
|
1307
|
+
results->elems[i].err =
|
|
1308
|
+
rd_kafka_share_translate_app_err(results->elems[i].err);
|
|
1309
|
+
|
|
1310
|
+
rko_reply = rd_kafka_op_new(RD_KAFKA_OP_SHARE_COMMIT_SYNC_FANOUT_REPLY);
|
|
1311
|
+
rko_reply->rko_u.share_commit_sync_fanout_reply.results = results;
|
|
1312
|
+
|
|
1313
|
+
rd_kafka_q_enq(rkcg->rkcg_commit_sync_request.replyq, rko_reply);
|
|
1314
|
+
rd_kafka_q_destroy(rkcg->rkcg_commit_sync_request.replyq);
|
|
1315
|
+
|
|
1316
|
+
rkcg->rkcg_commit_sync_request.id = 0;
|
|
1317
|
+
rkcg->rkcg_commit_sync_request.results = NULL;
|
|
1318
|
+
rkcg->rkcg_commit_sync_request.replyq = NULL;
|
|
1319
|
+
rkcg->rkcg_commit_sync_request.abs_timeout = 0;
|
|
1320
|
+
rkcg->rkcg_commit_sync_request.brokers_awaiting_result_cnt = 0;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
/**
|
|
1324
|
+
* @brief Check if all broker results are in and send response if done.
|
|
1325
|
+
*
|
|
1326
|
+
* Called after each broker reply arrives. If brokers_awaiting_result_cnt
|
|
1327
|
+
* reaches zero, stops the timeout timer and sends the response op
|
|
1328
|
+
* to the app thread's temp queue.
|
|
1329
|
+
*
|
|
1330
|
+
* @param rk Client instance.
|
|
1331
|
+
* @param rkcg Consumer group handle.
|
|
1332
|
+
*
|
|
1333
|
+
* @locality main thread
|
|
1334
|
+
*/
|
|
1335
|
+
void rd_kafka_share_commit_sync_maybe_complete(rd_kafka_t *rk,
|
|
1336
|
+
rd_kafka_cgrp_t *rkcg) {
|
|
1337
|
+
if (rkcg->rkcg_commit_sync_request.brokers_awaiting_result_cnt > 0)
|
|
1338
|
+
return;
|
|
1339
|
+
|
|
1340
|
+
rd_kafka_dbg(rk, CGRP, "SHARE",
|
|
1341
|
+
"Commit sync request %" PRId64
|
|
1342
|
+
" complete; all broker replies received, "
|
|
1343
|
+
"sending response",
|
|
1344
|
+
rkcg->rkcg_commit_sync_request.id);
|
|
1345
|
+
|
|
1346
|
+
rd_kafka_timer_stop(&rk->rk_timers, &rkcg->rkcg_commit_sync_request.tmr,
|
|
1347
|
+
1);
|
|
1348
|
+
|
|
1349
|
+
rd_kafka_share_commit_sync_send_response(rkcg);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* @brief Apply a broker's commit_sync result: copy each batch's
|
|
1354
|
+
* per-partition err onto the corresponding entry in
|
|
1355
|
+
* rkcg_commit_sync_request.results, decrement the count of
|
|
1356
|
+
* brokers still awaiting reply, and complete the commit_sync
|
|
1357
|
+
* if this was the last broker outstanding.
|
|
1358
|
+
*
|
|
1359
|
+
* The caller is responsible for setting batch->rktpar->err on each
|
|
1360
|
+
* batch before invoking this (either from the broker reply path or
|
|
1361
|
+
* from a synthetic failure path like broker decommission).
|
|
1362
|
+
*
|
|
1363
|
+
* @locality main thread.
|
|
1364
|
+
*/
|
|
1365
|
+
void rd_kafka_share_commit_sync_apply_result(rd_kafka_t *rk,
|
|
1366
|
+
rd_kafka_cgrp_t *rkcg,
|
|
1367
|
+
rd_list_t *ack_batches) {
|
|
1368
|
+
if (ack_batches) {
|
|
1369
|
+
rd_kafka_share_ack_batches_t *batch;
|
|
1370
|
+
int k;
|
|
1371
|
+
|
|
1372
|
+
RD_LIST_FOREACH(batch, ack_batches, k) {
|
|
1373
|
+
rd_kafka_topic_partition_t *dst =
|
|
1374
|
+
rd_kafka_topic_partition_list_find(
|
|
1375
|
+
rkcg->rkcg_commit_sync_request.results,
|
|
1376
|
+
batch->rktpar->topic, batch->rktpar->partition);
|
|
1377
|
+
if (dst)
|
|
1378
|
+
dst->err = batch->rktpar->err;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
rkcg->rkcg_commit_sync_request.brokers_awaiting_result_cnt--;
|
|
1383
|
+
rd_kafka_share_commit_sync_maybe_complete(rk, rkcg);
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
void rd_kafka_share_acks_clear_during_broker_decommission(
|
|
1388
|
+
rd_kafka_t *rk,
|
|
1389
|
+
rd_kafka_broker_t *rkb) {
|
|
1390
|
+
rd_kafka_share_ack_batches_t *batch;
|
|
1391
|
+
int k;
|
|
1392
|
+
|
|
1393
|
+
/* Async acks: stamp SHARE_SESSION_NOT_FOUND on each batch and
|
|
1394
|
+
* fire the share-ack callback so the application sees the
|
|
1395
|
+
* failure. */
|
|
1396
|
+
if (rkb->rkb_share_async_ack_details) {
|
|
1397
|
+
rd_rkb_dbg(rkb, BROKER, "TERM",
|
|
1398
|
+
"Clearing %d pending async ack batch(es); "
|
|
1399
|
+
"dispatching ack callbacks with "
|
|
1400
|
+
"SHARE_SESSION_NOT_FOUND",
|
|
1401
|
+
rd_list_cnt(rkb->rkb_share_async_ack_details));
|
|
1402
|
+
|
|
1403
|
+
RD_LIST_FOREACH(batch, rkb->rkb_share_async_ack_details, k) {
|
|
1404
|
+
batch->rktpar->err =
|
|
1405
|
+
RD_KAFKA_RESP_ERR_SHARE_SESSION_NOT_FOUND;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
rd_kafka_share_dispatch_ack_callbacks(
|
|
1409
|
+
rk, rkb->rkb_share_async_ack_details);
|
|
1410
|
+
|
|
1411
|
+
rd_list_destroy(rkb->rkb_share_async_ack_details);
|
|
1412
|
+
rkb->rkb_share_async_ack_details = NULL;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/* Sync acks: stamp SHARE_SESSION_NOT_FOUND on each batch and
|
|
1416
|
+
* apply the result to the in-flight commit_sync request (copies
|
|
1417
|
+
* err into the cgrp's result list, decrements awaiting count,
|
|
1418
|
+
* completes the sync if this was the last broker outstanding). */
|
|
1419
|
+
if (rkb->rkb_pending_commit_sync.sync_ack_details) {
|
|
1420
|
+
rd_kafka_cgrp_t *rkcg = rd_kafka_cgrp_get(rk);
|
|
1421
|
+
|
|
1422
|
+
rd_rkb_dbg(
|
|
1423
|
+
rkb, BROKER, "TERM",
|
|
1424
|
+
"Clearing %d pending commit sync ack batch(es); "
|
|
1425
|
+
"dispatching ack callbacks and "
|
|
1426
|
+
"stamping SHARE_SESSION_NOT_FOUND on commit_sync result "
|
|
1427
|
+
"for this broker's partitions",
|
|
1428
|
+
rd_list_cnt(rkb->rkb_pending_commit_sync.sync_ack_details));
|
|
1429
|
+
|
|
1430
|
+
RD_LIST_FOREACH(
|
|
1431
|
+
batch, rkb->rkb_pending_commit_sync.sync_ack_details, k) {
|
|
1432
|
+
batch->rktpar->err =
|
|
1433
|
+
RD_KAFKA_RESP_ERR_SHARE_SESSION_NOT_FOUND;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
rd_kafka_share_commit_sync_apply_result(
|
|
1437
|
+
rk, rkcg, rkb->rkb_pending_commit_sync.sync_ack_details);
|
|
1438
|
+
|
|
1439
|
+
rd_kafka_share_dispatch_ack_callbacks(
|
|
1440
|
+
rk, rkb->rkb_pending_commit_sync.sync_ack_details);
|
|
1441
|
+
|
|
1442
|
+
rd_list_destroy(rkb->rkb_pending_commit_sync.sync_ack_details);
|
|
1443
|
+
rkb->rkb_pending_commit_sync.sync_ack_details = NULL;
|
|
1444
|
+
}
|
|
1445
|
+
}
|