@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,1207 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* librdkafka - Apache Kafka C library
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025, 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
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Mocks
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#include "rdkafka_int.h"
|
|
36
|
+
#include "rdbuf.h"
|
|
37
|
+
#include "rdkafka_mock_int.h"
|
|
38
|
+
#include <math.h>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @brief Share group target assignment (manual)
|
|
42
|
+
*/
|
|
43
|
+
typedef struct rd_kafka_mock_sharegroup_target_assignments_s {
|
|
44
|
+
rd_list_t member_ids; /**< List of member ids (char *) */
|
|
45
|
+
rd_list_t assignment; /**< List of rd_kafka_topic_partition_list_t */
|
|
46
|
+
} rd_kafka_mock_sharegroup_target_assignment_t;
|
|
47
|
+
|
|
48
|
+
/* Forward declarations */
|
|
49
|
+
static void rd_kafka_mock_sharegroup_session_tmr_cb(rd_kafka_timers_t *rkts,
|
|
50
|
+
void *arg);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @brief Initializes sharegroups in mock cluster
|
|
54
|
+
*/
|
|
55
|
+
void rd_kafka_mock_sharegrps_init(rd_kafka_mock_cluster_t *mcluster) {
|
|
56
|
+
TAILQ_INIT(&mcluster->sharegrps);
|
|
57
|
+
mcluster->defaults.sharegroup_session_timeout_ms = 45000;
|
|
58
|
+
mcluster->defaults.sharegroup_heartbeat_interval_ms = 5000;
|
|
59
|
+
mcluster->defaults.sharegroup_max_delivery_attempts = 5;
|
|
60
|
+
mcluster->defaults.sharegroup_record_lock_duration_ms = 30000;
|
|
61
|
+
mcluster->defaults.sharegroup_max_size = 200;
|
|
62
|
+
mcluster->defaults.sharegroup_isolation_level = 0;
|
|
63
|
+
mcluster->defaults.sharegroup_max_fetch_sessions = 2000;
|
|
64
|
+
mcluster->defaults.sharegroup_max_record_locks = 2000;
|
|
65
|
+
mcluster->defaults.sharegroup_auto_offset_reset = 0; /* latest */
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @brief Find a share group by GroupId.
|
|
70
|
+
*/
|
|
71
|
+
rd_kafka_mock_sharegroup_t *
|
|
72
|
+
rd_kafka_mock_sharegroup_find(rd_kafka_mock_cluster_t *mcluster,
|
|
73
|
+
const rd_kafkap_str_t *GroupId) {
|
|
74
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
75
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link) {
|
|
76
|
+
if (!rd_kafkap_str_cmp_str(GroupId, mshgrp->id))
|
|
77
|
+
return mshgrp;
|
|
78
|
+
}
|
|
79
|
+
return NULL;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @brief Get or create a share group
|
|
84
|
+
*/
|
|
85
|
+
rd_kafka_mock_sharegroup_t *
|
|
86
|
+
rd_kafka_mock_sharegroup_get(rd_kafka_mock_cluster_t *mcluster,
|
|
87
|
+
const rd_kafkap_str_t *GroupID) {
|
|
88
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
89
|
+
|
|
90
|
+
/* Check if the share group already exists */
|
|
91
|
+
mshgrp = rd_kafka_mock_sharegroup_find(mcluster, GroupID);
|
|
92
|
+
if (mshgrp)
|
|
93
|
+
return mshgrp;
|
|
94
|
+
|
|
95
|
+
/* Create new share group */
|
|
96
|
+
mshgrp = rd_calloc(1, sizeof(*mshgrp));
|
|
97
|
+
mshgrp->cluster = mcluster;
|
|
98
|
+
mshgrp->id = RD_KAFKAP_STR_DUP(GroupID);
|
|
99
|
+
mshgrp->group_epoch = 1;
|
|
100
|
+
mshgrp->session_timeout_ms =
|
|
101
|
+
mcluster->defaults.sharegroup_session_timeout_ms;
|
|
102
|
+
mshgrp->heartbeat_interval_ms =
|
|
103
|
+
mcluster->defaults.sharegroup_heartbeat_interval_ms;
|
|
104
|
+
|
|
105
|
+
TAILQ_INIT(&mshgrp->members);
|
|
106
|
+
mshgrp->member_cnt = 0;
|
|
107
|
+
|
|
108
|
+
/* ShareFetch state */
|
|
109
|
+
TAILQ_INIT(&mshgrp->partitions);
|
|
110
|
+
TAILQ_INIT(&mshgrp->fetch_sessions);
|
|
111
|
+
mshgrp->partition_cnt = 0;
|
|
112
|
+
mshgrp->fetch_session_cnt = 0;
|
|
113
|
+
|
|
114
|
+
/* Per-record limits */
|
|
115
|
+
mshgrp->max_delivery_attempts =
|
|
116
|
+
mcluster->defaults.sharegroup_max_delivery_attempts;
|
|
117
|
+
mshgrp->record_lock_duration_ms =
|
|
118
|
+
mcluster->defaults.sharegroup_record_lock_duration_ms;
|
|
119
|
+
mshgrp->isolation_level = mcluster->defaults.sharegroup_isolation_level;
|
|
120
|
+
mshgrp->max_size = mcluster->defaults.sharegroup_max_size;
|
|
121
|
+
mshgrp->max_fetch_sessions =
|
|
122
|
+
mcluster->defaults.sharegroup_max_fetch_sessions;
|
|
123
|
+
mshgrp->max_record_locks =
|
|
124
|
+
mcluster->defaults.sharegroup_max_record_locks;
|
|
125
|
+
mshgrp->auto_offset_reset =
|
|
126
|
+
mcluster->defaults.sharegroup_auto_offset_reset;
|
|
127
|
+
|
|
128
|
+
rd_kafka_timer_start(&mcluster->timers, &mshgrp->session_tmr,
|
|
129
|
+
1000 * 1000 /* 1s */,
|
|
130
|
+
rd_kafka_mock_sharegroup_session_tmr_cb, mshgrp);
|
|
131
|
+
|
|
132
|
+
/* Fetch session expiry timer */
|
|
133
|
+
rd_kafka_timer_start(&mcluster->timers, &mshgrp->fetch_session_tmr,
|
|
134
|
+
1000 * 1000 /* 1s */,
|
|
135
|
+
rd_kafka_mock_sgrp_fetch_session_tmr_cb, mshgrp);
|
|
136
|
+
|
|
137
|
+
TAILQ_INSERT_TAIL(&mcluster->sharegrps, mshgrp, link);
|
|
138
|
+
|
|
139
|
+
return mshgrp;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @brief Destroy a share group
|
|
144
|
+
*/
|
|
145
|
+
void rd_kafka_mock_sharegroup_destroy(rd_kafka_mock_sharegroup_t *mshgrp) {
|
|
146
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
147
|
+
rd_kafka_mock_sgrp_partmeta_t *pmeta;
|
|
148
|
+
rd_kafka_mock_sgrp_fetch_session_t *session;
|
|
149
|
+
|
|
150
|
+
TAILQ_REMOVE(&mshgrp->cluster->sharegrps, mshgrp, link);
|
|
151
|
+
rd_kafka_timer_stop(&mshgrp->cluster->timers, &mshgrp->session_tmr,
|
|
152
|
+
RD_DO_LOCK);
|
|
153
|
+
rd_kafka_timer_stop(&mshgrp->cluster->timers,
|
|
154
|
+
&mshgrp->fetch_session_tmr, RD_DO_LOCK);
|
|
155
|
+
|
|
156
|
+
/* Destroy all members */
|
|
157
|
+
while ((member = TAILQ_FIRST(&mshgrp->members)))
|
|
158
|
+
rd_kafka_mock_sharegroup_member_destroy(mshgrp, member);
|
|
159
|
+
|
|
160
|
+
/* Destroy ShareFetch partition metadata */
|
|
161
|
+
while ((pmeta = TAILQ_FIRST(&mshgrp->partitions))) {
|
|
162
|
+
rd_kafka_mock_sgrp_record_state_t *state;
|
|
163
|
+
TAILQ_REMOVE(&mshgrp->partitions, pmeta, link);
|
|
164
|
+
while ((state = TAILQ_FIRST(&pmeta->inflight))) {
|
|
165
|
+
TAILQ_REMOVE(&pmeta->inflight, state, link);
|
|
166
|
+
rd_free(state->owner_member_id);
|
|
167
|
+
rd_free(state);
|
|
168
|
+
}
|
|
169
|
+
rd_free(pmeta);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* Destroy ShareFetch sessions */
|
|
173
|
+
while ((session = TAILQ_FIRST(&mshgrp->fetch_sessions))) {
|
|
174
|
+
TAILQ_REMOVE(&mshgrp->fetch_sessions, session, link);
|
|
175
|
+
mshgrp->fetch_session_cnt--;
|
|
176
|
+
rd_kafka_mock_sgrp_fetch_session_destroy(session);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
rd_free(mshgrp->id);
|
|
180
|
+
rd_free(mshgrp);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @brief Find a share group member by MemberId.
|
|
185
|
+
*/
|
|
186
|
+
rd_kafka_mock_sharegroup_member_t *
|
|
187
|
+
rd_kafka_mock_sharegroup_member_find(rd_kafka_mock_sharegroup_t *mshgrp,
|
|
188
|
+
const rd_kafkap_str_t *MemberId) {
|
|
189
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
190
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
191
|
+
if (!rd_kafkap_str_cmp_str(MemberId, member->id))
|
|
192
|
+
return member;
|
|
193
|
+
}
|
|
194
|
+
return NULL;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @brief Destroy a share group member.
|
|
199
|
+
*/
|
|
200
|
+
void rd_kafka_mock_sharegroup_member_destroy(
|
|
201
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
202
|
+
rd_kafka_mock_sharegroup_member_t *member) {
|
|
203
|
+
rd_assert(mshgrp->member_cnt > 0);
|
|
204
|
+
TAILQ_REMOVE(&mshgrp->members, member, link);
|
|
205
|
+
mshgrp->member_cnt--;
|
|
206
|
+
rd_free(member->id);
|
|
207
|
+
|
|
208
|
+
RD_IF_FREE(member->subscribed_topic_names, rd_list_destroy_free);
|
|
209
|
+
RD_IF_FREE(member->assignment, rd_kafka_topic_partition_list_destroy);
|
|
210
|
+
rd_free(member);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @brief Mark member as active.
|
|
215
|
+
*/
|
|
216
|
+
void rd_kafka_mock_sharegroup_member_active(
|
|
217
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
218
|
+
rd_kafka_mock_sharegroup_member_t *member) {
|
|
219
|
+
rd_kafka_dbg(mshgrp->cluster->rk, MOCK, "MOCK",
|
|
220
|
+
"Marking mock share group member %s as active",
|
|
221
|
+
member->id);
|
|
222
|
+
member->ts_last_activity = rd_clock();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @brief Fence a member.
|
|
227
|
+
*/
|
|
228
|
+
void rd_kafka_mock_sharegroup_member_fenced(
|
|
229
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
230
|
+
rd_kafka_mock_sharegroup_member_t *member) {
|
|
231
|
+
rd_kafka_dbg(mshgrp->cluster->rk, MOCK, "MOCK",
|
|
232
|
+
"Member %s is fenced from sharegroup %s", member->id,
|
|
233
|
+
mshgrp->id);
|
|
234
|
+
|
|
235
|
+
rd_kafka_mock_sharegroup_member_destroy(mshgrp, member);
|
|
236
|
+
|
|
237
|
+
/* Recalculate assignments so remaining members get the
|
|
238
|
+
* freed partitions. */
|
|
239
|
+
rd_kafka_mock_sharegroup_assignment_recalculate(mshgrp);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @brief Check all members for inactivity and remove them if timed out.
|
|
244
|
+
*/
|
|
245
|
+
static void rd_kafka_mock_sharegroup_session_tmr_cb(rd_kafka_timers_t *rkts,
|
|
246
|
+
void *arg) {
|
|
247
|
+
rd_kafka_mock_sharegroup_t *mshgrp = arg;
|
|
248
|
+
rd_kafka_mock_sharegroup_member_t *member, *tmp;
|
|
249
|
+
rd_ts_t now = rd_clock();
|
|
250
|
+
rd_kafka_mock_cluster_t *mcluster = mshgrp->cluster;
|
|
251
|
+
|
|
252
|
+
mtx_lock(&mcluster->lock);
|
|
253
|
+
TAILQ_FOREACH_SAFE(member, &mshgrp->members, link, tmp) {
|
|
254
|
+
if (member->ts_last_activity +
|
|
255
|
+
(mshgrp->session_timeout_ms * 1000) >
|
|
256
|
+
now)
|
|
257
|
+
continue;
|
|
258
|
+
|
|
259
|
+
rd_kafka_dbg(mcluster->rk, MOCK, "MOCK",
|
|
260
|
+
"Member %s session timed out for sharegroup %s",
|
|
261
|
+
member->id, mshgrp->id);
|
|
262
|
+
|
|
263
|
+
rd_kafka_mock_sharegroup_member_fenced(mshgrp, member);
|
|
264
|
+
}
|
|
265
|
+
mtx_unlock(&mcluster->lock);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @brief Get or create a share group member.
|
|
270
|
+
*/
|
|
271
|
+
rd_kafka_mock_sharegroup_member_t *
|
|
272
|
+
rd_kafka_mock_sharegroup_member_get(rd_kafka_mock_sharegroup_t *mshgrp,
|
|
273
|
+
const rd_kafkap_str_t *MemberID,
|
|
274
|
+
int32_t MemberEpoch,
|
|
275
|
+
rd_kafka_mock_connection_t *mconn) {
|
|
276
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
277
|
+
|
|
278
|
+
/* Check if the member already exists */
|
|
279
|
+
member = rd_kafka_mock_sharegroup_member_find(mshgrp, MemberID);
|
|
280
|
+
if (member) {
|
|
281
|
+
member->conn = mconn;
|
|
282
|
+
rd_kafka_mock_sharegroup_member_active(mshgrp, member);
|
|
283
|
+
return member;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Only create if epoch is 0 */
|
|
287
|
+
if (MemberEpoch != 0)
|
|
288
|
+
return NULL;
|
|
289
|
+
|
|
290
|
+
/* Create new member */
|
|
291
|
+
member = rd_calloc(1, sizeof(*member));
|
|
292
|
+
member->mshgrp = mshgrp;
|
|
293
|
+
member->id = RD_KAFKAP_STR_DUP(MemberID);
|
|
294
|
+
member->member_epoch = mshgrp->group_epoch;
|
|
295
|
+
member->previous_member_epoch =
|
|
296
|
+
-1; /* No previous epoch for new members */
|
|
297
|
+
member->conn = mconn;
|
|
298
|
+
|
|
299
|
+
TAILQ_INSERT_TAIL(&mshgrp->members, member, link);
|
|
300
|
+
mshgrp->member_cnt++;
|
|
301
|
+
rd_kafka_mock_sharegroup_member_active(mshgrp, member);
|
|
302
|
+
|
|
303
|
+
return member;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @brief Update share group member's subscribed topic names.
|
|
308
|
+
*
|
|
309
|
+
* @param member The member to update.
|
|
310
|
+
* @param SubscribedTopicNames Array of topic names.
|
|
311
|
+
* @param SubscribedTopicNamesCnt Count of topic names:
|
|
312
|
+
* -1 = unchanged (no modification)
|
|
313
|
+
* 0 = clear all subscriptions
|
|
314
|
+
* >0 = set to provided topics
|
|
315
|
+
*
|
|
316
|
+
* @returns rd_true if subscriptions changed, rd_false otherwise.
|
|
317
|
+
*/
|
|
318
|
+
rd_bool_t rd_kafka_mock_sharegroup_member_subscribed_topic_names_set(
|
|
319
|
+
rd_kafka_mock_sharegroup_member_t *member,
|
|
320
|
+
const rd_kafkap_str_t *SubscribedTopicNames,
|
|
321
|
+
int32_t SubscribedTopicNamesCnt) {
|
|
322
|
+
int32_t i;
|
|
323
|
+
|
|
324
|
+
if (SubscribedTopicNamesCnt < 0) {
|
|
325
|
+
/* -1 means unchanged */
|
|
326
|
+
return rd_false;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (SubscribedTopicNamesCnt == 0) {
|
|
330
|
+
/* 0 means clear all subscriptions */
|
|
331
|
+
if (!member->subscribed_topic_names ||
|
|
332
|
+
rd_list_cnt(member->subscribed_topic_names) == 0) {
|
|
333
|
+
/* Already empty, no change */
|
|
334
|
+
return rd_false;
|
|
335
|
+
}
|
|
336
|
+
rd_list_destroy(member->subscribed_topic_names);
|
|
337
|
+
member->subscribed_topic_names = NULL;
|
|
338
|
+
return rd_true;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* SubscribedTopicNamesCnt > 0: Check if subscription changed */
|
|
342
|
+
if (member->subscribed_topic_names) {
|
|
343
|
+
if (rd_list_cnt(member->subscribed_topic_names) ==
|
|
344
|
+
SubscribedTopicNamesCnt) {
|
|
345
|
+
rd_bool_t same = rd_true;
|
|
346
|
+
char *topic;
|
|
347
|
+
int j;
|
|
348
|
+
|
|
349
|
+
RD_LIST_FOREACH(topic, member->subscribed_topic_names,
|
|
350
|
+
j) {
|
|
351
|
+
rd_bool_t found = rd_false;
|
|
352
|
+
for (i = 0; i < SubscribedTopicNamesCnt; i++) {
|
|
353
|
+
if (!rd_kafkap_str_cmp_str(
|
|
354
|
+
&SubscribedTopicNames[i],
|
|
355
|
+
topic)) {
|
|
356
|
+
found = rd_true;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (!found) {
|
|
361
|
+
same = rd_false;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (same)
|
|
366
|
+
return rd_false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* Subscription changed, update the list */
|
|
371
|
+
RD_IF_FREE(member->subscribed_topic_names, rd_list_destroy);
|
|
372
|
+
member->subscribed_topic_names =
|
|
373
|
+
rd_list_new(SubscribedTopicNamesCnt, rd_free);
|
|
374
|
+
|
|
375
|
+
for (i = 0; i < SubscribedTopicNamesCnt; i++) {
|
|
376
|
+
rd_list_add(member->subscribed_topic_names,
|
|
377
|
+
RD_KAFKAP_STR_DUP(&SubscribedTopicNames[i]));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return rd_true;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @brief Collect all subscribed topic names from all members.
|
|
385
|
+
*/
|
|
386
|
+
static rd_list_t *rd_kafka_mock_sharegroup_collect_subscribed_topics(
|
|
387
|
+
rd_kafka_mock_sharegroup_t *mshgrp) {
|
|
388
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
389
|
+
rd_list_t *all_topics;
|
|
390
|
+
|
|
391
|
+
all_topics = rd_list_new(32, rd_free);
|
|
392
|
+
|
|
393
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
394
|
+
const char *topic;
|
|
395
|
+
int i;
|
|
396
|
+
|
|
397
|
+
if (!member->subscribed_topic_names)
|
|
398
|
+
continue;
|
|
399
|
+
|
|
400
|
+
RD_LIST_FOREACH(topic, member->subscribed_topic_names, i) {
|
|
401
|
+
const char *existing;
|
|
402
|
+
int j;
|
|
403
|
+
rd_bool_t found = rd_false;
|
|
404
|
+
|
|
405
|
+
/* Check if topic already in all_topics */
|
|
406
|
+
RD_LIST_FOREACH(existing, all_topics, j) {
|
|
407
|
+
if (!strcmp(topic, existing)) {
|
|
408
|
+
found = rd_true;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* Add if not found */
|
|
414
|
+
if (!found) {
|
|
415
|
+
rd_list_add(all_topics, rd_strdup(topic));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return all_topics;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @brief Get list of member ID's subscribed to a topic.
|
|
425
|
+
*/
|
|
426
|
+
rd_list_t *rd_kafka_mock_sharegroup_get_members_for_topic(
|
|
427
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
428
|
+
char *topic_name) {
|
|
429
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
430
|
+
rd_list_t *subscribed_members;
|
|
431
|
+
int member_idx = 0;
|
|
432
|
+
|
|
433
|
+
subscribed_members = rd_list_new(mshgrp->member_cnt, rd_free);
|
|
434
|
+
|
|
435
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
436
|
+
char *topic;
|
|
437
|
+
int i;
|
|
438
|
+
|
|
439
|
+
if (member->subscribed_topic_names) {
|
|
440
|
+
RD_LIST_FOREACH(topic, member->subscribed_topic_names,
|
|
441
|
+
i) {
|
|
442
|
+
if (!strcmp(topic, topic_name)) {
|
|
443
|
+
int *idx = rd_malloc(sizeof(*idx));
|
|
444
|
+
*idx = member_idx;
|
|
445
|
+
rd_list_add(subscribed_members, idx);
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
member_idx++;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return subscribed_members;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* @brief Assign partitions of a single topic to subscribed members.
|
|
458
|
+
*/
|
|
459
|
+
void rd_kafka_mock_sharegroup_assign_topic_partitions(
|
|
460
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
461
|
+
rd_kafka_mock_topic_t *mtopic,
|
|
462
|
+
rd_list_t *subscribed_member_indices) {
|
|
463
|
+
int member_count;
|
|
464
|
+
int partition_cnt;
|
|
465
|
+
int partition_idx;
|
|
466
|
+
double precise;
|
|
467
|
+
int i;
|
|
468
|
+
|
|
469
|
+
member_count = rd_list_cnt(subscribed_member_indices);
|
|
470
|
+
partition_cnt = mtopic->partition_cnt;
|
|
471
|
+
|
|
472
|
+
if (member_count == 0 || partition_cnt == 0)
|
|
473
|
+
return;
|
|
474
|
+
|
|
475
|
+
precise = (double)partition_cnt / (double)member_count;
|
|
476
|
+
partition_idx = 0;
|
|
477
|
+
|
|
478
|
+
for (i = 0; i < member_count; i++) {
|
|
479
|
+
int *member_idx_ptr =
|
|
480
|
+
(int *)rd_list_elem(subscribed_member_indices, i);
|
|
481
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
482
|
+
int j, cnt = 0;
|
|
483
|
+
int num_partitions;
|
|
484
|
+
|
|
485
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
486
|
+
if (cnt == *member_idx_ptr)
|
|
487
|
+
break;
|
|
488
|
+
cnt++;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (!member)
|
|
492
|
+
continue;
|
|
493
|
+
|
|
494
|
+
num_partitions = (int)ceil(precise * (double)(i + 1)) -
|
|
495
|
+
(int)ceil(precise * (double)i);
|
|
496
|
+
|
|
497
|
+
if (!member->assignment)
|
|
498
|
+
member->assignment =
|
|
499
|
+
rd_kafka_topic_partition_list_new(num_partitions);
|
|
500
|
+
|
|
501
|
+
for (j = 0; j < num_partitions && partition_idx < partition_cnt;
|
|
502
|
+
j++, partition_idx++) {
|
|
503
|
+
rd_kafka_topic_partition_t *rktpar;
|
|
504
|
+
rktpar = rd_kafka_topic_partition_list_add(
|
|
505
|
+
member->assignment, mtopic->name, partition_idx);
|
|
506
|
+
/* Set topic ID so the response can include it */
|
|
507
|
+
rd_kafka_topic_partition_set_topic_id(rktpar,
|
|
508
|
+
mtopic->id);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* @brief Recalculate assignments for all members in the share group.
|
|
515
|
+
*/
|
|
516
|
+
void rd_kafka_mock_sharegroup_assignment_recalculate(
|
|
517
|
+
rd_kafka_mock_sharegroup_t *mshgrp) {
|
|
518
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
519
|
+
rd_list_t *all_topics;
|
|
520
|
+
char *topic_name;
|
|
521
|
+
int i;
|
|
522
|
+
|
|
523
|
+
if (mshgrp->member_cnt == 0)
|
|
524
|
+
return;
|
|
525
|
+
|
|
526
|
+
/* Skip automatic assignment if manual mode is enabled */
|
|
527
|
+
if (mshgrp->manual_assignment)
|
|
528
|
+
return;
|
|
529
|
+
|
|
530
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
531
|
+
if (member->assignment) {
|
|
532
|
+
rd_kafka_topic_partition_list_destroy(
|
|
533
|
+
member->assignment);
|
|
534
|
+
member->assignment = NULL;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
all_topics = rd_kafka_mock_sharegroup_collect_subscribed_topics(mshgrp);
|
|
539
|
+
|
|
540
|
+
RD_LIST_FOREACH(topic_name, all_topics, i) {
|
|
541
|
+
rd_kafka_mock_topic_t *mtopic;
|
|
542
|
+
rd_list_t *subscribed_members;
|
|
543
|
+
|
|
544
|
+
mtopic = rd_kafka_mock_topic_find(mshgrp->cluster, topic_name);
|
|
545
|
+
if (!mtopic)
|
|
546
|
+
continue;
|
|
547
|
+
|
|
548
|
+
subscribed_members =
|
|
549
|
+
rd_kafka_mock_sharegroup_get_members_for_topic(mshgrp,
|
|
550
|
+
topic_name);
|
|
551
|
+
|
|
552
|
+
rd_kafka_mock_sharegroup_assign_topic_partitions(
|
|
553
|
+
mshgrp, mtopic, subscribed_members);
|
|
554
|
+
|
|
555
|
+
rd_list_destroy(subscribed_members);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
mshgrp->group_epoch++;
|
|
559
|
+
|
|
560
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
561
|
+
/* Save the current epoch as previous before bumping.
|
|
562
|
+
* This allows the client to catch up if the response
|
|
563
|
+
* with the new epoch was lost. */
|
|
564
|
+
member->previous_member_epoch = member->member_epoch;
|
|
565
|
+
member->member_epoch = mshgrp->group_epoch;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
rd_list_destroy(all_topics);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* @brief Create a new target assignment (manual)
|
|
573
|
+
*/
|
|
574
|
+
rd_kafka_mock_sharegroup_target_assignment_t *
|
|
575
|
+
rd_kafka_mock_sharegroup_target_assignment_new(void) {
|
|
576
|
+
rd_kafka_mock_sharegroup_target_assignment_t *target_assignment;
|
|
577
|
+
target_assignment = rd_calloc(1, sizeof(*target_assignment));
|
|
578
|
+
rd_list_init(&target_assignment->member_ids, 0, rd_free);
|
|
579
|
+
rd_list_init(&target_assignment->assignment, 0,
|
|
580
|
+
(void *)rd_kafka_topic_partition_list_destroy);
|
|
581
|
+
|
|
582
|
+
return target_assignment;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* @brief Destroy target assignment
|
|
587
|
+
*/
|
|
588
|
+
void rd_kafka_mock_sharegroup_target_assignment_destroy(
|
|
589
|
+
rd_kafka_mock_sharegroup_target_assignment_t *target_assignment) {
|
|
590
|
+
rd_list_destroy(&target_assignment->member_ids);
|
|
591
|
+
rd_list_destroy(&target_assignment->assignment);
|
|
592
|
+
rd_free(target_assignment);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* @brief Set the target assignment for the sharegroup.
|
|
597
|
+
* This applies the manual assignment to the members.
|
|
598
|
+
*
|
|
599
|
+
* @locks mcluster->lock MUST be held.
|
|
600
|
+
*/
|
|
601
|
+
static void rd_kafka_mock_sharegroup_target_assignment_set(
|
|
602
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
603
|
+
rd_kafka_mock_sharegroup_target_assignment_t *target_assignment) {
|
|
604
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
605
|
+
int i;
|
|
606
|
+
|
|
607
|
+
for (i = 0; i < rd_list_cnt(&target_assignment->member_ids); i++) {
|
|
608
|
+
const char *member_id =
|
|
609
|
+
rd_list_elem(&target_assignment->member_ids, i);
|
|
610
|
+
const rd_kafka_topic_partition_list_t *partitions =
|
|
611
|
+
rd_list_elem(&target_assignment->assignment, i);
|
|
612
|
+
rd_kafkap_str_t *member_id_str;
|
|
613
|
+
|
|
614
|
+
member_id_str = rd_kafkap_str_new(member_id, -1);
|
|
615
|
+
member =
|
|
616
|
+
rd_kafka_mock_sharegroup_member_find(mshgrp, member_id_str);
|
|
617
|
+
rd_kafkap_str_destroy(member_id_str);
|
|
618
|
+
|
|
619
|
+
if (!member) {
|
|
620
|
+
rd_kafka_dbg(mshgrp->cluster->rk, MOCK, "MOCK",
|
|
621
|
+
"Cannot set target assignment for "
|
|
622
|
+
"non-existing member %s in sharegroup %s",
|
|
623
|
+
member_id, mshgrp->id);
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (member->assignment) {
|
|
628
|
+
rd_kafka_topic_partition_list_destroy(
|
|
629
|
+
member->assignment);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
member->assignment =
|
|
633
|
+
rd_kafka_topic_partition_list_copy(partitions);
|
|
634
|
+
|
|
635
|
+
/* Set topic IDs on each partition so the heartbeat response
|
|
636
|
+
* can include them (ShareGroupHeartbeat uses topic IDs) */
|
|
637
|
+
{
|
|
638
|
+
int j;
|
|
639
|
+
for (j = 0; j < member->assignment->cnt; j++) {
|
|
640
|
+
rd_kafka_topic_partition_t *rktpar =
|
|
641
|
+
&member->assignment->elems[j];
|
|
642
|
+
rd_kafkap_str_t topic_str = {
|
|
643
|
+
.str = rktpar->topic,
|
|
644
|
+
.len = strlen(rktpar->topic)};
|
|
645
|
+
rd_kafka_mock_topic_t *mtopic =
|
|
646
|
+
rd_kafka_mock_topic_find_by_kstr(
|
|
647
|
+
mshgrp->cluster, &topic_str);
|
|
648
|
+
if (mtopic) {
|
|
649
|
+
rd_kafka_topic_partition_set_topic_id(
|
|
650
|
+
rktpar, mtopic->id);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
rd_kafka_dbg(
|
|
656
|
+
mshgrp->cluster->rk, MOCK, "MOCK",
|
|
657
|
+
"Target assignment set for member %s: %d partition(s)",
|
|
658
|
+
member_id, member->assignment->cnt);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/* Bump the epochs */
|
|
662
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
663
|
+
member->previous_member_epoch = member->member_epoch;
|
|
664
|
+
member->member_epoch = ++mshgrp->group_epoch;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @brief Manual target assignment interface for sharegroups.
|
|
670
|
+
*/
|
|
671
|
+
void rd_kafka_mock_sharegroup_target_assignment(
|
|
672
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
673
|
+
const char *group_id,
|
|
674
|
+
const char **member_ids,
|
|
675
|
+
rd_kafka_topic_partition_list_t **assignment,
|
|
676
|
+
size_t member_cnt) {
|
|
677
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
678
|
+
rd_kafka_mock_sharegroup_target_assignment_t *target_assignment;
|
|
679
|
+
size_t i;
|
|
680
|
+
rd_kafkap_str_t *group_id_str;
|
|
681
|
+
|
|
682
|
+
mtx_lock(&mcluster->lock);
|
|
683
|
+
group_id_str = rd_kafkap_str_new(group_id, -1);
|
|
684
|
+
mshgrp = rd_kafka_mock_sharegroup_find(mcluster, group_id_str);
|
|
685
|
+
rd_kafkap_str_destroy(group_id_str);
|
|
686
|
+
|
|
687
|
+
if (!mshgrp) {
|
|
688
|
+
rd_kafka_log(mcluster->rk, LOG_ERR, "MOCK",
|
|
689
|
+
"Sharegroup %s not found for target assignment",
|
|
690
|
+
group_id);
|
|
691
|
+
mtx_unlock(&mcluster->lock);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
mshgrp->manual_assignment = rd_true;
|
|
696
|
+
target_assignment = rd_kafka_mock_sharegroup_target_assignment_new();
|
|
697
|
+
|
|
698
|
+
for (i = 0; i < member_cnt; i++) {
|
|
699
|
+
rd_list_add(&target_assignment->member_ids,
|
|
700
|
+
rd_strdup(member_ids[i]));
|
|
701
|
+
rd_list_add(&target_assignment->assignment,
|
|
702
|
+
rd_kafka_topic_partition_list_copy(assignment[i]));
|
|
703
|
+
}
|
|
704
|
+
rd_kafka_mock_sharegroup_target_assignment_set(mshgrp,
|
|
705
|
+
target_assignment);
|
|
706
|
+
rd_kafka_mock_sharegroup_target_assignment_destroy(target_assignment);
|
|
707
|
+
mtx_unlock(&mcluster->lock);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @brief Set the sharegroup session timeout for the sharegroup.
|
|
712
|
+
*/
|
|
713
|
+
void rd_kafka_mock_sharegroup_set_session_timeout(
|
|
714
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
715
|
+
int session_timeout_ms) {
|
|
716
|
+
mtx_lock(&mcluster->lock);
|
|
717
|
+
mcluster->defaults.sharegroup_session_timeout_ms = session_timeout_ms;
|
|
718
|
+
mtx_unlock(&mcluster->lock);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* @brief Set the sharegroup heartbeat interval for the sharegroup.
|
|
723
|
+
*/
|
|
724
|
+
void rd_kafka_mock_sharegroup_set_heartbeat_interval(
|
|
725
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
726
|
+
int heartbeat_interval_ms) {
|
|
727
|
+
mtx_lock(&mcluster->lock);
|
|
728
|
+
mcluster->defaults.sharegroup_heartbeat_interval_ms =
|
|
729
|
+
heartbeat_interval_ms;
|
|
730
|
+
mtx_unlock(&mcluster->lock);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* @brief Set the maximum delivery attempts per record for the sharegroup.
|
|
735
|
+
*/
|
|
736
|
+
void rd_kafka_mock_sharegroup_set_max_delivery_attempts(
|
|
737
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
738
|
+
int max_attempts) {
|
|
739
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
740
|
+
mtx_lock(&mcluster->lock);
|
|
741
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
742
|
+
mshgrp->max_delivery_attempts = max_attempts;
|
|
743
|
+
mcluster->defaults.sharegroup_max_delivery_attempts = max_attempts;
|
|
744
|
+
mtx_unlock(&mcluster->lock);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* @brief Set the per-record lock duration in milliseconds for the sharegroup.
|
|
749
|
+
*/
|
|
750
|
+
void rd_kafka_mock_sharegroup_set_record_lock_duration(
|
|
751
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
752
|
+
int lock_duration_ms) {
|
|
753
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
754
|
+
mtx_lock(&mcluster->lock);
|
|
755
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
756
|
+
mshgrp->record_lock_duration_ms = lock_duration_ms;
|
|
757
|
+
mcluster->defaults.sharegroup_record_lock_duration_ms =
|
|
758
|
+
lock_duration_ms;
|
|
759
|
+
mtx_unlock(&mcluster->lock);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* @brief Set the share group isolation level for transactions.
|
|
764
|
+
*/
|
|
765
|
+
void rd_kafka_mock_sharegroup_set_isolation_level(
|
|
766
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
767
|
+
int level) {
|
|
768
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
769
|
+
mtx_lock(&mcluster->lock);
|
|
770
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
771
|
+
mshgrp->isolation_level = level;
|
|
772
|
+
mcluster->defaults.sharegroup_isolation_level = level;
|
|
773
|
+
mtx_unlock(&mcluster->lock);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* @brief Set the maximum number of members allowed in a share group.
|
|
778
|
+
*/
|
|
779
|
+
void rd_kafka_mock_sharegroup_set_max_size(rd_kafka_mock_cluster_t *mcluster,
|
|
780
|
+
int max_size) {
|
|
781
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
782
|
+
mtx_lock(&mcluster->lock);
|
|
783
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
784
|
+
mshgrp->max_size = max_size;
|
|
785
|
+
mcluster->defaults.sharegroup_max_size = max_size;
|
|
786
|
+
mtx_unlock(&mcluster->lock);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* @brief Set the maximum number of fetch sessions allowed per broker.
|
|
791
|
+
*/
|
|
792
|
+
void rd_kafka_mock_sharegroup_set_max_fetch_sessions(
|
|
793
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
794
|
+
int max_fetch_sessions) {
|
|
795
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
796
|
+
mtx_lock(&mcluster->lock);
|
|
797
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
798
|
+
mshgrp->max_fetch_sessions = max_fetch_sessions;
|
|
799
|
+
mcluster->defaults.sharegroup_max_fetch_sessions = max_fetch_sessions;
|
|
800
|
+
mtx_unlock(&mcluster->lock);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* @brief Set the maximum number of in-flight record locks per
|
|
805
|
+
* share-partition.
|
|
806
|
+
*/
|
|
807
|
+
void rd_kafka_mock_sharegroup_set_max_record_locks(
|
|
808
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
809
|
+
int max_record_locks) {
|
|
810
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
811
|
+
mtx_lock(&mcluster->lock);
|
|
812
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
813
|
+
mshgrp->max_record_locks = max_record_locks;
|
|
814
|
+
mcluster->defaults.sharegroup_max_record_locks = max_record_locks;
|
|
815
|
+
mtx_unlock(&mcluster->lock);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* @brief Set the auto offset reset policy for share groups.
|
|
820
|
+
*/
|
|
821
|
+
void rd_kafka_mock_sharegroup_set_auto_offset_reset(
|
|
822
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
823
|
+
int auto_offset_reset) {
|
|
824
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
825
|
+
mtx_lock(&mcluster->lock);
|
|
826
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link)
|
|
827
|
+
mshgrp->auto_offset_reset = auto_offset_reset;
|
|
828
|
+
mcluster->defaults.sharegroup_auto_offset_reset = auto_offset_reset;
|
|
829
|
+
mtx_unlock(&mcluster->lock);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* @brief Destroy share fetch session.
|
|
834
|
+
*/
|
|
835
|
+
void rd_kafka_mock_sgrp_fetch_session_destroy(
|
|
836
|
+
rd_kafka_mock_sgrp_fetch_session_t *session) {
|
|
837
|
+
rd_free(session->member_id);
|
|
838
|
+
RD_IF_FREE(session->partitions, rd_kafka_topic_partition_list_destroy);
|
|
839
|
+
rd_free(session);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* @brief Common share-session validation for ShareFetch / ShareAcknowledge.
|
|
845
|
+
*
|
|
846
|
+
* Performs:
|
|
847
|
+
* 1. Session lookup by (MemberId, NodeId).
|
|
848
|
+
* 2. SessionEpoch == 0 : destroy old session if any (caller creates new).
|
|
849
|
+
* 3. SessionEpoch == -1 : keep session alive (FinalContext behaviour).
|
|
850
|
+
* 4. SessionEpoch > 0 : validate that session exists and epoch matches.
|
|
851
|
+
*
|
|
852
|
+
* On return, \p *sessionp is set to the looked-up session (or NULL if
|
|
853
|
+
* no session was found or it was closed).
|
|
854
|
+
*
|
|
855
|
+
* @note Does NOT handle SessionEpoch == 0 (open new session), which is
|
|
856
|
+
* ShareFetch-specific. The caller is also responsible for
|
|
857
|
+
* incrementing session_epoch and updating ts_last_activity on
|
|
858
|
+
* success.
|
|
859
|
+
*
|
|
860
|
+
* @param sgrp Share group.
|
|
861
|
+
* @param MemberId Member identifier from the request.
|
|
862
|
+
* @param NodeId Node ID of the broker handling the request.
|
|
863
|
+
* @param SessionEpoch Session epoch from the request.
|
|
864
|
+
* @param sessionp [out] Session pointer.
|
|
865
|
+
* @param api_name API name for debug messages ("ShareFetch" etc.).
|
|
866
|
+
*
|
|
867
|
+
* @returns Error code, or RD_KAFKA_RESP_ERR_NO_ERROR on success.
|
|
868
|
+
*
|
|
869
|
+
* @locks mcluster->lock MUST be held.
|
|
870
|
+
*/
|
|
871
|
+
rd_kafka_resp_err_t rd_kafka_mock_sgrp_session_validate(
|
|
872
|
+
rd_kafka_mock_sharegroup_t *sgrp,
|
|
873
|
+
const rd_kafkap_str_t *MemberId,
|
|
874
|
+
int32_t NodeId,
|
|
875
|
+
int32_t SessionEpoch,
|
|
876
|
+
rd_kafka_mock_sgrp_fetch_session_t **sessionp,
|
|
877
|
+
const char *api_name) {
|
|
878
|
+
rd_kafka_mock_sgrp_fetch_session_t *session = NULL;
|
|
879
|
+
|
|
880
|
+
*sessionp = NULL;
|
|
881
|
+
|
|
882
|
+
/* The real Kafka broker's partition leader does NOT
|
|
883
|
+
* validate group membership on ShareFetch — share sessions are
|
|
884
|
+
* managed independently of the group coordinator. */
|
|
885
|
+
|
|
886
|
+
/* 1. Look up existing session by (MemberId, NodeId).
|
|
887
|
+
* In real Kafka, ShareSessionCache is per-broker, so each
|
|
888
|
+
* broker maintains its own independent session for the same
|
|
889
|
+
* member. We emulate this by keying on both fields. */
|
|
890
|
+
TAILQ_FOREACH(session, &sgrp->fetch_sessions, link) {
|
|
891
|
+
if (!rd_kafkap_str_cmp_str(MemberId, session->member_id) &&
|
|
892
|
+
session->node_id == NodeId)
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/* 2. SessionEpoch == 0: open a new session.
|
|
897
|
+
* If an old session exists for this member (e.g. after a
|
|
898
|
+
* LEAVE→rejoin cycle), destroy it so the caller creates a
|
|
899
|
+
* fresh one. */
|
|
900
|
+
if (SessionEpoch == 0) {
|
|
901
|
+
if (session) {
|
|
902
|
+
rd_kafka_mock_sgrp_release_session_locks(sgrp, session);
|
|
903
|
+
TAILQ_REMOVE(&sgrp->fetch_sessions, session, link);
|
|
904
|
+
sgrp->fetch_session_cnt--;
|
|
905
|
+
rd_kafka_mock_sgrp_fetch_session_destroy(session);
|
|
906
|
+
session = NULL;
|
|
907
|
+
}
|
|
908
|
+
} else if (SessionEpoch == -1) {
|
|
909
|
+
/* 3. SessionEpoch == -1 (FINAL_EPOCH): return the existing
|
|
910
|
+
* session so the caller can process final acks and
|
|
911
|
+
* then close it. If no session exists, fail with
|
|
912
|
+
* SHARE_SESSION_NOT_FOUND per the protocol. */
|
|
913
|
+
if (!session) {
|
|
914
|
+
*sessionp = NULL;
|
|
915
|
+
return RD_KAFKA_RESP_ERR_SHARE_SESSION_NOT_FOUND;
|
|
916
|
+
}
|
|
917
|
+
} else if (SessionEpoch > 0) {
|
|
918
|
+
/* 4. SessionEpoch > 0: validate epoch. */
|
|
919
|
+
if (!session) {
|
|
920
|
+
/* Session not in cache →
|
|
921
|
+
* SHARE_SESSION_NOT_FOUND (distinct from epoch
|
|
922
|
+
* mismatch which uses
|
|
923
|
+
* INVALID_SHARE_SESSION_EPOCH). */
|
|
924
|
+
*sessionp = NULL;
|
|
925
|
+
return RD_KAFKA_RESP_ERR_SHARE_SESSION_NOT_FOUND;
|
|
926
|
+
} else if (SessionEpoch != session->session_epoch) {
|
|
927
|
+
/* Epoch mismatch → destroy the stale
|
|
928
|
+
* session and return INVALID_SHARE_SESSION_EPOCH.
|
|
929
|
+
* The client handles this by resetting its
|
|
930
|
+
* per-broker epoch to 0 (opening a fresh session
|
|
931
|
+
* on the next fetch). */
|
|
932
|
+
rd_kafka_mock_sgrp_release_session_locks(sgrp, session);
|
|
933
|
+
TAILQ_REMOVE(&sgrp->fetch_sessions, session, link);
|
|
934
|
+
sgrp->fetch_session_cnt--;
|
|
935
|
+
rd_kafka_mock_sgrp_fetch_session_destroy(session);
|
|
936
|
+
*sessionp = NULL;
|
|
937
|
+
return RD_KAFKA_RESP_ERR_INVALID_SHARE_SESSION_EPOCH;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
*sessionp = session;
|
|
942
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* @brief Release a single ACQUIRED record state back to AVAILABLE or ARCHIVED.
|
|
948
|
+
*
|
|
949
|
+
* If \p mshgrp has a max_delivery_attempts limit and the record's
|
|
950
|
+
* delivery_count has reached it, the record is archived instead of
|
|
951
|
+
* made available again. Clears owner_member_id and lock_expiry_ts.
|
|
952
|
+
*
|
|
953
|
+
* @locks mcluster->lock MUST be held.
|
|
954
|
+
*/
|
|
955
|
+
void rd_kafka_mock_sgrp_record_release(
|
|
956
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
957
|
+
rd_kafka_mock_sgrp_partmeta_t *pmeta,
|
|
958
|
+
rd_kafka_mock_sgrp_record_state_t *state) {
|
|
959
|
+
if (state->state == RD_KAFKA_MOCK_SGRP_RECORD_ACQUIRED)
|
|
960
|
+
pmeta->acquired_cnt--;
|
|
961
|
+
if (mshgrp->max_delivery_attempts > 0 &&
|
|
962
|
+
state->delivery_count >= mshgrp->max_delivery_attempts) {
|
|
963
|
+
state->state = RD_KAFKA_MOCK_SGRP_RECORD_ARCHIVED;
|
|
964
|
+
} else {
|
|
965
|
+
state->state = RD_KAFKA_MOCK_SGRP_RECORD_AVAILABLE;
|
|
966
|
+
}
|
|
967
|
+
rd_free(state->owner_member_id);
|
|
968
|
+
state->owner_member_id = NULL;
|
|
969
|
+
state->lock_expiry_ts = 0;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* @brief Release all ACQUIRED records owned by \p session's member on
|
|
974
|
+
* the partitions belonging to \p session.
|
|
975
|
+
*
|
|
976
|
+
* Share sessions are per-broker: closing one broker's session must
|
|
977
|
+
* only release the records acquired through that session (the
|
|
978
|
+
* partitions that broker leads), never the member's locks held
|
|
979
|
+
* through other brokers' intact sessions.
|
|
980
|
+
*
|
|
981
|
+
* This is called when a session is closed (epoch=-1), replaced
|
|
982
|
+
* (epoch=0), invalidated (epoch mismatch), times out, or its
|
|
983
|
+
* connection is closed.
|
|
984
|
+
*
|
|
985
|
+
* @locks mcluster->lock MUST be held.
|
|
986
|
+
*/
|
|
987
|
+
void rd_kafka_mock_sgrp_release_session_locks(
|
|
988
|
+
rd_kafka_mock_sharegroup_t *mshgrp,
|
|
989
|
+
const rd_kafka_mock_sgrp_fetch_session_t *session) {
|
|
990
|
+
rd_kafka_mock_sgrp_partmeta_t *pmeta;
|
|
991
|
+
|
|
992
|
+
if (!session->partitions)
|
|
993
|
+
return;
|
|
994
|
+
|
|
995
|
+
TAILQ_FOREACH(pmeta, &mshgrp->partitions, link) {
|
|
996
|
+
rd_kafka_mock_sgrp_record_state_t *state, *tmp;
|
|
997
|
+
rd_kafka_mock_topic_t *mtopic;
|
|
998
|
+
rd_kafka_mock_partition_t *mpart;
|
|
999
|
+
|
|
1000
|
+
if (rd_kafka_topic_partition_list_find_idx_by_id(
|
|
1001
|
+
session->partitions, pmeta->topic_id,
|
|
1002
|
+
pmeta->partition) < 0)
|
|
1003
|
+
continue;
|
|
1004
|
+
|
|
1005
|
+
/* A session can only release locks for partitions its
|
|
1006
|
+
* broker currently leads: a session's partition list
|
|
1007
|
+
* can be stale after a leader change, while the locks
|
|
1008
|
+
* now belong to the new leader's session. */
|
|
1009
|
+
mtopic = rd_kafka_mock_topic_find_by_id(mshgrp->cluster,
|
|
1010
|
+
pmeta->topic_id);
|
|
1011
|
+
mpart = mtopic ? rd_kafka_mock_partition_find(mtopic,
|
|
1012
|
+
pmeta->partition)
|
|
1013
|
+
: NULL;
|
|
1014
|
+
if (!mpart || !mpart->leader ||
|
|
1015
|
+
mpart->leader->id != session->node_id)
|
|
1016
|
+
continue;
|
|
1017
|
+
|
|
1018
|
+
TAILQ_FOREACH_SAFE(state, &pmeta->inflight, link, tmp) {
|
|
1019
|
+
if (state->state != RD_KAFKA_MOCK_SGRP_RECORD_ACQUIRED)
|
|
1020
|
+
continue;
|
|
1021
|
+
if (!state->owner_member_id)
|
|
1022
|
+
continue;
|
|
1023
|
+
if (strcmp(state->owner_member_id,
|
|
1024
|
+
session->member_id) != 0)
|
|
1025
|
+
continue;
|
|
1026
|
+
|
|
1027
|
+
rd_kafka_mock_sgrp_record_release(mshgrp, pmeta, state);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* @brief Proactively release any expired acquisition locks.
|
|
1034
|
+
*
|
|
1035
|
+
* Iterates all partition metadata in the share group and flips
|
|
1036
|
+
* ACQUIRED records whose lock_expiry_ts has passed back to AVAILABLE.
|
|
1037
|
+
*
|
|
1038
|
+
* @locks mcluster->lock MUST be held.
|
|
1039
|
+
*/
|
|
1040
|
+
static void rd_kafka_mock_sgrp_expire_locks(rd_kafka_mock_sharegroup_t *mshgrp,
|
|
1041
|
+
rd_ts_t now) {
|
|
1042
|
+
rd_kafka_mock_sgrp_partmeta_t *pmeta;
|
|
1043
|
+
|
|
1044
|
+
TAILQ_FOREACH(pmeta, &mshgrp->partitions, link) {
|
|
1045
|
+
rd_kafka_mock_sgrp_record_state_t *state, *tmp;
|
|
1046
|
+
TAILQ_FOREACH_SAFE(state, &pmeta->inflight, link, tmp) {
|
|
1047
|
+
if (state->state != RD_KAFKA_MOCK_SGRP_RECORD_ACQUIRED)
|
|
1048
|
+
continue;
|
|
1049
|
+
if (!state->lock_expiry_ts ||
|
|
1050
|
+
state->lock_expiry_ts > now)
|
|
1051
|
+
continue;
|
|
1052
|
+
|
|
1053
|
+
/* Lock has expired. If delivery
|
|
1054
|
+
* count has reached the limit, archive the
|
|
1055
|
+
* record instead of making it available. */
|
|
1056
|
+
rd_kafka_mock_sgrp_record_release(mshgrp, pmeta, state);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* @brief Periodic timer: expire stale share-fetch sessions and
|
|
1063
|
+
* proactively reclaim expired acquisition locks.
|
|
1064
|
+
*
|
|
1065
|
+
* @locks mcluster->lock is acquired and released.
|
|
1066
|
+
*/
|
|
1067
|
+
void rd_kafka_mock_sgrp_fetch_session_tmr_cb(rd_kafka_timers_t *rkts,
|
|
1068
|
+
void *arg) {
|
|
1069
|
+
rd_kafka_mock_sharegroup_t *mshgrp = arg;
|
|
1070
|
+
rd_kafka_mock_sgrp_fetch_session_t *session, *tmp;
|
|
1071
|
+
rd_ts_t now = rd_clock();
|
|
1072
|
+
rd_kafka_mock_cluster_t *mcluster = mshgrp->cluster;
|
|
1073
|
+
|
|
1074
|
+
(void)rkts;
|
|
1075
|
+
|
|
1076
|
+
mtx_lock(&mcluster->lock);
|
|
1077
|
+
|
|
1078
|
+
/* 1. Expire stale sessions and release their member locks. */
|
|
1079
|
+
TAILQ_FOREACH_SAFE(session, &mshgrp->fetch_sessions, link, tmp) {
|
|
1080
|
+
if (session->ts_last_activity +
|
|
1081
|
+
(mshgrp->session_timeout_ms * 1000) >
|
|
1082
|
+
now)
|
|
1083
|
+
continue;
|
|
1084
|
+
|
|
1085
|
+
/* Release all locks held by this member before
|
|
1086
|
+
* destroying the session. */
|
|
1087
|
+
rd_kafka_mock_sgrp_release_session_locks(mshgrp, session);
|
|
1088
|
+
|
|
1089
|
+
TAILQ_REMOVE(&mshgrp->fetch_sessions, session, link);
|
|
1090
|
+
mshgrp->fetch_session_cnt--;
|
|
1091
|
+
rd_kafka_mock_sgrp_fetch_session_destroy(session);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
/* 2. Proactively reclaim any expired acquisition locks.
|
|
1095
|
+
* This catches records whose owning consumer crashed
|
|
1096
|
+
* without closing its session cleanly. */
|
|
1097
|
+
rd_kafka_mock_sgrp_expire_locks(mshgrp, now);
|
|
1098
|
+
|
|
1099
|
+
mtx_unlock(&mcluster->lock);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* @brief A client connection closed, check if any sharegroup has any
|
|
1104
|
+
* state for this connection that needs to be cleared.
|
|
1105
|
+
*
|
|
1106
|
+
* @param mcluster Cluster to search in.
|
|
1107
|
+
* @param mconn Connection that was closed.
|
|
1108
|
+
*
|
|
1109
|
+
* @locks mcluster->lock MUST be held.
|
|
1110
|
+
*/
|
|
1111
|
+
void rd_kafka_mock_sharegrps_connection_closed(
|
|
1112
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
1113
|
+
rd_kafka_mock_connection_t *mconn) {
|
|
1114
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
1115
|
+
|
|
1116
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link) {
|
|
1117
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
1118
|
+
/* Clear heartbeat connection for any member on this conn. */
|
|
1119
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
1120
|
+
if (member->conn == mconn)
|
|
1121
|
+
member->conn = NULL;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* @brief Close all share fetch sessions on \p node_id.
|
|
1128
|
+
*
|
|
1129
|
+
* Called from rd_kafka_mock_connection_close() where mconn->broker is
|
|
1130
|
+
* guaranteed to be valid. Must NOT be called with a fake connection pointer.
|
|
1131
|
+
*
|
|
1132
|
+
* @locks mcluster->lock MUST be held.
|
|
1133
|
+
*/
|
|
1134
|
+
void rd_kafka_mock_sharegrps_node_connection_closed(
|
|
1135
|
+
rd_kafka_mock_cluster_t *mcluster,
|
|
1136
|
+
int32_t node_id) {
|
|
1137
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
1138
|
+
|
|
1139
|
+
TAILQ_FOREACH(mshgrp, &mcluster->sharegrps, link) {
|
|
1140
|
+
rd_kafka_mock_sgrp_fetch_session_t *session, *tmp;
|
|
1141
|
+
/* When a connection is disconnected, any share session
|
|
1142
|
+
* on that broker is automatically closed. */
|
|
1143
|
+
TAILQ_FOREACH_SAFE(session, &mshgrp->fetch_sessions, link,
|
|
1144
|
+
tmp) {
|
|
1145
|
+
if (session->node_id != node_id)
|
|
1146
|
+
continue;
|
|
1147
|
+
rd_kafka_mock_sgrp_release_session_locks(mshgrp,
|
|
1148
|
+
session);
|
|
1149
|
+
TAILQ_REMOVE(&mshgrp->fetch_sessions, session, link);
|
|
1150
|
+
mshgrp->fetch_session_cnt--;
|
|
1151
|
+
rd_kafka_mock_sgrp_fetch_session_destroy(session);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* @brief Retrieve the member IDs from a sharegroup.
|
|
1158
|
+
*
|
|
1159
|
+
* @param mcluster Mock cluster instance.
|
|
1160
|
+
* @param group_id The sharegroup ID.
|
|
1161
|
+
* @param member_ids_out Output array of member IDs (caller must free each
|
|
1162
|
+
* string and the array itself).
|
|
1163
|
+
* @param member_cnt_out Output count of members.
|
|
1164
|
+
*
|
|
1165
|
+
* @returns RD_KAFKA_RESP_ERR_NO_ERROR on success,
|
|
1166
|
+
* RD_KAFKA_RESP_ERR_GROUP_ID_NOT_FOUND if sharegroup not found.
|
|
1167
|
+
*/
|
|
1168
|
+
rd_kafka_resp_err_t
|
|
1169
|
+
rd_kafka_mock_sharegroup_get_member_ids(rd_kafka_mock_cluster_t *mcluster,
|
|
1170
|
+
const char *group_id,
|
|
1171
|
+
char ***member_ids_out,
|
|
1172
|
+
size_t *member_cnt_out) {
|
|
1173
|
+
rd_kafka_mock_sharegroup_t *mshgrp;
|
|
1174
|
+
rd_kafka_mock_sharegroup_member_t *member;
|
|
1175
|
+
rd_kafkap_str_t *group_id_str;
|
|
1176
|
+
char **member_ids;
|
|
1177
|
+
size_t i;
|
|
1178
|
+
|
|
1179
|
+
mtx_lock(&mcluster->lock);
|
|
1180
|
+
group_id_str = rd_kafkap_str_new(group_id, -1);
|
|
1181
|
+
mshgrp = rd_kafka_mock_sharegroup_find(mcluster, group_id_str);
|
|
1182
|
+
rd_kafkap_str_destroy(group_id_str);
|
|
1183
|
+
|
|
1184
|
+
if (!mshgrp) {
|
|
1185
|
+
mtx_unlock(&mcluster->lock);
|
|
1186
|
+
*member_ids_out = NULL;
|
|
1187
|
+
*member_cnt_out = 0;
|
|
1188
|
+
return RD_KAFKA_RESP_ERR_GROUP_ID_NOT_FOUND;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
*member_cnt_out = mshgrp->member_cnt;
|
|
1192
|
+
if (mshgrp->member_cnt == 0) {
|
|
1193
|
+
mtx_unlock(&mcluster->lock);
|
|
1194
|
+
*member_ids_out = NULL;
|
|
1195
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
member_ids = rd_malloc(sizeof(*member_ids) * mshgrp->member_cnt);
|
|
1199
|
+
i = 0;
|
|
1200
|
+
TAILQ_FOREACH(member, &mshgrp->members, link) {
|
|
1201
|
+
member_ids[i++] = rd_strdup(member->id);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
mtx_unlock(&mcluster->lock);
|
|
1205
|
+
*member_ids_out = member_ids;
|
|
1206
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1207
|
+
}
|