@point3/node-rdkafka 3.6.0-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/LICENSE.txt +20 -0
- package/README.md +636 -0
- package/binding.gyp +154 -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 +33 -0
- package/deps/librdkafka/.gdbmacros +19 -0
- package/deps/librdkafka/.github/CODEOWNERS +1 -0
- package/deps/librdkafka/.github/ISSUE_TEMPLATE +34 -0
- package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
- package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
- package/deps/librdkafka/.semaphore/semaphore.yml +378 -0
- package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
- package/deps/librdkafka/CHANGELOG.md +2208 -0
- package/deps/librdkafka/CMakeLists.txt +291 -0
- package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
- package/deps/librdkafka/CONFIGURATION.md +209 -0
- package/deps/librdkafka/CONTRIBUTING.md +431 -0
- package/deps/librdkafka/Doxyfile +2375 -0
- package/deps/librdkafka/INTRODUCTION.md +2481 -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 +199 -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 +331 -0
- package/deps/librdkafka/debian/changelog +111 -0
- package/deps/librdkafka/debian/compat +1 -0
- package/deps/librdkafka/debian/control +71 -0
- package/deps/librdkafka/debian/copyright +99 -0
- package/deps/librdkafka/debian/gbp.conf +9 -0
- package/deps/librdkafka/debian/librdkafka++1.install +1 -0
- package/deps/librdkafka/debian/librdkafka-dev.examples +2 -0
- package/deps/librdkafka/debian/librdkafka-dev.install +9 -0
- package/deps/librdkafka/debian/librdkafka1.docs +5 -0
- package/deps/librdkafka/debian/librdkafka1.install +1 -0
- package/deps/librdkafka/debian/librdkafka1.symbols +135 -0
- package/deps/librdkafka/debian/rules +19 -0
- package/deps/librdkafka/debian/source/format +1 -0
- package/deps/librdkafka/debian/watch +2 -0
- package/deps/librdkafka/dev-conf.sh +123 -0
- package/deps/librdkafka/examples/CMakeLists.txt +79 -0
- package/deps/librdkafka/examples/Makefile +167 -0
- package/deps/librdkafka/examples/README.md +42 -0
- package/deps/librdkafka/examples/alter_consumer_group_offsets.c +338 -0
- package/deps/librdkafka/examples/consumer.c +271 -0
- package/deps/librdkafka/examples/delete_records.c +233 -0
- package/deps/librdkafka/examples/describe_cluster.c +322 -0
- package/deps/librdkafka/examples/describe_consumer_groups.c +455 -0
- package/deps/librdkafka/examples/describe_topics.c +427 -0
- package/deps/librdkafka/examples/elect_leaders.c +317 -0
- package/deps/librdkafka/examples/globals.json +11 -0
- package/deps/librdkafka/examples/idempotent_producer.c +344 -0
- package/deps/librdkafka/examples/incremental_alter_configs.c +347 -0
- package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +945 -0
- package/deps/librdkafka/examples/list_consumer_group_offsets.c +359 -0
- package/deps/librdkafka/examples/list_consumer_groups.c +365 -0
- package/deps/librdkafka/examples/list_offsets.c +327 -0
- package/deps/librdkafka/examples/misc.c +287 -0
- package/deps/librdkafka/examples/openssl_engine_example.cpp +248 -0
- package/deps/librdkafka/examples/producer.c +251 -0
- package/deps/librdkafka/examples/producer.cpp +228 -0
- package/deps/librdkafka/examples/rdkafka_complex_consumer_example.c +617 -0
- package/deps/librdkafka/examples/rdkafka_complex_consumer_example.cpp +467 -0
- package/deps/librdkafka/examples/rdkafka_consume_batch.cpp +264 -0
- package/deps/librdkafka/examples/rdkafka_example.c +853 -0
- package/deps/librdkafka/examples/rdkafka_example.cpp +679 -0
- package/deps/librdkafka/examples/rdkafka_performance.c +1781 -0
- package/deps/librdkafka/examples/transactions-older-broker.c +668 -0
- package/deps/librdkafka/examples/transactions.c +665 -0
- package/deps/librdkafka/examples/user_scram.c +491 -0
- package/deps/librdkafka/examples/win_ssl_cert_store.cpp +396 -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/packaging/RELEASE.md +319 -0
- package/deps/librdkafka/packaging/alpine/build-alpine.sh +38 -0
- package/deps/librdkafka/packaging/archlinux/PKGBUILD +30 -0
- package/deps/librdkafka/packaging/cmake/Config.cmake.in +37 -0
- package/deps/librdkafka/packaging/cmake/Modules/FindLZ4.cmake +38 -0
- package/deps/librdkafka/packaging/cmake/Modules/FindZSTD.cmake +27 -0
- package/deps/librdkafka/packaging/cmake/Modules/LICENSE.FindZstd +178 -0
- package/deps/librdkafka/packaging/cmake/README.md +38 -0
- package/deps/librdkafka/packaging/cmake/config.h.in +52 -0
- package/deps/librdkafka/packaging/cmake/parseversion.cmake +60 -0
- package/deps/librdkafka/packaging/cmake/rdkafka.pc.in +12 -0
- package/deps/librdkafka/packaging/cmake/try_compile/atomic_32_test.c +8 -0
- package/deps/librdkafka/packaging/cmake/try_compile/atomic_64_test.c +8 -0
- package/deps/librdkafka/packaging/cmake/try_compile/c11threads_test.c +14 -0
- package/deps/librdkafka/packaging/cmake/try_compile/crc32c_hw_test.c +27 -0
- package/deps/librdkafka/packaging/cmake/try_compile/dlopen_test.c +11 -0
- package/deps/librdkafka/packaging/cmake/try_compile/libsasl2_test.c +7 -0
- package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_darwin_test.c +6 -0
- package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_freebsd_test.c +7 -0
- package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_gnu_test.c +5 -0
- package/deps/librdkafka/packaging/cmake/try_compile/rand_r_test.c +7 -0
- package/deps/librdkafka/packaging/cmake/try_compile/rdkafka_setup.cmake +122 -0
- package/deps/librdkafka/packaging/cmake/try_compile/regex_test.c +10 -0
- package/deps/librdkafka/packaging/cmake/try_compile/strndup_test.c +5 -0
- package/deps/librdkafka/packaging/cmake/try_compile/sync_32_test.c +8 -0
- package/deps/librdkafka/packaging/cmake/try_compile/sync_64_test.c +8 -0
- package/deps/librdkafka/packaging/cp/README.md +16 -0
- package/deps/librdkafka/packaging/cp/check_features.c +72 -0
- package/deps/librdkafka/packaging/cp/verify-deb.sh +33 -0
- package/deps/librdkafka/packaging/cp/verify-packages.sh +69 -0
- package/deps/librdkafka/packaging/cp/verify-rpm.sh +32 -0
- package/deps/librdkafka/packaging/debian/changelog +66 -0
- package/deps/librdkafka/packaging/debian/compat +1 -0
- package/deps/librdkafka/packaging/debian/control +49 -0
- package/deps/librdkafka/packaging/debian/copyright +84 -0
- package/deps/librdkafka/packaging/debian/docs +5 -0
- package/deps/librdkafka/packaging/debian/gbp.conf +9 -0
- package/deps/librdkafka/packaging/debian/librdkafka-dev.dirs +2 -0
- package/deps/librdkafka/packaging/debian/librdkafka-dev.examples +2 -0
- package/deps/librdkafka/packaging/debian/librdkafka-dev.install +6 -0
- package/deps/librdkafka/packaging/debian/librdkafka-dev.substvars +1 -0
- package/deps/librdkafka/packaging/debian/librdkafka.dsc +16 -0
- package/deps/librdkafka/packaging/debian/librdkafka1-dbg.substvars +1 -0
- package/deps/librdkafka/packaging/debian/librdkafka1.dirs +1 -0
- package/deps/librdkafka/packaging/debian/librdkafka1.install +2 -0
- package/deps/librdkafka/packaging/debian/librdkafka1.postinst.debhelper +5 -0
- package/deps/librdkafka/packaging/debian/librdkafka1.postrm.debhelper +5 -0
- package/deps/librdkafka/packaging/debian/librdkafka1.symbols +64 -0
- package/deps/librdkafka/packaging/debian/rules +19 -0
- package/deps/librdkafka/packaging/debian/source/format +1 -0
- package/deps/librdkafka/packaging/debian/watch +2 -0
- package/deps/librdkafka/packaging/get_version.py +21 -0
- package/deps/librdkafka/packaging/homebrew/README.md +15 -0
- package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +31 -0
- package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw-static.sh +52 -0
- package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw.sh +21 -0
- package/deps/librdkafka/packaging/mingw-w64/export-variables.sh +13 -0
- package/deps/librdkafka/packaging/mingw-w64/run-tests.sh +6 -0
- package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +38 -0
- package/deps/librdkafka/packaging/nuget/README.md +84 -0
- package/deps/librdkafka/packaging/nuget/artifact.py +177 -0
- package/deps/librdkafka/packaging/nuget/cleanup-s3.py +143 -0
- package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr120.zip +0 -0
- package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr140.zip +0 -0
- package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr120.zip +0 -0
- package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr140.zip +0 -0
- package/deps/librdkafka/packaging/nuget/nuget.sh +21 -0
- package/deps/librdkafka/packaging/nuget/nugetpackage.py +278 -0
- package/deps/librdkafka/packaging/nuget/packaging.py +448 -0
- package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +21 -0
- package/deps/librdkafka/packaging/nuget/release.py +167 -0
- package/deps/librdkafka/packaging/nuget/requirements.txt +3 -0
- package/deps/librdkafka/packaging/nuget/staticpackage.py +178 -0
- package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.nuspec +21 -0
- package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.props +18 -0
- package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.targets +19 -0
- package/deps/librdkafka/packaging/nuget/zfile/__init__.py +0 -0
- package/deps/librdkafka/packaging/nuget/zfile/zfile.py +98 -0
- package/deps/librdkafka/packaging/rpm/Makefile +92 -0
- package/deps/librdkafka/packaging/rpm/README.md +23 -0
- package/deps/librdkafka/packaging/rpm/el7-x86_64.cfg +40 -0
- package/deps/librdkafka/packaging/rpm/librdkafka.spec +118 -0
- package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +96 -0
- package/deps/librdkafka/packaging/rpm/tests/Makefile +25 -0
- package/deps/librdkafka/packaging/rpm/tests/README.md +8 -0
- package/deps/librdkafka/packaging/rpm/tests/run-test.sh +42 -0
- package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +56 -0
- package/deps/librdkafka/packaging/rpm/tests/test.c +77 -0
- package/deps/librdkafka/packaging/rpm/tests/test.cpp +34 -0
- package/deps/librdkafka/packaging/tools/Dockerfile +31 -0
- package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +12 -0
- package/deps/librdkafka/packaging/tools/build-deb-package.sh +64 -0
- package/deps/librdkafka/packaging/tools/build-debian.sh +65 -0
- package/deps/librdkafka/packaging/tools/build-manylinux.sh +68 -0
- package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +139 -0
- package/deps/librdkafka/packaging/tools/distro-build.sh +38 -0
- package/deps/librdkafka/packaging/tools/gh-release-checksums.py +39 -0
- package/deps/librdkafka/packaging/tools/rdutcoverage.sh +25 -0
- package/deps/librdkafka/packaging/tools/requirements.txt +2 -0
- package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
- package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
- package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
- package/deps/librdkafka/packaging/tools/style-format.sh +149 -0
- package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
- package/deps/librdkafka/service.yml +172 -0
- package/deps/librdkafka/src/CMakeLists.txt +374 -0
- package/deps/librdkafka/src/Makefile +103 -0
- package/deps/librdkafka/src/README.lz4.md +30 -0
- package/deps/librdkafka/src/cJSON.c +2834 -0
- package/deps/librdkafka/src/cJSON.h +398 -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 +584 -0
- package/deps/librdkafka/src/rdaddr.c +255 -0
- package/deps/librdkafka/src/rdaddr.h +202 -0
- package/deps/librdkafka/src/rdatomic.h +230 -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 +830 -0
- package/deps/librdkafka/src/rdhttp.h +101 -0
- package/deps/librdkafka/src/rdinterval.h +177 -0
- package/deps/librdkafka/src/rdkafka.c +5505 -0
- package/deps/librdkafka/src/rdkafka.h +10686 -0
- package/deps/librdkafka/src/rdkafka_admin.c +9794 -0
- package/deps/librdkafka/src/rdkafka_admin.h +661 -0
- package/deps/librdkafka/src/rdkafka_assignment.c +1010 -0
- package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
- package/deps/librdkafka/src/rdkafka_assignor.c +1786 -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 +221 -0
- package/deps/librdkafka/src/rdkafka_broker.c +6337 -0
- package/deps/librdkafka/src/rdkafka_broker.h +744 -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 +7587 -0
- package/deps/librdkafka/src/rdkafka_cgrp.h +477 -0
- package/deps/librdkafka/src/rdkafka_conf.c +4880 -0
- package/deps/librdkafka/src/rdkafka_conf.h +732 -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 +1422 -0
- package/deps/librdkafka/src/rdkafka_fetcher.h +44 -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 +1260 -0
- package/deps/librdkafka/src/rdkafka_interceptor.c +819 -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 +2209 -0
- package/deps/librdkafka/src/rdkafka_metadata.h +345 -0
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
- package/deps/librdkafka/src/rdkafka_mock.c +3661 -0
- package/deps/librdkafka/src/rdkafka_mock.h +610 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1876 -0
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +3113 -0
- package/deps/librdkafka/src/rdkafka_mock_int.h +710 -0
- package/deps/librdkafka/src/rdkafka_msg.c +2589 -0
- package/deps/librdkafka/src/rdkafka_msg.h +614 -0
- package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
- package/deps/librdkafka/src/rdkafka_msgset.h +98 -0
- package/deps/librdkafka/src/rdkafka_msgset_reader.c +1806 -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 +997 -0
- package/deps/librdkafka/src/rdkafka_op.h +858 -0
- package/deps/librdkafka/src/rdkafka_partition.c +4896 -0
- package/deps/librdkafka/src/rdkafka_partition.h +1182 -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 +736 -0
- package/deps/librdkafka/src/rdkafka_protocol.h +128 -0
- package/deps/librdkafka/src/rdkafka_queue.c +1230 -0
- package/deps/librdkafka/src/rdkafka_queue.h +1220 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
- package/deps/librdkafka/src/rdkafka_request.c +7089 -0
- package/deps/librdkafka/src/rdkafka_request.h +732 -0
- package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
- package/deps/librdkafka/src/rdkafka_sasl.c +530 -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 +1666 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +47 -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_ssl.c +2129 -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 +278 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +760 -0
- package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1053 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +997 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +301 -0
- package/deps/librdkafka/src/rdkafka_timer.c +402 -0
- package/deps/librdkafka/src/rdkafka_timer.h +117 -0
- package/deps/librdkafka/src/rdkafka_topic.c +2161 -0
- package/deps/librdkafka/src/rdkafka_topic.h +334 -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 +576 -0
- package/deps/librdkafka/src/rdlist.h +434 -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 +80 -0
- package/deps/librdkafka/src/rdrand.h +43 -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 +549 -0
- package/deps/librdkafka/src/rdunittest.h +232 -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 +199 -0
- package/deps/librdkafka/src/tinycthread_extra.h +212 -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 +97 -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 +338 -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 +279 -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 +481 -0
- package/deps/librdkafka/tests/0065-yield.cpp +140 -0
- package/deps/librdkafka/tests/0066-plugins.cpp +129 -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 +363 -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 +658 -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 +528 -0
- package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
- package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +125 -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 +143 -0
- package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +619 -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 +515 -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 +952 -0
- package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -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/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 +170 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
- package/deps/librdkafka/tests/Makefile +182 -0
- package/deps/librdkafka/tests/README.md +509 -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 +191 -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 +79 -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 +140 -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/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 +7778 -0
- package/deps/librdkafka/tests/test.conf.example +27 -0
- package/deps/librdkafka/tests/test.h +1028 -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.14.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 +276 -0
- package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
- package/deps/librdkafka/win32/msbuild.ps1 +15 -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 +253 -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 +62 -0
- package/lib/admin.js +233 -0
- package/lib/client.js +573 -0
- package/lib/error.js +500 -0
- package/lib/index.js +34 -0
- package/lib/kafka-consumer-stream.js +397 -0
- package/lib/kafka-consumer.js +698 -0
- package/lib/producer/high-level-producer.js +323 -0
- package/lib/producer-stream.js +307 -0
- package/lib/producer.js +375 -0
- package/lib/tools/ref-counter.js +52 -0
- package/lib/topic-partition.js +88 -0
- package/lib/topic.js +42 -0
- package/lib/util.js +29 -0
- package/package.json +61 -0
- package/prebuilds/darwin-arm64/@point3+node-rdkafka.node +0 -0
- package/prebuilds/linux-x64/@point3+node-rdkafka.node +0 -0
- package/util/configure.js +30 -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,1806 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* librdkafka - Apache Kafka C library
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-2022, Magnus Edenhill
|
|
5
|
+
* 2023, Confluent Inc.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
|
10
|
+
*
|
|
11
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
12
|
+
* this list of conditions and the following disclaimer.
|
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
18
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
19
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
20
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
21
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
22
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
23
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
24
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
25
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
26
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
27
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @name MessageSet reader interface
|
|
32
|
+
*
|
|
33
|
+
* Parses FetchResponse for Messages
|
|
34
|
+
*
|
|
35
|
+
*
|
|
36
|
+
* @remark
|
|
37
|
+
* The broker may send partial messages, when this happens we bail out
|
|
38
|
+
* silently and keep the messages that we successfully parsed.
|
|
39
|
+
*
|
|
40
|
+
* "A Guide To The Kafka Protocol" states:
|
|
41
|
+
* "As an optimization the server is allowed to
|
|
42
|
+
* return a partial message at the end of the
|
|
43
|
+
* message set.
|
|
44
|
+
* Clients should handle this case."
|
|
45
|
+
*
|
|
46
|
+
* We're handling it by not passing the error upstream.
|
|
47
|
+
* This is why most err_parse: goto labels (that are called from buf parsing
|
|
48
|
+
* macros) suppress the error message and why log_decode_errors is off
|
|
49
|
+
* unless PROTOCOL debugging is enabled.
|
|
50
|
+
*
|
|
51
|
+
* When a FetchResponse contains multiple partitions, each partition's
|
|
52
|
+
* MessageSet may be partial, regardless of the other partitions.
|
|
53
|
+
* To make sure the next partition can be parsed, each partition parse
|
|
54
|
+
* uses its own sub-slice of only that partition's MessageSetSize length.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
#include "rd.h"
|
|
58
|
+
#include "rdunittest.h"
|
|
59
|
+
#include "rdavl.h"
|
|
60
|
+
#include "rdlist.h"
|
|
61
|
+
#include "rdkafka_int.h"
|
|
62
|
+
#include "rdkafka_msg.h"
|
|
63
|
+
#include "rdkafka_msgset.h"
|
|
64
|
+
#include "rdkafka_topic.h"
|
|
65
|
+
#include "rdkafka_partition.h"
|
|
66
|
+
#include "rdkafka_header.h"
|
|
67
|
+
#include "rdkafka_lz4.h"
|
|
68
|
+
|
|
69
|
+
#include "rdvarint.h"
|
|
70
|
+
#include "crc32c.h"
|
|
71
|
+
|
|
72
|
+
#if WITH_ZLIB
|
|
73
|
+
#include "rdgz.h"
|
|
74
|
+
#endif
|
|
75
|
+
#if WITH_SNAPPY
|
|
76
|
+
#include "snappy.h"
|
|
77
|
+
#endif
|
|
78
|
+
#if WITH_ZSTD
|
|
79
|
+
#include "rdkafka_zstd.h"
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
static RD_INLINE int64_t
|
|
84
|
+
rd_kafka_aborted_txns_pop_offset(rd_kafka_aborted_txns_t *aborted_txns,
|
|
85
|
+
int64_t pid,
|
|
86
|
+
int64_t max_offset);
|
|
87
|
+
static RD_INLINE int64_t
|
|
88
|
+
rd_kafka_aborted_txns_get_offset(const rd_kafka_aborted_txns_t *aborted_txns,
|
|
89
|
+
int64_t pid);
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
struct msgset_v2_hdr {
|
|
93
|
+
int64_t BaseOffset;
|
|
94
|
+
int32_t Length;
|
|
95
|
+
int32_t PartitionLeaderEpoch;
|
|
96
|
+
int8_t MagicByte;
|
|
97
|
+
int32_t Crc;
|
|
98
|
+
int16_t Attributes;
|
|
99
|
+
int32_t LastOffsetDelta;
|
|
100
|
+
int64_t BaseTimestamp;
|
|
101
|
+
int64_t MaxTimestamp;
|
|
102
|
+
int64_t PID;
|
|
103
|
+
int16_t ProducerEpoch;
|
|
104
|
+
int32_t BaseSequence;
|
|
105
|
+
int32_t RecordCount;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @struct rd_kafka_aborted_txn_start_offsets_t
|
|
111
|
+
*
|
|
112
|
+
* @brief A sorted list of aborted transaction start offsets
|
|
113
|
+
* (ascending) for a PID, and an offset into that list.
|
|
114
|
+
*/
|
|
115
|
+
typedef struct rd_kafka_aborted_txn_start_offsets_s {
|
|
116
|
+
rd_avl_node_t avl_node;
|
|
117
|
+
int64_t pid;
|
|
118
|
+
int offsets_idx;
|
|
119
|
+
rd_list_t offsets;
|
|
120
|
+
} rd_kafka_aborted_txn_start_offsets_t;
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
typedef struct rd_kafka_msgset_reader_s {
|
|
124
|
+
rd_kafka_buf_t *msetr_rkbuf; /**< Response read buffer */
|
|
125
|
+
|
|
126
|
+
int msetr_relative_offsets; /**< Bool: using relative offsets */
|
|
127
|
+
|
|
128
|
+
/**< Outer/wrapper Message fields. */
|
|
129
|
+
struct {
|
|
130
|
+
int64_t offset; /**< Relative_offsets: outer message's
|
|
131
|
+
* Offset (last offset) */
|
|
132
|
+
rd_kafka_timestamp_type_t tstype; /**< Compressed
|
|
133
|
+
* MessageSet's
|
|
134
|
+
* timestamp type. */
|
|
135
|
+
int64_t timestamp; /**< ... timestamp*/
|
|
136
|
+
} msetr_outer;
|
|
137
|
+
|
|
138
|
+
struct msgset_v2_hdr *msetr_v2_hdr; /**< MessageSet v2 header */
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* Aborted Transaction Start Offsets. These are arranged in a map
|
|
142
|
+
* (ABORTED_TXN_OFFSETS), with PID as the key and value as follows:
|
|
143
|
+
* - OFFSETS: sorted list of aborted transaction start offsets
|
|
144
|
+
* (ascending)
|
|
145
|
+
* - IDX: an index into OFFSETS list, initialized to 0.
|
|
146
|
+
*
|
|
147
|
+
* The logic for processing fetched data is as follows (note: this is
|
|
148
|
+
* different from the Java client):
|
|
149
|
+
*
|
|
150
|
+
* 1. If the message is a transaction control message and the status is
|
|
151
|
+
* ABORT then increment ABORTED_TXN_OFFSETS(PID).IDX. note: sanity check
|
|
152
|
+
* that OFFSETS[ABORTED_TXN_OFFSETS(PID).IDX] is less than the current
|
|
153
|
+
* offset before incrementing. If the status is COMMIT, do nothing.
|
|
154
|
+
*
|
|
155
|
+
* 2. If the message is a normal message, find the corresponding OFFSETS
|
|
156
|
+
* list in ABORTED_TXN_OFFSETS. If it doesn't exist, then keep the
|
|
157
|
+
* message. If the PID does exist, compare ABORTED_TXN_OFFSETS(PID).IDX
|
|
158
|
+
* with len(OFFSETS). If it's >= then the message should be kept. If
|
|
159
|
+
* not, compare the message offset with
|
|
160
|
+
* OFFSETS[ABORTED_TXN_OFFSETS(PID).IDX]. If it's greater than or equal
|
|
161
|
+
* to this value, then the message should be ignored. If it's less than,
|
|
162
|
+
* then the message should be kept.
|
|
163
|
+
*
|
|
164
|
+
* Note: A MessageSet comprises messages from at most one transaction,
|
|
165
|
+
* so the logic in step 2 is done at the message set level.
|
|
166
|
+
*/
|
|
167
|
+
rd_kafka_aborted_txns_t *msetr_aborted_txns;
|
|
168
|
+
|
|
169
|
+
const struct rd_kafka_toppar_ver *msetr_tver; /**< Toppar op version of
|
|
170
|
+
* request. */
|
|
171
|
+
|
|
172
|
+
int32_t msetr_leader_epoch; /**< Current MessageSet's partition
|
|
173
|
+
* leader epoch (or -1). */
|
|
174
|
+
|
|
175
|
+
int32_t msetr_broker_id; /**< Broker id (of msetr_rkb) */
|
|
176
|
+
rd_kafka_broker_t *msetr_rkb; /* @warning Not a refcounted
|
|
177
|
+
* reference! */
|
|
178
|
+
rd_kafka_toppar_t *msetr_rktp; /* @warning Not a refcounted
|
|
179
|
+
* reference! */
|
|
180
|
+
|
|
181
|
+
int msetr_msgcnt; /**< Number of messages in rkq */
|
|
182
|
+
int64_t msetr_msg_bytes; /**< Number of bytes in rkq */
|
|
183
|
+
rd_kafka_q_t msetr_rkq; /**< Temp Message and error queue */
|
|
184
|
+
rd_kafka_q_t *msetr_par_rkq; /**< Parent message and error queue,
|
|
185
|
+
* the temp msetr_rkq will be moved
|
|
186
|
+
* to this queue when parsing
|
|
187
|
+
* is done.
|
|
188
|
+
* Refcount is not increased. */
|
|
189
|
+
|
|
190
|
+
int64_t msetr_next_offset; /**< Next offset to fetch after
|
|
191
|
+
* this reader run is done.
|
|
192
|
+
* Optional: only used for special
|
|
193
|
+
* cases where the per-message offset
|
|
194
|
+
* can't be relied on for next
|
|
195
|
+
* fetch offset, such as with
|
|
196
|
+
* compacted topics. */
|
|
197
|
+
|
|
198
|
+
int msetr_ctrl_cnt; /**< Number of control messages
|
|
199
|
+
* or MessageSets received. */
|
|
200
|
+
|
|
201
|
+
int msetr_aborted_cnt; /**< Number of aborted MessageSets
|
|
202
|
+
* encountered. */
|
|
203
|
+
|
|
204
|
+
const char *msetr_srcname; /**< Optional message source string,
|
|
205
|
+
* used in debug logging to
|
|
206
|
+
* indicate messages were
|
|
207
|
+
* from an inner compressed
|
|
208
|
+
* message set.
|
|
209
|
+
* Not freed (use const memory).
|
|
210
|
+
* Add trailing space. */
|
|
211
|
+
|
|
212
|
+
rd_kafka_compression_t msetr_compression; /**< Compression codec */
|
|
213
|
+
} rd_kafka_msgset_reader_t;
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
/* Forward declarations */
|
|
218
|
+
static rd_kafka_resp_err_t
|
|
219
|
+
rd_kafka_msgset_reader_run(rd_kafka_msgset_reader_t *msetr);
|
|
220
|
+
static rd_kafka_resp_err_t
|
|
221
|
+
rd_kafka_msgset_reader_msgs_v2(rd_kafka_msgset_reader_t *msetr);
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @brief Set up a MessageSet reader but don't start reading messages.
|
|
226
|
+
*/
|
|
227
|
+
static void rd_kafka_msgset_reader_init(rd_kafka_msgset_reader_t *msetr,
|
|
228
|
+
rd_kafka_buf_t *rkbuf,
|
|
229
|
+
rd_kafka_toppar_t *rktp,
|
|
230
|
+
const struct rd_kafka_toppar_ver *tver,
|
|
231
|
+
rd_kafka_aborted_txns_t *aborted_txns,
|
|
232
|
+
rd_kafka_q_t *par_rkq) {
|
|
233
|
+
|
|
234
|
+
memset(msetr, 0, sizeof(*msetr));
|
|
235
|
+
|
|
236
|
+
msetr->msetr_rkb = rkbuf->rkbuf_rkb;
|
|
237
|
+
msetr->msetr_leader_epoch = -1;
|
|
238
|
+
msetr->msetr_broker_id = rd_kafka_broker_id(msetr->msetr_rkb);
|
|
239
|
+
msetr->msetr_rktp = rktp;
|
|
240
|
+
msetr->msetr_aborted_txns = aborted_txns;
|
|
241
|
+
msetr->msetr_tver = tver;
|
|
242
|
+
msetr->msetr_rkbuf = rkbuf;
|
|
243
|
+
msetr->msetr_srcname = "";
|
|
244
|
+
|
|
245
|
+
rkbuf->rkbuf_uflow_mitigation = "truncated response from broker (ok)";
|
|
246
|
+
|
|
247
|
+
/* All parsed messages are put on this temporary op
|
|
248
|
+
* queue first and then moved in one go to the real op queue. */
|
|
249
|
+
rd_kafka_q_init(&msetr->msetr_rkq, msetr->msetr_rkb->rkb_rk);
|
|
250
|
+
|
|
251
|
+
/* Make sure enqueued ops get the correct serve/opaque reflecting the
|
|
252
|
+
* original queue. */
|
|
253
|
+
msetr->msetr_rkq.rkq_serve = par_rkq->rkq_serve;
|
|
254
|
+
msetr->msetr_rkq.rkq_opaque = par_rkq->rkq_opaque;
|
|
255
|
+
|
|
256
|
+
/* Keep (non-refcounted) reference to parent queue for
|
|
257
|
+
* moving the messages and events in msetr_rkq to when
|
|
258
|
+
* parsing is done. */
|
|
259
|
+
msetr->msetr_par_rkq = par_rkq;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @brief Decompress MessageSet, pass the uncompressed MessageSet to
|
|
266
|
+
* the MessageSet reader.
|
|
267
|
+
*/
|
|
268
|
+
static rd_kafka_resp_err_t
|
|
269
|
+
rd_kafka_msgset_reader_decompress(rd_kafka_msgset_reader_t *msetr,
|
|
270
|
+
int MsgVersion,
|
|
271
|
+
int Attributes,
|
|
272
|
+
int64_t Timestamp,
|
|
273
|
+
int64_t Offset,
|
|
274
|
+
const void *compressed,
|
|
275
|
+
size_t compressed_size) {
|
|
276
|
+
struct iovec iov = {.iov_base = NULL, .iov_len = 0};
|
|
277
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
278
|
+
int codec = Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK;
|
|
279
|
+
rd_kafka_resp_err_t err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
280
|
+
rd_kafka_buf_t *rkbufz;
|
|
281
|
+
|
|
282
|
+
msetr->msetr_compression = codec;
|
|
283
|
+
|
|
284
|
+
switch (codec) {
|
|
285
|
+
#if WITH_ZLIB
|
|
286
|
+
case RD_KAFKA_COMPRESSION_GZIP: {
|
|
287
|
+
uint64_t outlenx = 0;
|
|
288
|
+
|
|
289
|
+
/* Decompress Message payload */
|
|
290
|
+
iov.iov_base = rd_gz_decompress(compressed,
|
|
291
|
+
(int)compressed_size, &outlenx);
|
|
292
|
+
if (unlikely(!iov.iov_base)) {
|
|
293
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "GZIP",
|
|
294
|
+
"Failed to decompress Gzip "
|
|
295
|
+
"message at offset %" PRId64 " of %" PRIusz
|
|
296
|
+
" bytes: "
|
|
297
|
+
"ignoring message",
|
|
298
|
+
Offset, compressed_size);
|
|
299
|
+
err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
|
|
300
|
+
goto err;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
iov.iov_len = (size_t)outlenx;
|
|
304
|
+
} break;
|
|
305
|
+
#endif
|
|
306
|
+
|
|
307
|
+
#if WITH_SNAPPY
|
|
308
|
+
case RD_KAFKA_COMPRESSION_SNAPPY: {
|
|
309
|
+
const char *inbuf = compressed;
|
|
310
|
+
size_t inlen = compressed_size;
|
|
311
|
+
int r;
|
|
312
|
+
static const unsigned char snappy_java_magic[] = {
|
|
313
|
+
0x82, 'S', 'N', 'A', 'P', 'P', 'Y', 0};
|
|
314
|
+
static const size_t snappy_java_hdrlen = 8 + 4 + 4;
|
|
315
|
+
|
|
316
|
+
/* snappy-java adds its own header (SnappyCodec)
|
|
317
|
+
* which is not compatible with the official Snappy
|
|
318
|
+
* implementation.
|
|
319
|
+
* 8: magic, 4: version, 4: compatible
|
|
320
|
+
* followed by any number of chunks:
|
|
321
|
+
* 4: length
|
|
322
|
+
* ...: snappy-compressed data. */
|
|
323
|
+
if (likely(inlen > snappy_java_hdrlen + 4 &&
|
|
324
|
+
!memcmp(inbuf, snappy_java_magic, 8))) {
|
|
325
|
+
/* snappy-java framing */
|
|
326
|
+
char errstr[128];
|
|
327
|
+
|
|
328
|
+
inbuf = inbuf + snappy_java_hdrlen;
|
|
329
|
+
inlen -= snappy_java_hdrlen;
|
|
330
|
+
iov.iov_base = rd_kafka_snappy_java_uncompress(
|
|
331
|
+
inbuf, inlen, &iov.iov_len, errstr, sizeof(errstr));
|
|
332
|
+
|
|
333
|
+
if (unlikely(!iov.iov_base)) {
|
|
334
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
|
|
335
|
+
"%s [%" PRId32
|
|
336
|
+
"]: "
|
|
337
|
+
"Snappy decompression for message "
|
|
338
|
+
"at offset %" PRId64
|
|
339
|
+
" failed: %s: "
|
|
340
|
+
"ignoring message",
|
|
341
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
342
|
+
rktp->rktp_partition, Offset,
|
|
343
|
+
errstr);
|
|
344
|
+
err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
|
|
345
|
+
goto err;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
} else {
|
|
350
|
+
/* No framing */
|
|
351
|
+
|
|
352
|
+
/* Acquire uncompressed length */
|
|
353
|
+
if (unlikely(!rd_kafka_snappy_uncompressed_length(
|
|
354
|
+
inbuf, inlen, &iov.iov_len))) {
|
|
355
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
|
|
356
|
+
"Failed to get length of Snappy "
|
|
357
|
+
"compressed payload "
|
|
358
|
+
"for message at offset %" PRId64
|
|
359
|
+
" (%" PRIusz
|
|
360
|
+
" bytes): "
|
|
361
|
+
"ignoring message",
|
|
362
|
+
Offset, inlen);
|
|
363
|
+
err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
|
|
364
|
+
goto err;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* Allocate output buffer for uncompressed data */
|
|
368
|
+
iov.iov_base = rd_malloc(iov.iov_len);
|
|
369
|
+
if (unlikely(!iov.iov_base)) {
|
|
370
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
|
|
371
|
+
"Failed to allocate Snappy "
|
|
372
|
+
"decompress buffer of size %" PRIusz
|
|
373
|
+
"for message at offset %" PRId64
|
|
374
|
+
" (%" PRIusz
|
|
375
|
+
" bytes): %s: "
|
|
376
|
+
"ignoring message",
|
|
377
|
+
iov.iov_len, Offset, inlen,
|
|
378
|
+
rd_strerror(errno));
|
|
379
|
+
err = RD_KAFKA_RESP_ERR__CRIT_SYS_RESOURCE;
|
|
380
|
+
goto err;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* Uncompress to outbuf */
|
|
384
|
+
if (unlikely((r = rd_kafka_snappy_uncompress(
|
|
385
|
+
inbuf, inlen, iov.iov_base)))) {
|
|
386
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
|
|
387
|
+
"Failed to decompress Snappy "
|
|
388
|
+
"payload for message at offset "
|
|
389
|
+
"%" PRId64 " (%" PRIusz
|
|
390
|
+
" bytes): %s: "
|
|
391
|
+
"ignoring message",
|
|
392
|
+
Offset, inlen,
|
|
393
|
+
rd_strerror(-r /*negative errno*/));
|
|
394
|
+
rd_free(iov.iov_base);
|
|
395
|
+
err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
|
|
396
|
+
goto err;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
} break;
|
|
401
|
+
#endif
|
|
402
|
+
|
|
403
|
+
case RD_KAFKA_COMPRESSION_LZ4: {
|
|
404
|
+
err =
|
|
405
|
+
rd_kafka_lz4_decompress(msetr->msetr_rkb,
|
|
406
|
+
/* Proper HC? */
|
|
407
|
+
MsgVersion >= 1 ? 1 : 0, Offset,
|
|
408
|
+
/* @warning Will modify compressed
|
|
409
|
+
* if no proper HC */
|
|
410
|
+
(char *)compressed, compressed_size,
|
|
411
|
+
&iov.iov_base, &iov.iov_len);
|
|
412
|
+
if (err)
|
|
413
|
+
goto err;
|
|
414
|
+
} break;
|
|
415
|
+
|
|
416
|
+
#if WITH_ZSTD
|
|
417
|
+
case RD_KAFKA_COMPRESSION_ZSTD: {
|
|
418
|
+
err = rd_kafka_zstd_decompress(
|
|
419
|
+
msetr->msetr_rkb, (char *)compressed, compressed_size,
|
|
420
|
+
&iov.iov_base, &iov.iov_len);
|
|
421
|
+
if (err)
|
|
422
|
+
goto err;
|
|
423
|
+
} break;
|
|
424
|
+
#endif
|
|
425
|
+
|
|
426
|
+
default:
|
|
427
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "CODEC",
|
|
428
|
+
"%s [%" PRId32 "]: Message at offset %" PRId64
|
|
429
|
+
" with unsupported "
|
|
430
|
+
"compression codec 0x%x: message ignored",
|
|
431
|
+
rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
|
|
432
|
+
Offset, (int)codec);
|
|
433
|
+
|
|
434
|
+
err = RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED;
|
|
435
|
+
goto err;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
rd_assert(iov.iov_base);
|
|
440
|
+
|
|
441
|
+
/*
|
|
442
|
+
* Decompression successful
|
|
443
|
+
*/
|
|
444
|
+
|
|
445
|
+
/* Create a new buffer pointing to the uncompressed
|
|
446
|
+
* allocated buffer (outbuf) and let messages keep a reference to
|
|
447
|
+
* this new buffer. */
|
|
448
|
+
rkbufz = rd_kafka_buf_new_shadow(iov.iov_base, iov.iov_len, rd_free);
|
|
449
|
+
rkbufz->rkbuf_rkb = msetr->msetr_rkbuf->rkbuf_rkb;
|
|
450
|
+
rd_kafka_broker_keep(rkbufz->rkbuf_rkb);
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
/* In MsgVersion v0..1 the decompressed data contains
|
|
454
|
+
* an inner MessageSet, pass it to a new MessageSet reader.
|
|
455
|
+
*
|
|
456
|
+
* For MsgVersion v2 the decompressed data are the list of messages.
|
|
457
|
+
*/
|
|
458
|
+
|
|
459
|
+
if (MsgVersion <= 1) {
|
|
460
|
+
/* Pass decompressed data (inner Messageset)
|
|
461
|
+
* to new instance of the MessageSet parser. */
|
|
462
|
+
rd_kafka_msgset_reader_t inner_msetr;
|
|
463
|
+
rd_kafka_msgset_reader_init(
|
|
464
|
+
&inner_msetr, rkbufz, msetr->msetr_rktp, msetr->msetr_tver,
|
|
465
|
+
/* there is no aborted transaction
|
|
466
|
+
* support for MsgVersion < 2 */
|
|
467
|
+
NULL, &msetr->msetr_rkq);
|
|
468
|
+
|
|
469
|
+
inner_msetr.msetr_srcname = "compressed ";
|
|
470
|
+
|
|
471
|
+
if (MsgVersion == 1) {
|
|
472
|
+
/* postproc() will convert relative to
|
|
473
|
+
* absolute offsets */
|
|
474
|
+
inner_msetr.msetr_relative_offsets = 1;
|
|
475
|
+
inner_msetr.msetr_outer.offset = Offset;
|
|
476
|
+
|
|
477
|
+
/* Apply single LogAppendTime timestamp for
|
|
478
|
+
* all messages. */
|
|
479
|
+
if (Attributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME) {
|
|
480
|
+
inner_msetr.msetr_outer.tstype =
|
|
481
|
+
RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
|
|
482
|
+
inner_msetr.msetr_outer.timestamp = Timestamp;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* Parse the inner MessageSet */
|
|
487
|
+
err = rd_kafka_msgset_reader_run(&inner_msetr);
|
|
488
|
+
|
|
489
|
+
/* Transfer message count from inner to outer */
|
|
490
|
+
msetr->msetr_msgcnt += inner_msetr.msetr_msgcnt;
|
|
491
|
+
msetr->msetr_msg_bytes += inner_msetr.msetr_msg_bytes;
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
} else {
|
|
495
|
+
/* MsgVersion 2 */
|
|
496
|
+
rd_kafka_buf_t *orig_rkbuf = msetr->msetr_rkbuf;
|
|
497
|
+
|
|
498
|
+
rkbufz->rkbuf_uflow_mitigation =
|
|
499
|
+
"truncated response from broker (ok)";
|
|
500
|
+
|
|
501
|
+
/* Temporarily replace read buffer with uncompressed buffer */
|
|
502
|
+
msetr->msetr_rkbuf = rkbufz;
|
|
503
|
+
|
|
504
|
+
/* Read messages */
|
|
505
|
+
err = rd_kafka_msgset_reader_msgs_v2(msetr);
|
|
506
|
+
|
|
507
|
+
/* Restore original buffer */
|
|
508
|
+
msetr->msetr_rkbuf = orig_rkbuf;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/* Loose our refcnt of the uncompressed rkbuf.
|
|
512
|
+
* Individual messages/rko's will have their own reference. */
|
|
513
|
+
rd_kafka_buf_destroy(rkbufz);
|
|
514
|
+
|
|
515
|
+
return err;
|
|
516
|
+
|
|
517
|
+
err:
|
|
518
|
+
/* Enqueue error messsage:
|
|
519
|
+
* Create op and push on temporary queue. */
|
|
520
|
+
rd_kafka_consumer_err(
|
|
521
|
+
&msetr->msetr_rkq, msetr->msetr_broker_id, err,
|
|
522
|
+
msetr->msetr_tver->version, NULL, rktp, Offset,
|
|
523
|
+
"Decompression (codec 0x%x) of message at %" PRIu64 " of %" PRIusz
|
|
524
|
+
" bytes failed: %s",
|
|
525
|
+
codec, Offset, compressed_size, rd_kafka_err2str(err));
|
|
526
|
+
|
|
527
|
+
return err;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* @brief Message parser for MsgVersion v0..1
|
|
534
|
+
*
|
|
535
|
+
* @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or on single-message errors,
|
|
536
|
+
* or any other error code when the MessageSet parser should stop
|
|
537
|
+
* parsing (such as for partial Messages).
|
|
538
|
+
*/
|
|
539
|
+
static rd_kafka_resp_err_t
|
|
540
|
+
rd_kafka_msgset_reader_msg_v0_1(rd_kafka_msgset_reader_t *msetr) {
|
|
541
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
542
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
543
|
+
rd_kafka_broker_t *rkb = msetr->msetr_rkb;
|
|
544
|
+
struct {
|
|
545
|
+
int64_t Offset; /* MessageSet header */
|
|
546
|
+
int32_t MessageSize; /* MessageSet header */
|
|
547
|
+
int32_t Crc;
|
|
548
|
+
int8_t MagicByte; /* MsgVersion */
|
|
549
|
+
int8_t Attributes;
|
|
550
|
+
int64_t Timestamp; /* v1 */
|
|
551
|
+
} hdr; /* Message header */
|
|
552
|
+
rd_kafkap_bytes_t Key;
|
|
553
|
+
rd_kafkap_bytes_t Value;
|
|
554
|
+
int32_t Value_len;
|
|
555
|
+
rd_kafka_op_t *rko;
|
|
556
|
+
size_t hdrsize = 6; /* Header size following MessageSize */
|
|
557
|
+
rd_slice_t crc_slice;
|
|
558
|
+
rd_kafka_msg_t *rkm;
|
|
559
|
+
int relative_offsets = 0;
|
|
560
|
+
const char *reloff_str = "";
|
|
561
|
+
/* Only log decoding errors if protocol debugging enabled. */
|
|
562
|
+
int log_decode_errors =
|
|
563
|
+
(rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
|
|
564
|
+
? LOG_DEBUG
|
|
565
|
+
: 0;
|
|
566
|
+
size_t message_end;
|
|
567
|
+
|
|
568
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.Offset);
|
|
569
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.MessageSize);
|
|
570
|
+
message_end = rd_slice_offset(&rkbuf->rkbuf_reader) + hdr.MessageSize;
|
|
571
|
+
|
|
572
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.Crc);
|
|
573
|
+
if (!rd_slice_narrow_copy_relative(&rkbuf->rkbuf_reader, &crc_slice,
|
|
574
|
+
hdr.MessageSize - 4))
|
|
575
|
+
rd_kafka_buf_check_len(rkbuf, hdr.MessageSize - 4);
|
|
576
|
+
|
|
577
|
+
rd_kafka_buf_read_i8(rkbuf, &hdr.MagicByte);
|
|
578
|
+
rd_kafka_buf_read_i8(rkbuf, &hdr.Attributes);
|
|
579
|
+
|
|
580
|
+
if (hdr.MagicByte == 1) { /* MsgVersion */
|
|
581
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.Timestamp);
|
|
582
|
+
hdrsize += 8;
|
|
583
|
+
/* MsgVersion 1 has relative offsets for compressed
|
|
584
|
+
* MessageSets*/
|
|
585
|
+
if (!(hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK) &&
|
|
586
|
+
msetr->msetr_relative_offsets) {
|
|
587
|
+
relative_offsets = 1;
|
|
588
|
+
reloff_str = "relative ";
|
|
589
|
+
}
|
|
590
|
+
} else
|
|
591
|
+
hdr.Timestamp = 0;
|
|
592
|
+
|
|
593
|
+
/* Verify MessageSize */
|
|
594
|
+
if (unlikely(hdr.MessageSize < (ssize_t)hdrsize))
|
|
595
|
+
rd_kafka_buf_parse_fail(
|
|
596
|
+
rkbuf,
|
|
597
|
+
"Message at %soffset %" PRId64 " MessageSize %" PRId32
|
|
598
|
+
" < hdrsize %" PRIusz,
|
|
599
|
+
reloff_str, hdr.Offset, hdr.MessageSize, hdrsize);
|
|
600
|
+
|
|
601
|
+
/* Early check for partial messages */
|
|
602
|
+
rd_kafka_buf_check_len(rkbuf, hdr.MessageSize - hdrsize);
|
|
603
|
+
|
|
604
|
+
if (rkb->rkb_rk->rk_conf.check_crcs) {
|
|
605
|
+
/* Verify CRC32 if desired. */
|
|
606
|
+
uint32_t calc_crc;
|
|
607
|
+
|
|
608
|
+
calc_crc = rd_slice_crc32(&crc_slice);
|
|
609
|
+
rd_dassert(rd_slice_remains(&crc_slice) == 0);
|
|
610
|
+
|
|
611
|
+
if (unlikely(hdr.Crc != (int32_t)calc_crc)) {
|
|
612
|
+
/* Propagate CRC error to application and
|
|
613
|
+
* continue with next message. */
|
|
614
|
+
rd_kafka_consumer_err(
|
|
615
|
+
&msetr->msetr_rkq, msetr->msetr_broker_id,
|
|
616
|
+
RD_KAFKA_RESP_ERR__BAD_MSG,
|
|
617
|
+
msetr->msetr_tver->version, NULL, rktp, hdr.Offset,
|
|
618
|
+
"Message at %soffset %" PRId64 " (%" PRId32
|
|
619
|
+
" bytes) "
|
|
620
|
+
"failed CRC32 check "
|
|
621
|
+
"(original 0x%" PRIx32
|
|
622
|
+
" != "
|
|
623
|
+
"calculated 0x%" PRIx32 ")",
|
|
624
|
+
reloff_str, hdr.Offset, hdr.MessageSize, hdr.Crc,
|
|
625
|
+
calc_crc);
|
|
626
|
+
rd_kafka_buf_skip_to(rkbuf, message_end);
|
|
627
|
+
rd_atomic64_add(&rkb->rkb_c.rx_err, 1);
|
|
628
|
+
/* Continue with next message */
|
|
629
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
/* Extract key */
|
|
635
|
+
rd_kafka_buf_read_kbytes(rkbuf, &Key);
|
|
636
|
+
|
|
637
|
+
/* Extract Value */
|
|
638
|
+
rd_kafka_buf_read_kbytes(rkbuf, &Value);
|
|
639
|
+
Value_len = RD_KAFKAP_BYTES_LEN(&Value);
|
|
640
|
+
|
|
641
|
+
/* MessageSets may contain offsets earlier than we
|
|
642
|
+
* requested (compressed MessageSets in particular),
|
|
643
|
+
* drop the earlier messages.
|
|
644
|
+
* Note: the inner offset may only be trusted for
|
|
645
|
+
* absolute offsets. KIP-31 introduced
|
|
646
|
+
* ApiVersion 2 that maintains relative offsets
|
|
647
|
+
* of compressed messages and the base offset
|
|
648
|
+
* in the outer message is the offset of
|
|
649
|
+
* the *LAST* message in the MessageSet.
|
|
650
|
+
* This requires us to assign offsets
|
|
651
|
+
* after all messages have been read from
|
|
652
|
+
* the messageset, and it also means
|
|
653
|
+
* we cant perform this offset check here
|
|
654
|
+
* in that case. */
|
|
655
|
+
if (!relative_offsets &&
|
|
656
|
+
hdr.Offset < rktp->rktp_offsets.fetch_pos.offset)
|
|
657
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next msg */
|
|
658
|
+
|
|
659
|
+
/* Handle compressed MessageSet */
|
|
660
|
+
if (unlikely(hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK))
|
|
661
|
+
return rd_kafka_msgset_reader_decompress(
|
|
662
|
+
msetr, hdr.MagicByte, hdr.Attributes, hdr.Timestamp,
|
|
663
|
+
hdr.Offset, Value.data, Value_len);
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
/* Pure uncompressed message, this is the innermost
|
|
667
|
+
* handler after all compression and cascaded
|
|
668
|
+
* MessageSets have been peeled off. */
|
|
669
|
+
|
|
670
|
+
/* Create op/message container for message. */
|
|
671
|
+
rko = rd_kafka_op_new_fetch_msg(
|
|
672
|
+
&rkm, rktp, msetr->msetr_tver->version, rkbuf,
|
|
673
|
+
RD_KAFKA_FETCH_POS(hdr.Offset, msetr->msetr_leader_epoch),
|
|
674
|
+
(size_t)RD_KAFKAP_BYTES_LEN(&Key),
|
|
675
|
+
RD_KAFKAP_BYTES_IS_NULL(&Key) ? NULL : Key.data,
|
|
676
|
+
(size_t)RD_KAFKAP_BYTES_LEN(&Value),
|
|
677
|
+
RD_KAFKAP_BYTES_IS_NULL(&Value) ? NULL : Value.data);
|
|
678
|
+
|
|
679
|
+
rkm->rkm_broker_id = msetr->msetr_broker_id;
|
|
680
|
+
|
|
681
|
+
/* Assign message timestamp.
|
|
682
|
+
* If message was in a compressed MessageSet and the outer/wrapper
|
|
683
|
+
* Message.Attribute had a LOG_APPEND_TIME set, use the
|
|
684
|
+
* outer timestamp */
|
|
685
|
+
if (msetr->msetr_outer.tstype == RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME) {
|
|
686
|
+
rkm->rkm_timestamp = msetr->msetr_outer.timestamp;
|
|
687
|
+
rkm->rkm_tstype = msetr->msetr_outer.tstype;
|
|
688
|
+
|
|
689
|
+
} else if (hdr.MagicByte >= 1 && hdr.Timestamp) {
|
|
690
|
+
rkm->rkm_timestamp = hdr.Timestamp;
|
|
691
|
+
if (hdr.Attributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME)
|
|
692
|
+
rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
|
|
693
|
+
else
|
|
694
|
+
rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_CREATE_TIME;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/* Enqueue message on temporary queue */
|
|
698
|
+
rd_kafka_q_enq(&msetr->msetr_rkq, rko);
|
|
699
|
+
msetr->msetr_msgcnt++;
|
|
700
|
+
msetr->msetr_msg_bytes += rkm->rkm_key_len + rkm->rkm_len;
|
|
701
|
+
|
|
702
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue */
|
|
703
|
+
|
|
704
|
+
err_parse:
|
|
705
|
+
/* Count all parse errors as partial message errors. */
|
|
706
|
+
rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
|
|
707
|
+
return rkbuf->rkbuf_err;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* @brief Message parser for MsgVersion v2
|
|
714
|
+
*/
|
|
715
|
+
static rd_kafka_resp_err_t
|
|
716
|
+
rd_kafka_msgset_reader_msg_v2(rd_kafka_msgset_reader_t *msetr) {
|
|
717
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
718
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
719
|
+
struct {
|
|
720
|
+
int64_t Length;
|
|
721
|
+
int8_t MsgAttributes;
|
|
722
|
+
int64_t TimestampDelta;
|
|
723
|
+
int64_t OffsetDelta;
|
|
724
|
+
int64_t Offset; /* Absolute offset */
|
|
725
|
+
rd_kafkap_bytes_t Key;
|
|
726
|
+
rd_kafkap_bytes_t Value;
|
|
727
|
+
rd_kafkap_bytes_t Headers;
|
|
728
|
+
} hdr;
|
|
729
|
+
rd_kafka_op_t *rko;
|
|
730
|
+
rd_kafka_msg_t *rkm;
|
|
731
|
+
/* Only log decoding errors if protocol debugging enabled. */
|
|
732
|
+
int log_decode_errors =
|
|
733
|
+
(rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
|
|
734
|
+
? LOG_DEBUG
|
|
735
|
+
: 0;
|
|
736
|
+
size_t message_end;
|
|
737
|
+
rd_kafka_fetch_pos_t msetr_pos;
|
|
738
|
+
|
|
739
|
+
rd_kafka_buf_read_varint(rkbuf, &hdr.Length);
|
|
740
|
+
message_end =
|
|
741
|
+
rd_slice_offset(&rkbuf->rkbuf_reader) + (size_t)hdr.Length;
|
|
742
|
+
rd_kafka_buf_read_i8(rkbuf, &hdr.MsgAttributes);
|
|
743
|
+
|
|
744
|
+
rd_kafka_buf_read_varint(rkbuf, &hdr.TimestampDelta);
|
|
745
|
+
rd_kafka_buf_read_varint(rkbuf, &hdr.OffsetDelta);
|
|
746
|
+
hdr.Offset = msetr->msetr_v2_hdr->BaseOffset + hdr.OffsetDelta;
|
|
747
|
+
msetr_pos = RD_KAFKA_FETCH_POS(hdr.Offset, msetr->msetr_leader_epoch);
|
|
748
|
+
|
|
749
|
+
/* Skip message if outdated.
|
|
750
|
+
* Don't check offset leader epoch, just log it, as if current leader
|
|
751
|
+
* epoch is different the fetch will fail (KIP-320) and if offset leader
|
|
752
|
+
* epoch is different it'll return an empty fetch (KIP-595). If we
|
|
753
|
+
* checked it, it's possible to have a loop when moving from a broker
|
|
754
|
+
* that supports leader epoch to one that doesn't. */
|
|
755
|
+
if (hdr.Offset < rktp->rktp_offsets.fetch_pos.offset) {
|
|
756
|
+
rd_rkb_dbg(
|
|
757
|
+
msetr->msetr_rkb, MSG, "MSG",
|
|
758
|
+
"%s [%" PRId32
|
|
759
|
+
"]: "
|
|
760
|
+
"Skip %s < fetch %s",
|
|
761
|
+
rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
|
|
762
|
+
rd_kafka_fetch_pos2str(msetr_pos),
|
|
763
|
+
rd_kafka_fetch_pos2str(rktp->rktp_offsets.fetch_pos));
|
|
764
|
+
rd_kafka_buf_skip_to(rkbuf, message_end);
|
|
765
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next msg */
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/* Handle control messages */
|
|
769
|
+
if (msetr->msetr_v2_hdr->Attributes & RD_KAFKA_MSGSET_V2_ATTR_CONTROL) {
|
|
770
|
+
struct {
|
|
771
|
+
int64_t KeySize;
|
|
772
|
+
int16_t Version;
|
|
773
|
+
int16_t Type;
|
|
774
|
+
} ctrl_data;
|
|
775
|
+
int64_t aborted_txn_start_offset;
|
|
776
|
+
|
|
777
|
+
rd_kafka_buf_read_varint(rkbuf, &ctrl_data.KeySize);
|
|
778
|
+
|
|
779
|
+
if (unlikely(ctrl_data.KeySize < 2))
|
|
780
|
+
rd_kafka_buf_parse_fail(
|
|
781
|
+
rkbuf,
|
|
782
|
+
"%s [%" PRId32
|
|
783
|
+
"]: "
|
|
784
|
+
"Ctrl message at %s"
|
|
785
|
+
" has invalid key size %" PRId64,
|
|
786
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
787
|
+
rktp->rktp_partition,
|
|
788
|
+
rd_kafka_fetch_pos2str(msetr_pos),
|
|
789
|
+
ctrl_data.KeySize);
|
|
790
|
+
|
|
791
|
+
rd_kafka_buf_read_i16(rkbuf, &ctrl_data.Version);
|
|
792
|
+
|
|
793
|
+
if (ctrl_data.Version != 0) {
|
|
794
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "MSG",
|
|
795
|
+
"%s [%" PRId32
|
|
796
|
+
"]: "
|
|
797
|
+
"Skipping ctrl msg with "
|
|
798
|
+
"unsupported version %" PRId16 " at %s",
|
|
799
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
800
|
+
rktp->rktp_partition, ctrl_data.Version,
|
|
801
|
+
rd_kafka_fetch_pos2str(msetr_pos));
|
|
802
|
+
rd_kafka_buf_skip_to(rkbuf, message_end);
|
|
803
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next
|
|
804
|
+
msg */
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
if (unlikely(ctrl_data.KeySize != 4))
|
|
808
|
+
rd_kafka_buf_parse_fail(
|
|
809
|
+
rkbuf,
|
|
810
|
+
"%s [%" PRId32
|
|
811
|
+
"]: "
|
|
812
|
+
"Ctrl message at %s"
|
|
813
|
+
" has invalid key size %" PRId64,
|
|
814
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
815
|
+
rktp->rktp_partition,
|
|
816
|
+
rd_kafka_fetch_pos2str(msetr_pos),
|
|
817
|
+
ctrl_data.KeySize);
|
|
818
|
+
|
|
819
|
+
rd_kafka_buf_read_i16(rkbuf, &ctrl_data.Type);
|
|
820
|
+
|
|
821
|
+
/* Client is uninterested in value of commit marker */
|
|
822
|
+
rd_kafka_buf_skip(
|
|
823
|
+
rkbuf, (int32_t)(message_end -
|
|
824
|
+
rd_slice_offset(&rkbuf->rkbuf_reader)));
|
|
825
|
+
|
|
826
|
+
switch (ctrl_data.Type) {
|
|
827
|
+
case RD_KAFKA_CTRL_MSG_COMMIT:
|
|
828
|
+
/* always ignore. */
|
|
829
|
+
break;
|
|
830
|
+
|
|
831
|
+
case RD_KAFKA_CTRL_MSG_ABORT:
|
|
832
|
+
if (msetr->msetr_rkb->rkb_rk->rk_conf.isolation_level !=
|
|
833
|
+
RD_KAFKA_READ_COMMITTED)
|
|
834
|
+
break;
|
|
835
|
+
|
|
836
|
+
if (unlikely(!msetr->msetr_aborted_txns)) {
|
|
837
|
+
rd_rkb_dbg(msetr->msetr_rkb,
|
|
838
|
+
MSG | RD_KAFKA_DBG_EOS, "TXN",
|
|
839
|
+
"%s [%" PRId32
|
|
840
|
+
"] received abort txn "
|
|
841
|
+
"ctrl msg at %s"
|
|
842
|
+
" for "
|
|
843
|
+
"PID %" PRId64
|
|
844
|
+
", but there are no "
|
|
845
|
+
"known aborted transactions: "
|
|
846
|
+
"ignoring",
|
|
847
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
848
|
+
rktp->rktp_partition,
|
|
849
|
+
rd_kafka_fetch_pos2str(msetr_pos),
|
|
850
|
+
msetr->msetr_v2_hdr->PID);
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/* This marks the end of this (aborted) transaction,
|
|
855
|
+
* advance to next aborted transaction in list */
|
|
856
|
+
aborted_txn_start_offset =
|
|
857
|
+
rd_kafka_aborted_txns_pop_offset(
|
|
858
|
+
msetr->msetr_aborted_txns,
|
|
859
|
+
msetr->msetr_v2_hdr->PID, msetr_pos.offset);
|
|
860
|
+
|
|
861
|
+
if (unlikely(aborted_txn_start_offset == -1)) {
|
|
862
|
+
rd_rkb_dbg(msetr->msetr_rkb,
|
|
863
|
+
MSG | RD_KAFKA_DBG_EOS, "TXN",
|
|
864
|
+
"%s [%" PRId32
|
|
865
|
+
"] received abort txn "
|
|
866
|
+
"ctrl msg at %s"
|
|
867
|
+
" for "
|
|
868
|
+
"PID %" PRId64
|
|
869
|
+
", but this offset is "
|
|
870
|
+
"not listed as an aborted "
|
|
871
|
+
"transaction: aborted transaction "
|
|
872
|
+
"was possibly empty: ignoring",
|
|
873
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
874
|
+
rktp->rktp_partition,
|
|
875
|
+
rd_kafka_fetch_pos2str(msetr_pos),
|
|
876
|
+
msetr->msetr_v2_hdr->PID);
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
break;
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
default:
|
|
883
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG,
|
|
884
|
+
"TXN"
|
|
885
|
+
"%s [%" PRId32
|
|
886
|
+
"]: "
|
|
887
|
+
"Unsupported ctrl message "
|
|
888
|
+
"type %" PRId16
|
|
889
|
+
" at "
|
|
890
|
+
" %s: ignoring",
|
|
891
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
892
|
+
rktp->rktp_partition, ctrl_data.Type,
|
|
893
|
+
rd_kafka_fetch_pos2str(msetr_pos));
|
|
894
|
+
break;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
rko = rd_kafka_op_new_ctrl_msg(rktp, msetr->msetr_tver->version,
|
|
898
|
+
rkbuf, msetr_pos);
|
|
899
|
+
rd_kafka_q_enq(&msetr->msetr_rkq, rko);
|
|
900
|
+
msetr->msetr_msgcnt++;
|
|
901
|
+
|
|
902
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/* Regular message */
|
|
906
|
+
|
|
907
|
+
/* Note: messages in aborted transactions are skipped at the MessageSet
|
|
908
|
+
* level */
|
|
909
|
+
|
|
910
|
+
rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Key);
|
|
911
|
+
rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Value);
|
|
912
|
+
|
|
913
|
+
/* We parse the Headers later, just store the size (possibly truncated)
|
|
914
|
+
* and pointer to the headers. */
|
|
915
|
+
hdr.Headers.len =
|
|
916
|
+
(int32_t)(message_end - rd_slice_offset(&rkbuf->rkbuf_reader));
|
|
917
|
+
rd_kafka_buf_read_ptr(rkbuf, &hdr.Headers.data, hdr.Headers.len);
|
|
918
|
+
|
|
919
|
+
/* Create op/message container for message. */
|
|
920
|
+
rko = rd_kafka_op_new_fetch_msg(
|
|
921
|
+
&rkm, rktp, msetr->msetr_tver->version, rkbuf, msetr_pos,
|
|
922
|
+
(size_t)RD_KAFKAP_BYTES_LEN(&hdr.Key),
|
|
923
|
+
RD_KAFKAP_BYTES_IS_NULL(&hdr.Key) ? NULL : hdr.Key.data,
|
|
924
|
+
(size_t)RD_KAFKAP_BYTES_LEN(&hdr.Value),
|
|
925
|
+
RD_KAFKAP_BYTES_IS_NULL(&hdr.Value) ? NULL : hdr.Value.data);
|
|
926
|
+
|
|
927
|
+
rkm->rkm_broker_id = msetr->msetr_broker_id;
|
|
928
|
+
|
|
929
|
+
/* Store pointer to unparsed message headers, they will
|
|
930
|
+
* be parsed on the first access.
|
|
931
|
+
* This pointer points to the rkbuf payload.
|
|
932
|
+
* Note: can't perform struct copy here due to const fields (MSVC) */
|
|
933
|
+
rkm->rkm_u.consumer.binhdrs.len = hdr.Headers.len;
|
|
934
|
+
rkm->rkm_u.consumer.binhdrs.data = hdr.Headers.data;
|
|
935
|
+
|
|
936
|
+
/* Set timestamp.
|
|
937
|
+
*
|
|
938
|
+
* When broker assigns the timestamps (LOG_APPEND_TIME) it will
|
|
939
|
+
* assign the same timestamp for all messages in a MessageSet
|
|
940
|
+
* using MaxTimestamp.
|
|
941
|
+
*/
|
|
942
|
+
if ((msetr->msetr_v2_hdr->Attributes &
|
|
943
|
+
RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME) ||
|
|
944
|
+
(hdr.MsgAttributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME)) {
|
|
945
|
+
rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
|
|
946
|
+
rkm->rkm_timestamp = msetr->msetr_v2_hdr->MaxTimestamp;
|
|
947
|
+
} else {
|
|
948
|
+
rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_CREATE_TIME;
|
|
949
|
+
rkm->rkm_timestamp =
|
|
950
|
+
msetr->msetr_v2_hdr->BaseTimestamp + hdr.TimestampDelta;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
/* Enqueue message on temporary queue */
|
|
955
|
+
rd_kafka_q_enq(&msetr->msetr_rkq, rko);
|
|
956
|
+
msetr->msetr_msgcnt++;
|
|
957
|
+
msetr->msetr_msg_bytes += rkm->rkm_key_len + rkm->rkm_len;
|
|
958
|
+
|
|
959
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
960
|
+
|
|
961
|
+
err_parse:
|
|
962
|
+
/* Count all parse errors as partial message errors. */
|
|
963
|
+
rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
|
|
964
|
+
return rkbuf->rkbuf_err;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* @brief Read v2 messages from current buffer position.
|
|
970
|
+
*/
|
|
971
|
+
static rd_kafka_resp_err_t
|
|
972
|
+
rd_kafka_msgset_reader_msgs_v2(rd_kafka_msgset_reader_t *msetr) {
|
|
973
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
974
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
975
|
+
/* Only log decoding errors if protocol debugging enabled. */
|
|
976
|
+
int log_decode_errors =
|
|
977
|
+
(rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
|
|
978
|
+
? LOG_DEBUG
|
|
979
|
+
: 0;
|
|
980
|
+
|
|
981
|
+
if (msetr->msetr_aborted_txns != NULL &&
|
|
982
|
+
(msetr->msetr_v2_hdr->Attributes &
|
|
983
|
+
(RD_KAFKA_MSGSET_V2_ATTR_TRANSACTIONAL |
|
|
984
|
+
RD_KAFKA_MSGSET_V2_ATTR_CONTROL)) ==
|
|
985
|
+
RD_KAFKA_MSGSET_V2_ATTR_TRANSACTIONAL) {
|
|
986
|
+
/* Transactional non-control MessageSet:
|
|
987
|
+
* check if it is part of an aborted transaction. */
|
|
988
|
+
int64_t txn_start_offset = rd_kafka_aborted_txns_get_offset(
|
|
989
|
+
msetr->msetr_aborted_txns, msetr->msetr_v2_hdr->PID);
|
|
990
|
+
|
|
991
|
+
if (txn_start_offset != -1 &&
|
|
992
|
+
msetr->msetr_v2_hdr->BaseOffset >= txn_start_offset) {
|
|
993
|
+
/* MessageSet is part of aborted transaction */
|
|
994
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG, "MSG",
|
|
995
|
+
"%s [%" PRId32
|
|
996
|
+
"]: "
|
|
997
|
+
"Skipping %" PRId32
|
|
998
|
+
" message(s) "
|
|
999
|
+
"in aborted transaction "
|
|
1000
|
+
"at offset %" PRId64 " for PID %" PRId64,
|
|
1001
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
1002
|
+
rktp->rktp_partition,
|
|
1003
|
+
msetr->msetr_v2_hdr->RecordCount,
|
|
1004
|
+
txn_start_offset, msetr->msetr_v2_hdr->PID);
|
|
1005
|
+
rd_kafka_buf_skip(
|
|
1006
|
+
msetr->msetr_rkbuf,
|
|
1007
|
+
rd_slice_remains(
|
|
1008
|
+
&msetr->msetr_rkbuf->rkbuf_reader));
|
|
1009
|
+
msetr->msetr_aborted_cnt++;
|
|
1010
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
while (rd_kafka_buf_read_remain(msetr->msetr_rkbuf)) {
|
|
1015
|
+
rd_kafka_resp_err_t err;
|
|
1016
|
+
err = rd_kafka_msgset_reader_msg_v2(msetr);
|
|
1017
|
+
if (unlikely(err))
|
|
1018
|
+
return err;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1022
|
+
|
|
1023
|
+
err_parse:
|
|
1024
|
+
/* Count all parse errors as partial message errors. */
|
|
1025
|
+
rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
|
|
1026
|
+
msetr->msetr_v2_hdr = NULL;
|
|
1027
|
+
return rkbuf->rkbuf_err;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* @brief MessageSet reader for MsgVersion v2 (FetchRequest v4)
|
|
1034
|
+
*/
|
|
1035
|
+
static rd_kafka_resp_err_t
|
|
1036
|
+
rd_kafka_msgset_reader_v2(rd_kafka_msgset_reader_t *msetr) {
|
|
1037
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
1038
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
1039
|
+
struct msgset_v2_hdr hdr;
|
|
1040
|
+
rd_slice_t save_slice;
|
|
1041
|
+
rd_kafka_resp_err_t err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1042
|
+
size_t len_start;
|
|
1043
|
+
size_t payload_size;
|
|
1044
|
+
int64_t LastOffset; /* Last absolute Offset in MessageSet header */
|
|
1045
|
+
/* Only log decoding errors if protocol debugging enabled. */
|
|
1046
|
+
int log_decode_errors =
|
|
1047
|
+
(rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
|
|
1048
|
+
? LOG_DEBUG
|
|
1049
|
+
: 0;
|
|
1050
|
+
|
|
1051
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.BaseOffset);
|
|
1052
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.Length);
|
|
1053
|
+
len_start = rd_slice_offset(&rkbuf->rkbuf_reader);
|
|
1054
|
+
|
|
1055
|
+
if (unlikely(hdr.Length < RD_KAFKAP_MSGSET_V2_SIZE - 8 - 4))
|
|
1056
|
+
rd_kafka_buf_parse_fail(rkbuf,
|
|
1057
|
+
"%s [%" PRId32
|
|
1058
|
+
"] "
|
|
1059
|
+
"MessageSet at offset %" PRId64
|
|
1060
|
+
" length %" PRId32 " < header size %d",
|
|
1061
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
1062
|
+
rktp->rktp_partition, hdr.BaseOffset,
|
|
1063
|
+
hdr.Length,
|
|
1064
|
+
RD_KAFKAP_MSGSET_V2_SIZE - 8 - 4);
|
|
1065
|
+
|
|
1066
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.PartitionLeaderEpoch);
|
|
1067
|
+
msetr->msetr_leader_epoch = hdr.PartitionLeaderEpoch;
|
|
1068
|
+
|
|
1069
|
+
rd_kafka_buf_read_i8(rkbuf, &hdr.MagicByte);
|
|
1070
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.Crc);
|
|
1071
|
+
|
|
1072
|
+
if (msetr->msetr_rkb->rkb_rk->rk_conf.check_crcs) {
|
|
1073
|
+
/* Verify CRC32C if desired. */
|
|
1074
|
+
uint32_t calc_crc;
|
|
1075
|
+
rd_slice_t crc_slice;
|
|
1076
|
+
size_t crc_len = hdr.Length - 4 - 1 - 4;
|
|
1077
|
+
|
|
1078
|
+
if (!rd_slice_narrow_copy_relative(&rkbuf->rkbuf_reader,
|
|
1079
|
+
&crc_slice, crc_len))
|
|
1080
|
+
rd_kafka_buf_check_len(rkbuf, crc_len);
|
|
1081
|
+
|
|
1082
|
+
calc_crc = rd_slice_crc32c(&crc_slice);
|
|
1083
|
+
|
|
1084
|
+
if (unlikely((uint32_t)hdr.Crc != calc_crc)) {
|
|
1085
|
+
/* Propagate CRC error to application and
|
|
1086
|
+
* continue with next message. */
|
|
1087
|
+
rd_kafka_consumer_err(
|
|
1088
|
+
&msetr->msetr_rkq, msetr->msetr_broker_id,
|
|
1089
|
+
RD_KAFKA_RESP_ERR__BAD_MSG,
|
|
1090
|
+
msetr->msetr_tver->version, NULL, rktp,
|
|
1091
|
+
hdr.BaseOffset,
|
|
1092
|
+
"MessageSet at offset %" PRId64 " (%" PRId32
|
|
1093
|
+
" bytes) "
|
|
1094
|
+
"failed CRC32C check "
|
|
1095
|
+
"(original 0x%" PRIx32
|
|
1096
|
+
" != "
|
|
1097
|
+
"calculated 0x%" PRIx32 ")",
|
|
1098
|
+
hdr.BaseOffset, hdr.Length, hdr.Crc, calc_crc);
|
|
1099
|
+
rd_kafka_buf_skip_to(rkbuf, crc_len);
|
|
1100
|
+
rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_err, 1);
|
|
1101
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
rd_kafka_buf_read_i16(rkbuf, &hdr.Attributes);
|
|
1106
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.LastOffsetDelta);
|
|
1107
|
+
LastOffset = hdr.BaseOffset + hdr.LastOffsetDelta;
|
|
1108
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.BaseTimestamp);
|
|
1109
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.MaxTimestamp);
|
|
1110
|
+
rd_kafka_buf_read_i64(rkbuf, &hdr.PID);
|
|
1111
|
+
rd_kafka_buf_read_i16(rkbuf, &hdr.ProducerEpoch);
|
|
1112
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.BaseSequence);
|
|
1113
|
+
rd_kafka_buf_read_i32(rkbuf, &hdr.RecordCount);
|
|
1114
|
+
|
|
1115
|
+
/* Payload size is hdr.Length - MessageSet headers */
|
|
1116
|
+
payload_size =
|
|
1117
|
+
hdr.Length - (rd_slice_offset(&rkbuf->rkbuf_reader) - len_start);
|
|
1118
|
+
|
|
1119
|
+
if (unlikely(payload_size > rd_kafka_buf_read_remain(rkbuf)))
|
|
1120
|
+
rd_kafka_buf_underflow_fail(
|
|
1121
|
+
rkbuf, payload_size,
|
|
1122
|
+
"%s [%" PRId32
|
|
1123
|
+
"] "
|
|
1124
|
+
"MessageSet at offset %" PRId64 " payload size %" PRIusz,
|
|
1125
|
+
rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
|
|
1126
|
+
hdr.BaseOffset, payload_size);
|
|
1127
|
+
|
|
1128
|
+
/* If entire MessageSet contains old outdated offsets, skip it. */
|
|
1129
|
+
if (LastOffset < rktp->rktp_offsets.fetch_pos.offset) {
|
|
1130
|
+
rd_kafka_buf_skip(rkbuf, payload_size);
|
|
1131
|
+
goto done;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
if (hdr.Attributes & RD_KAFKA_MSGSET_V2_ATTR_CONTROL)
|
|
1135
|
+
msetr->msetr_ctrl_cnt++;
|
|
1136
|
+
|
|
1137
|
+
msetr->msetr_v2_hdr = &hdr;
|
|
1138
|
+
|
|
1139
|
+
/* Handle compressed MessageSet */
|
|
1140
|
+
if (hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK) {
|
|
1141
|
+
const void *compressed;
|
|
1142
|
+
|
|
1143
|
+
compressed =
|
|
1144
|
+
rd_slice_ensure_contig(&rkbuf->rkbuf_reader, payload_size);
|
|
1145
|
+
rd_assert(compressed);
|
|
1146
|
+
|
|
1147
|
+
err = rd_kafka_msgset_reader_decompress(
|
|
1148
|
+
msetr, 2 /*MsgVersion v2*/, hdr.Attributes,
|
|
1149
|
+
hdr.BaseTimestamp, hdr.BaseOffset, compressed,
|
|
1150
|
+
payload_size);
|
|
1151
|
+
if (err)
|
|
1152
|
+
goto err;
|
|
1153
|
+
|
|
1154
|
+
} else {
|
|
1155
|
+
/* Read uncompressed messages */
|
|
1156
|
+
|
|
1157
|
+
/* Save original slice, reduce size of the current one to
|
|
1158
|
+
* be limited by the MessageSet.Length, and then start reading
|
|
1159
|
+
* messages until the lesser slice is exhausted. */
|
|
1160
|
+
if (!rd_slice_narrow_relative(&rkbuf->rkbuf_reader, &save_slice,
|
|
1161
|
+
payload_size))
|
|
1162
|
+
rd_kafka_buf_check_len(rkbuf, payload_size);
|
|
1163
|
+
|
|
1164
|
+
/* Read messages */
|
|
1165
|
+
err = rd_kafka_msgset_reader_msgs_v2(msetr);
|
|
1166
|
+
|
|
1167
|
+
/* Restore wider slice */
|
|
1168
|
+
rd_slice_widen(&rkbuf->rkbuf_reader, &save_slice);
|
|
1169
|
+
|
|
1170
|
+
if (unlikely(err))
|
|
1171
|
+
goto err;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
done:
|
|
1176
|
+
/* Set the next fetch offset to the MessageSet header's last offset + 1
|
|
1177
|
+
* to avoid getting stuck on compacted MessageSets where the last
|
|
1178
|
+
* Message in the MessageSet has an Offset < MessageSet header's
|
|
1179
|
+
* last offset. See KAFKA-5443 */
|
|
1180
|
+
msetr->msetr_next_offset = LastOffset + 1;
|
|
1181
|
+
|
|
1182
|
+
msetr->msetr_v2_hdr = NULL;
|
|
1183
|
+
|
|
1184
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1185
|
+
|
|
1186
|
+
err_parse:
|
|
1187
|
+
/* Count all parse errors as partial message errors. */
|
|
1188
|
+
rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
|
|
1189
|
+
err = rkbuf->rkbuf_err;
|
|
1190
|
+
/* FALLTHRU */
|
|
1191
|
+
err:
|
|
1192
|
+
msetr->msetr_v2_hdr = NULL;
|
|
1193
|
+
return err;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
/**
|
|
1198
|
+
* @brief Peek into the next MessageSet to find the MsgVersion.
|
|
1199
|
+
*
|
|
1200
|
+
* @param MagicBytep the MsgVersion is returned here on success.
|
|
1201
|
+
*
|
|
1202
|
+
* @returns an error on read underflow or if the MsgVersion is
|
|
1203
|
+
* unsupported.
|
|
1204
|
+
*/
|
|
1205
|
+
static rd_kafka_resp_err_t
|
|
1206
|
+
rd_kafka_msgset_reader_peek_msg_version(rd_kafka_msgset_reader_t *msetr,
|
|
1207
|
+
int8_t *MagicBytep) {
|
|
1208
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
1209
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
1210
|
+
/* Only log decoding errors if protocol debugging enabled. */
|
|
1211
|
+
int log_decode_errors =
|
|
1212
|
+
(rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
|
|
1213
|
+
? LOG_DEBUG
|
|
1214
|
+
: 0;
|
|
1215
|
+
size_t read_offset = rd_slice_offset(&rkbuf->rkbuf_reader);
|
|
1216
|
+
|
|
1217
|
+
rd_kafka_buf_peek_i8(rkbuf, read_offset + 8 + 4 + 4, MagicBytep);
|
|
1218
|
+
|
|
1219
|
+
if (unlikely(*MagicBytep < 0 || *MagicBytep > 2)) {
|
|
1220
|
+
int64_t Offset; /* For error logging */
|
|
1221
|
+
int32_t Length;
|
|
1222
|
+
|
|
1223
|
+
rd_kafka_buf_read_i64(rkbuf, &Offset);
|
|
1224
|
+
|
|
1225
|
+
rd_rkb_dbg(msetr->msetr_rkb,
|
|
1226
|
+
MSG | RD_KAFKA_DBG_PROTOCOL | RD_KAFKA_DBG_FETCH,
|
|
1227
|
+
"MAGICBYTE",
|
|
1228
|
+
"%s [%" PRId32
|
|
1229
|
+
"]: "
|
|
1230
|
+
"Unsupported Message(Set) MagicByte %d at "
|
|
1231
|
+
"offset %" PRId64
|
|
1232
|
+
" "
|
|
1233
|
+
"(buffer position %" PRIusz "/%" PRIusz
|
|
1234
|
+
"): skipping",
|
|
1235
|
+
rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
|
|
1236
|
+
(int)*MagicBytep, Offset, read_offset,
|
|
1237
|
+
rd_slice_size(&rkbuf->rkbuf_reader));
|
|
1238
|
+
|
|
1239
|
+
if (Offset >=
|
|
1240
|
+
msetr->msetr_rktp->rktp_offsets.fetch_pos.offset) {
|
|
1241
|
+
rd_kafka_consumer_err(
|
|
1242
|
+
&msetr->msetr_rkq, msetr->msetr_broker_id,
|
|
1243
|
+
RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED,
|
|
1244
|
+
msetr->msetr_tver->version, NULL, rktp, Offset,
|
|
1245
|
+
"Unsupported Message(Set) MagicByte %d "
|
|
1246
|
+
"at offset %" PRId64,
|
|
1247
|
+
(int)*MagicBytep, Offset);
|
|
1248
|
+
/* Skip message(set) */
|
|
1249
|
+
msetr->msetr_rktp->rktp_offsets.fetch_pos.offset =
|
|
1250
|
+
Offset + 1;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/* Skip this Message(Set).
|
|
1254
|
+
* If the message is malformed, the skip may trigger err_parse
|
|
1255
|
+
* and return ERR__BAD_MSG. */
|
|
1256
|
+
rd_kafka_buf_read_i32(rkbuf, &Length);
|
|
1257
|
+
rd_kafka_buf_skip(rkbuf, Length);
|
|
1258
|
+
|
|
1259
|
+
return RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1263
|
+
|
|
1264
|
+
err_parse:
|
|
1265
|
+
return RD_KAFKA_RESP_ERR__BAD_MSG;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* @brief Parse and read messages from msgset reader buffer.
|
|
1271
|
+
*/
|
|
1272
|
+
static rd_kafka_resp_err_t
|
|
1273
|
+
rd_kafka_msgset_reader(rd_kafka_msgset_reader_t *msetr) {
|
|
1274
|
+
rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
|
|
1275
|
+
rd_kafka_resp_err_t (*reader[])(rd_kafka_msgset_reader_t *) = {
|
|
1276
|
+
/* Indexed by MsgVersion/MagicByte, pointing to
|
|
1277
|
+
* a Msg(Set)Version reader */
|
|
1278
|
+
[0] = rd_kafka_msgset_reader_msg_v0_1,
|
|
1279
|
+
[1] = rd_kafka_msgset_reader_msg_v0_1,
|
|
1280
|
+
[2] = rd_kafka_msgset_reader_v2};
|
|
1281
|
+
rd_kafka_resp_err_t err;
|
|
1282
|
+
|
|
1283
|
+
/* Parse MessageSets until the slice is exhausted or an
|
|
1284
|
+
* error occurs (typically a partial message). */
|
|
1285
|
+
do {
|
|
1286
|
+
int8_t MagicByte;
|
|
1287
|
+
|
|
1288
|
+
/* We dont know the MsgVersion at this point, peek where the
|
|
1289
|
+
* MagicByte resides both in MsgVersion v0..1 and v2 to
|
|
1290
|
+
* know which MessageSet reader to use. */
|
|
1291
|
+
err =
|
|
1292
|
+
rd_kafka_msgset_reader_peek_msg_version(msetr, &MagicByte);
|
|
1293
|
+
if (unlikely(err)) {
|
|
1294
|
+
if (err == RD_KAFKA_RESP_ERR__BAD_MSG)
|
|
1295
|
+
/* Read underflow, not an error.
|
|
1296
|
+
* Broker may return a partial Fetch response
|
|
1297
|
+
* due to its use of sendfile(2). */
|
|
1298
|
+
return RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1299
|
+
|
|
1300
|
+
/* Continue on unsupported MsgVersions, the
|
|
1301
|
+
* MessageSet will be skipped. */
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
/* Use MsgVersion-specific reader */
|
|
1306
|
+
err = reader[(int)MagicByte](msetr);
|
|
1307
|
+
|
|
1308
|
+
} while (!err && rd_slice_remains(&rkbuf->rkbuf_reader) > 0);
|
|
1309
|
+
|
|
1310
|
+
return err;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* @brief MessageSet post-processing.
|
|
1317
|
+
*
|
|
1318
|
+
* @param last_offsetp will be set to the offset of the last message in the set,
|
|
1319
|
+
* or -1 if not applicable.
|
|
1320
|
+
*/
|
|
1321
|
+
static void rd_kafka_msgset_reader_postproc(rd_kafka_msgset_reader_t *msetr,
|
|
1322
|
+
int64_t *last_offsetp) {
|
|
1323
|
+
rd_kafka_op_t *rko;
|
|
1324
|
+
|
|
1325
|
+
rko = rd_kafka_q_last(&msetr->msetr_rkq, RD_KAFKA_OP_FETCH,
|
|
1326
|
+
0 /* no error ops */);
|
|
1327
|
+
if (rko) {
|
|
1328
|
+
*last_offsetp = rko->rko_u.fetch.rkm.rkm_offset;
|
|
1329
|
+
|
|
1330
|
+
if (*last_offsetp != -1 && msetr->msetr_relative_offsets) {
|
|
1331
|
+
/* Update messages to absolute offsets
|
|
1332
|
+
* and purge any messages older than the current
|
|
1333
|
+
* fetch offset. */
|
|
1334
|
+
rd_kafka_q_fix_offsets(
|
|
1335
|
+
&msetr->msetr_rkq,
|
|
1336
|
+
msetr->msetr_rktp->rktp_offsets.fetch_pos.offset,
|
|
1337
|
+
msetr->msetr_outer.offset - *last_offsetp);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
/**
|
|
1345
|
+
* @brief Run the MessageSet reader, read messages until buffer is
|
|
1346
|
+
* exhausted (or error encountered), enqueue parsed messages on
|
|
1347
|
+
* partition queue.
|
|
1348
|
+
*
|
|
1349
|
+
* @returns RD_KAFKA_RESP_ERR_NO_ERROR if MessageSet was successfully
|
|
1350
|
+
* or partially parsed. When other error codes are returned it
|
|
1351
|
+
* indicates a semi-permanent error (such as unsupported MsgVersion)
|
|
1352
|
+
* and the fetcher should back off this partition to avoid
|
|
1353
|
+
* busy-looping.
|
|
1354
|
+
*/
|
|
1355
|
+
static rd_kafka_resp_err_t
|
|
1356
|
+
rd_kafka_msgset_reader_run(rd_kafka_msgset_reader_t *msetr) {
|
|
1357
|
+
rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
|
|
1358
|
+
rd_kafka_resp_err_t err;
|
|
1359
|
+
int64_t last_offset = -1;
|
|
1360
|
+
|
|
1361
|
+
/* Parse MessageSets and messages */
|
|
1362
|
+
err = rd_kafka_msgset_reader(msetr);
|
|
1363
|
+
|
|
1364
|
+
if (unlikely(rd_kafka_q_len(&msetr->msetr_rkq) == 0)) {
|
|
1365
|
+
/* The message set didn't contain at least one full message
|
|
1366
|
+
* or no error was posted on the response queue.
|
|
1367
|
+
* This means the size limit perhaps was too tight,
|
|
1368
|
+
* increase it automatically.
|
|
1369
|
+
* If there was at least one control message there
|
|
1370
|
+
* is probably not a size limit and nothing is done.
|
|
1371
|
+
* If there were aborted messagesets and no underflow then
|
|
1372
|
+
* there is no error either (#2993).
|
|
1373
|
+
*
|
|
1374
|
+
* Also; avoid propagating underflow errors, which cause
|
|
1375
|
+
* backoffs, since we'll want to continue fetching the
|
|
1376
|
+
* remaining truncated messages as soon as possible.
|
|
1377
|
+
*/
|
|
1378
|
+
if (msetr->msetr_ctrl_cnt > 0) {
|
|
1379
|
+
/* Noop */
|
|
1380
|
+
if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
|
|
1381
|
+
err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1382
|
+
|
|
1383
|
+
} else if (rktp->rktp_fetch_msg_max_bytes < (1 << 30)) {
|
|
1384
|
+
rktp->rktp_fetch_msg_max_bytes *= 2;
|
|
1385
|
+
rd_rkb_dbg(msetr->msetr_rkb, FETCH, "CONSUME",
|
|
1386
|
+
"Topic %s [%" PRId32
|
|
1387
|
+
"]: Increasing "
|
|
1388
|
+
"max fetch bytes to %" PRId32,
|
|
1389
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
1390
|
+
rktp->rktp_partition,
|
|
1391
|
+
rktp->rktp_fetch_msg_max_bytes);
|
|
1392
|
+
|
|
1393
|
+
if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
|
|
1394
|
+
err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1395
|
+
|
|
1396
|
+
} else if (!err && msetr->msetr_aborted_cnt == 0) {
|
|
1397
|
+
rd_kafka_consumer_err(
|
|
1398
|
+
&msetr->msetr_rkq, msetr->msetr_broker_id,
|
|
1399
|
+
RD_KAFKA_RESP_ERR_MSG_SIZE_TOO_LARGE,
|
|
1400
|
+
msetr->msetr_tver->version, NULL, rktp,
|
|
1401
|
+
rktp->rktp_offsets.fetch_pos.offset,
|
|
1402
|
+
"Message at offset %" PRId64
|
|
1403
|
+
" might be too large to fetch, try increasing "
|
|
1404
|
+
"receive.message.max.bytes",
|
|
1405
|
+
rktp->rktp_offsets.fetch_pos.offset);
|
|
1406
|
+
|
|
1407
|
+
} else if (msetr->msetr_aborted_cnt > 0) {
|
|
1408
|
+
/* Noop */
|
|
1409
|
+
if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
|
|
1410
|
+
err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
} else {
|
|
1414
|
+
/* MessageSet post-processing. */
|
|
1415
|
+
rd_kafka_msgset_reader_postproc(msetr, &last_offset);
|
|
1416
|
+
|
|
1417
|
+
/* Ignore parse errors if there was at least one
|
|
1418
|
+
* good message since it probably indicates a
|
|
1419
|
+
* partial response rather than an erroneous one. */
|
|
1420
|
+
if (err == RD_KAFKA_RESP_ERR__UNDERFLOW &&
|
|
1421
|
+
msetr->msetr_msgcnt > 0)
|
|
1422
|
+
err = RD_KAFKA_RESP_ERR_NO_ERROR;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
rd_rkb_dbg(msetr->msetr_rkb, MSG | RD_KAFKA_DBG_FETCH, "CONSUME",
|
|
1426
|
+
"Enqueue %i %smessage(s) (%" PRId64
|
|
1427
|
+
" bytes, %d ops) on %s [%" PRId32
|
|
1428
|
+
"] fetch queue (qlen %d, v%d, last_offset %" PRId64
|
|
1429
|
+
", %d ctrl msgs, %d aborted msgsets, %s)",
|
|
1430
|
+
msetr->msetr_msgcnt, msetr->msetr_srcname,
|
|
1431
|
+
msetr->msetr_msg_bytes, rd_kafka_q_len(&msetr->msetr_rkq),
|
|
1432
|
+
rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
|
|
1433
|
+
rd_kafka_q_len(msetr->msetr_par_rkq),
|
|
1434
|
+
msetr->msetr_tver->version, last_offset,
|
|
1435
|
+
msetr->msetr_ctrl_cnt, msetr->msetr_aborted_cnt,
|
|
1436
|
+
msetr->msetr_compression
|
|
1437
|
+
? rd_kafka_compression2str(msetr->msetr_compression)
|
|
1438
|
+
: "uncompressed");
|
|
1439
|
+
|
|
1440
|
+
/* Concat all messages&errors onto the parent's queue
|
|
1441
|
+
* (the partition's fetch queue) */
|
|
1442
|
+
if (rd_kafka_q_concat(msetr->msetr_par_rkq, &msetr->msetr_rkq) != -1) {
|
|
1443
|
+
/* Update partition's fetch offset based on
|
|
1444
|
+
* last message's offest. */
|
|
1445
|
+
if (likely(last_offset != -1))
|
|
1446
|
+
rktp->rktp_offsets.fetch_pos.offset = last_offset + 1;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/* Adjust next fetch offset if outlier code has indicated
|
|
1450
|
+
* an even later next offset. */
|
|
1451
|
+
if (msetr->msetr_next_offset > rktp->rktp_offsets.fetch_pos.offset)
|
|
1452
|
+
rktp->rktp_offsets.fetch_pos.offset = msetr->msetr_next_offset;
|
|
1453
|
+
|
|
1454
|
+
rktp->rktp_offsets.fetch_pos.leader_epoch = msetr->msetr_leader_epoch;
|
|
1455
|
+
|
|
1456
|
+
rd_kafka_q_destroy_owner(&msetr->msetr_rkq);
|
|
1457
|
+
|
|
1458
|
+
/* Skip remaining part of slice so caller can continue
|
|
1459
|
+
* with next partition. */
|
|
1460
|
+
rd_slice_read(&msetr->msetr_rkbuf->rkbuf_reader, NULL,
|
|
1461
|
+
rd_slice_remains(&msetr->msetr_rkbuf->rkbuf_reader));
|
|
1462
|
+
return err;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
/**
|
|
1468
|
+
* @brief Parse one MessageSet at the current buffer read position,
|
|
1469
|
+
* enqueueing messages, propagating errors, etc.
|
|
1470
|
+
* @remark The current rkbuf_reader slice must be limited to the MessageSet size
|
|
1471
|
+
*
|
|
1472
|
+
* @returns see rd_kafka_msgset_reader_run()
|
|
1473
|
+
*/
|
|
1474
|
+
rd_kafka_resp_err_t
|
|
1475
|
+
rd_kafka_msgset_parse(rd_kafka_buf_t *rkbuf,
|
|
1476
|
+
rd_kafka_buf_t *request,
|
|
1477
|
+
rd_kafka_toppar_t *rktp,
|
|
1478
|
+
rd_kafka_aborted_txns_t *aborted_txns,
|
|
1479
|
+
const struct rd_kafka_toppar_ver *tver) {
|
|
1480
|
+
rd_kafka_msgset_reader_t msetr;
|
|
1481
|
+
rd_kafka_resp_err_t err;
|
|
1482
|
+
|
|
1483
|
+
rd_kafka_msgset_reader_init(&msetr, rkbuf, rktp, tver, aborted_txns,
|
|
1484
|
+
rktp->rktp_fetchq);
|
|
1485
|
+
|
|
1486
|
+
/* Parse and handle the message set */
|
|
1487
|
+
err = rd_kafka_msgset_reader_run(&msetr);
|
|
1488
|
+
|
|
1489
|
+
rd_atomic64_add(&rktp->rktp_c.rx_msgs, msetr.msetr_msgcnt);
|
|
1490
|
+
rd_atomic64_add(&rktp->rktp_c.rx_msg_bytes, msetr.msetr_msg_bytes);
|
|
1491
|
+
|
|
1492
|
+
rd_avg_add(&rktp->rktp_rkt->rkt_avg_batchcnt,
|
|
1493
|
+
(int64_t)msetr.msetr_msgcnt);
|
|
1494
|
+
rd_avg_add(&rktp->rktp_rkt->rkt_avg_batchsize,
|
|
1495
|
+
(int64_t)msetr.msetr_msg_bytes);
|
|
1496
|
+
|
|
1497
|
+
return err;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* @brief Offset comparator
|
|
1503
|
+
*/
|
|
1504
|
+
static int rd_kafka_offset_cmp(const void *_a, const void *_b) {
|
|
1505
|
+
const int64_t *a = _a, *b = _b;
|
|
1506
|
+
return (*a > *b) - (*a < *b);
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
/**
|
|
1511
|
+
* @brief Pid comparator for rd_kafka_aborted_txn_start_offsets_t
|
|
1512
|
+
*/
|
|
1513
|
+
static int rd_kafka_aborted_txn_cmp_by_pid(const void *_a, const void *_b) {
|
|
1514
|
+
const rd_kafka_aborted_txn_start_offsets_t *a = _a, *b = _b;
|
|
1515
|
+
return (a->pid > b->pid) - (a->pid < b->pid);
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
|
|
1519
|
+
/**
|
|
1520
|
+
* @brief Free resources associated with an AVL tree node.
|
|
1521
|
+
*/
|
|
1522
|
+
static void rd_kafka_aborted_txn_node_destroy(void *_node_ptr) {
|
|
1523
|
+
rd_kafka_aborted_txn_start_offsets_t *node_ptr = _node_ptr;
|
|
1524
|
+
rd_list_destroy(&node_ptr->offsets);
|
|
1525
|
+
rd_free(node_ptr);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
|
|
1529
|
+
/**
|
|
1530
|
+
* @brief Allocate memory for, and initialize a new
|
|
1531
|
+
* rd_kafka_aborted_txns_t struct.
|
|
1532
|
+
*/
|
|
1533
|
+
rd_kafka_aborted_txns_t *rd_kafka_aborted_txns_new(int32_t txn_cnt) {
|
|
1534
|
+
rd_kafka_aborted_txns_t *aborted_txns;
|
|
1535
|
+
aborted_txns = rd_malloc(sizeof(*aborted_txns));
|
|
1536
|
+
rd_avl_init(&aborted_txns->avl, rd_kafka_aborted_txn_cmp_by_pid, 0);
|
|
1537
|
+
rd_list_init(&aborted_txns->list, txn_cnt,
|
|
1538
|
+
rd_kafka_aborted_txn_node_destroy);
|
|
1539
|
+
aborted_txns->cnt = txn_cnt;
|
|
1540
|
+
return aborted_txns;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
/**
|
|
1545
|
+
* @brief Free all resources associated with a
|
|
1546
|
+
* rd_kafka_aborted_txns_t struct.
|
|
1547
|
+
*/
|
|
1548
|
+
void rd_kafka_aborted_txns_destroy(rd_kafka_aborted_txns_t *aborted_txns) {
|
|
1549
|
+
rd_list_destroy(&aborted_txns->list);
|
|
1550
|
+
rd_avl_destroy(&aborted_txns->avl);
|
|
1551
|
+
rd_free(aborted_txns);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
/**
|
|
1556
|
+
* @brief Get the abort txn start offsets corresponding to
|
|
1557
|
+
* the specified pid.
|
|
1558
|
+
*/
|
|
1559
|
+
static RD_INLINE rd_kafka_aborted_txn_start_offsets_t *
|
|
1560
|
+
rd_kafka_aborted_txns_offsets_for_pid(rd_kafka_aborted_txns_t *aborted_txns,
|
|
1561
|
+
int64_t pid) {
|
|
1562
|
+
rd_kafka_aborted_txn_start_offsets_t node;
|
|
1563
|
+
node.pid = pid;
|
|
1564
|
+
return RD_AVL_FIND(&aborted_txns->avl, &node);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* @brief Get the next aborted transaction start
|
|
1570
|
+
* offset for the specified pid.
|
|
1571
|
+
*
|
|
1572
|
+
* @param increment_idx if true, the offset index will be incremented.
|
|
1573
|
+
* @param max_offset If the next aborted offset is greater than \p max_offset
|
|
1574
|
+
* then the index is not incremented (regardless of
|
|
1575
|
+
* \p increment_idx) and the function returns -1.
|
|
1576
|
+
* This may be the case for empty aborted transactions
|
|
1577
|
+
* that have an ABORT marker but are not listed in the
|
|
1578
|
+
* AbortedTxns list.
|
|
1579
|
+
*
|
|
1580
|
+
*
|
|
1581
|
+
* @returns the start offset or -1 if there is none.
|
|
1582
|
+
*/
|
|
1583
|
+
static int64_t
|
|
1584
|
+
rd_kafka_aborted_txns_next_offset(rd_kafka_aborted_txns_t *aborted_txns,
|
|
1585
|
+
int64_t pid,
|
|
1586
|
+
rd_bool_t increment_idx,
|
|
1587
|
+
int64_t max_offset) {
|
|
1588
|
+
int64_t abort_start_offset;
|
|
1589
|
+
rd_kafka_aborted_txn_start_offsets_t *node_ptr =
|
|
1590
|
+
rd_kafka_aborted_txns_offsets_for_pid(aborted_txns, pid);
|
|
1591
|
+
|
|
1592
|
+
if (node_ptr == NULL)
|
|
1593
|
+
return -1;
|
|
1594
|
+
|
|
1595
|
+
if (unlikely(node_ptr->offsets_idx >= rd_list_cnt(&node_ptr->offsets)))
|
|
1596
|
+
return -1;
|
|
1597
|
+
|
|
1598
|
+
abort_start_offset = *(
|
|
1599
|
+
(int64_t *)rd_list_elem(&node_ptr->offsets, node_ptr->offsets_idx));
|
|
1600
|
+
|
|
1601
|
+
if (unlikely(abort_start_offset > max_offset))
|
|
1602
|
+
return -1;
|
|
1603
|
+
|
|
1604
|
+
if (increment_idx)
|
|
1605
|
+
node_ptr->offsets_idx++;
|
|
1606
|
+
|
|
1607
|
+
return abort_start_offset;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
|
|
1611
|
+
/**
|
|
1612
|
+
* @brief Get the next aborted transaction start
|
|
1613
|
+
* offset for the specified pid and progress the
|
|
1614
|
+
* current index to the next one.
|
|
1615
|
+
*
|
|
1616
|
+
* @param max_offset If the next aborted offset is greater than \p max_offset
|
|
1617
|
+
* then no offset is popped and the function returns -1.
|
|
1618
|
+
* This may be the case for empty aborted transactions
|
|
1619
|
+
* that have an ABORT marker but are not listed in the
|
|
1620
|
+
* AbortedTxns list.
|
|
1621
|
+
*
|
|
1622
|
+
* @returns the start offset or -1 if there is none.
|
|
1623
|
+
*/
|
|
1624
|
+
static RD_INLINE int64_t
|
|
1625
|
+
rd_kafka_aborted_txns_pop_offset(rd_kafka_aborted_txns_t *aborted_txns,
|
|
1626
|
+
int64_t pid,
|
|
1627
|
+
int64_t max_offset) {
|
|
1628
|
+
return rd_kafka_aborted_txns_next_offset(aborted_txns, pid, rd_true,
|
|
1629
|
+
max_offset);
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* @brief Get the next aborted transaction start
|
|
1635
|
+
* offset for the specified pid.
|
|
1636
|
+
*
|
|
1637
|
+
* @returns the start offset or -1 if there is none.
|
|
1638
|
+
*/
|
|
1639
|
+
static RD_INLINE int64_t
|
|
1640
|
+
rd_kafka_aborted_txns_get_offset(const rd_kafka_aborted_txns_t *aborted_txns,
|
|
1641
|
+
int64_t pid) {
|
|
1642
|
+
return rd_kafka_aborted_txns_next_offset(
|
|
1643
|
+
(rd_kafka_aborted_txns_t *)aborted_txns, pid, rd_false, INT64_MAX);
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* @brief Add a transaction start offset corresponding
|
|
1649
|
+
* to the specified pid to the aborted_txns collection.
|
|
1650
|
+
*/
|
|
1651
|
+
void rd_kafka_aborted_txns_add(rd_kafka_aborted_txns_t *aborted_txns,
|
|
1652
|
+
int64_t pid,
|
|
1653
|
+
int64_t first_offset) {
|
|
1654
|
+
int64_t *v;
|
|
1655
|
+
rd_kafka_aborted_txn_start_offsets_t *node_ptr =
|
|
1656
|
+
rd_kafka_aborted_txns_offsets_for_pid(aborted_txns, pid);
|
|
1657
|
+
|
|
1658
|
+
if (!node_ptr) {
|
|
1659
|
+
node_ptr = rd_malloc(sizeof(*node_ptr));
|
|
1660
|
+
node_ptr->pid = pid;
|
|
1661
|
+
node_ptr->offsets_idx = 0;
|
|
1662
|
+
rd_list_init(&node_ptr->offsets, 0, NULL);
|
|
1663
|
+
/* Each PID list has no more than AbortedTxnCnt elements */
|
|
1664
|
+
rd_list_prealloc_elems(&node_ptr->offsets, sizeof(int64_t),
|
|
1665
|
+
aborted_txns->cnt, 0);
|
|
1666
|
+
RD_AVL_INSERT(&aborted_txns->avl, node_ptr, avl_node);
|
|
1667
|
+
rd_list_add(&aborted_txns->list, node_ptr);
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
v = rd_list_add(&node_ptr->offsets, NULL);
|
|
1671
|
+
*v = first_offset;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
/**
|
|
1676
|
+
* @brief Sort each of the abort transaction start
|
|
1677
|
+
* offset lists for each pid.
|
|
1678
|
+
*/
|
|
1679
|
+
void rd_kafka_aborted_txns_sort(rd_kafka_aborted_txns_t *aborted_txns) {
|
|
1680
|
+
int k;
|
|
1681
|
+
for (k = 0; k < rd_list_cnt(&aborted_txns->list); k++) {
|
|
1682
|
+
rd_kafka_aborted_txn_start_offsets_t *el =
|
|
1683
|
+
rd_list_elem(&aborted_txns->list, k);
|
|
1684
|
+
rd_list_sort(&el->offsets, rd_kafka_offset_cmp);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
/**
|
|
1690
|
+
* @brief Unit tests for all functions that operate on
|
|
1691
|
+
* rd_kafka_aborted_txns_t
|
|
1692
|
+
*/
|
|
1693
|
+
int unittest_aborted_txns(void) {
|
|
1694
|
+
rd_kafka_aborted_txns_t *aborted_txns = NULL;
|
|
1695
|
+
int64_t start_offset;
|
|
1696
|
+
|
|
1697
|
+
aborted_txns = rd_kafka_aborted_txns_new(7);
|
|
1698
|
+
rd_kafka_aborted_txns_add(aborted_txns, 1, 42);
|
|
1699
|
+
rd_kafka_aborted_txns_add(aborted_txns, 1, 44);
|
|
1700
|
+
rd_kafka_aborted_txns_add(aborted_txns, 1, 10);
|
|
1701
|
+
rd_kafka_aborted_txns_add(aborted_txns, 1, 100);
|
|
1702
|
+
rd_kafka_aborted_txns_add(aborted_txns, 2, 11);
|
|
1703
|
+
rd_kafka_aborted_txns_add(aborted_txns, 2, 7);
|
|
1704
|
+
rd_kafka_aborted_txns_add(aborted_txns, 1, 3);
|
|
1705
|
+
rd_kafka_aborted_txns_sort(aborted_txns);
|
|
1706
|
+
|
|
1707
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1708
|
+
RD_UT_ASSERT(3 == start_offset,
|
|
1709
|
+
"queried start offset was %" PRId64
|
|
1710
|
+
", "
|
|
1711
|
+
"expected 3",
|
|
1712
|
+
start_offset);
|
|
1713
|
+
|
|
1714
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1715
|
+
RD_UT_ASSERT(3 == start_offset,
|
|
1716
|
+
"queried start offset was %" PRId64
|
|
1717
|
+
", "
|
|
1718
|
+
"expected 3",
|
|
1719
|
+
start_offset);
|
|
1720
|
+
|
|
1721
|
+
start_offset =
|
|
1722
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
|
|
1723
|
+
RD_UT_ASSERT(3 == start_offset,
|
|
1724
|
+
"queried start offset was %" PRId64
|
|
1725
|
+
", "
|
|
1726
|
+
"expected 3",
|
|
1727
|
+
start_offset);
|
|
1728
|
+
|
|
1729
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1730
|
+
RD_UT_ASSERT(10 == start_offset,
|
|
1731
|
+
"queried start offset was %" PRId64
|
|
1732
|
+
", "
|
|
1733
|
+
"expected 10",
|
|
1734
|
+
start_offset);
|
|
1735
|
+
|
|
1736
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
|
|
1737
|
+
RD_UT_ASSERT(7 == start_offset,
|
|
1738
|
+
"queried start offset was %" PRId64
|
|
1739
|
+
", "
|
|
1740
|
+
"expected 7",
|
|
1741
|
+
start_offset);
|
|
1742
|
+
|
|
1743
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
|
|
1744
|
+
|
|
1745
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1746
|
+
RD_UT_ASSERT(42 == start_offset,
|
|
1747
|
+
"queried start offset was %" PRId64
|
|
1748
|
+
", "
|
|
1749
|
+
"expected 42",
|
|
1750
|
+
start_offset);
|
|
1751
|
+
|
|
1752
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
|
|
1753
|
+
|
|
1754
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1755
|
+
RD_UT_ASSERT(44 == start_offset,
|
|
1756
|
+
"queried start offset was %" PRId64
|
|
1757
|
+
", "
|
|
1758
|
+
"expected 44",
|
|
1759
|
+
start_offset);
|
|
1760
|
+
|
|
1761
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
|
|
1762
|
+
RD_UT_ASSERT(7 == start_offset,
|
|
1763
|
+
"queried start offset was %" PRId64
|
|
1764
|
+
", "
|
|
1765
|
+
"expected 7",
|
|
1766
|
+
start_offset);
|
|
1767
|
+
|
|
1768
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 2, INT64_MAX);
|
|
1769
|
+
|
|
1770
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
|
|
1771
|
+
RD_UT_ASSERT(11 == start_offset,
|
|
1772
|
+
"queried start offset was %" PRId64
|
|
1773
|
+
", "
|
|
1774
|
+
"expected 11",
|
|
1775
|
+
start_offset);
|
|
1776
|
+
|
|
1777
|
+
/* error cases */
|
|
1778
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 3);
|
|
1779
|
+
RD_UT_ASSERT(-1 == start_offset,
|
|
1780
|
+
"queried start offset was %" PRId64
|
|
1781
|
+
", "
|
|
1782
|
+
"expected -1",
|
|
1783
|
+
start_offset);
|
|
1784
|
+
|
|
1785
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
|
|
1786
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
|
|
1787
|
+
rd_kafka_aborted_txns_pop_offset(aborted_txns, 2, INT64_MAX);
|
|
1788
|
+
|
|
1789
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
|
|
1790
|
+
RD_UT_ASSERT(-1 == start_offset,
|
|
1791
|
+
"queried start offset was %" PRId64
|
|
1792
|
+
", "
|
|
1793
|
+
"expected -1",
|
|
1794
|
+
start_offset);
|
|
1795
|
+
|
|
1796
|
+
start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
|
|
1797
|
+
RD_UT_ASSERT(-1 == start_offset,
|
|
1798
|
+
"queried start offset was %" PRId64
|
|
1799
|
+
", "
|
|
1800
|
+
"expected -1",
|
|
1801
|
+
start_offset);
|
|
1802
|
+
|
|
1803
|
+
rd_kafka_aborted_txns_destroy(aborted_txns);
|
|
1804
|
+
|
|
1805
|
+
RD_UT_PASS();
|
|
1806
|
+
}
|