@platformatic/rdkafka 4.0.1 → 4.1.0
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/README.md +5 -5
- package/bench/seed.sh +0 -0
- package/binding.gyp +8 -1
- package/ci/prepublish.js +0 -1
- package/config.d.ts +126 -10
- package/configure +0 -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 +67 -44
- package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
- package/deps/librdkafka/CHANGELOG.md +471 -1
- package/deps/librdkafka/CONFIGURATION.md +29 -9
- package/deps/librdkafka/INTRODUCTION.md +909 -601
- package/deps/librdkafka/LICENSES.txt +592 -1
- package/deps/librdkafka/Makefile +2 -1
- package/deps/librdkafka/_mkltmpuuWEwa.c +13 -0
- package/deps/librdkafka/configure +0 -0
- package/deps/librdkafka/debian/rules +0 -0
- package/deps/librdkafka/dev-conf.sh +0 -0
- package/deps/librdkafka/examples/consumer.c +18 -8
- package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
- package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
- package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
- package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
- package/deps/librdkafka/examples/producer.cpp +2 -2
- package/deps/librdkafka/examples/user_scram.c +4 -5
- package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
- package/deps/librdkafka/lds-gen.py +0 -0
- package/deps/librdkafka/mklove/Makefile.base +0 -0
- package/deps/librdkafka/packaging/RELEASE.md +8 -0
- package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
- package/deps/librdkafka/packaging/cp/README.md +4 -1
- package/deps/librdkafka/packaging/cp/check_features.c +12 -4
- package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
- package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
- package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
- package/deps/librdkafka/packaging/debian/rules +0 -0
- package/deps/librdkafka/packaging/get_version.py +0 -0
- package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
- package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
- package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
- package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
- package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
- package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
- package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
- package/deps/librdkafka/packaging/nuget/release.py +0 -0
- package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
- package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
- package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
- package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
- package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
- package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
- package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
- package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -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 +6 -5
- package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
- package/deps/librdkafka/service.yml +154 -0
- package/deps/librdkafka/src/generate_proto.sh +0 -0
- package/deps/librdkafka/src/rd.h +145 -2
- package/deps/librdkafka/src/rdaddr.h +6 -7
- package/deps/librdkafka/src/rdatomic.h +15 -11
- package/deps/librdkafka/src/rdavg.h +3 -2
- package/deps/librdkafka/src/rdbase64.c +33 -2
- package/deps/librdkafka/src/rdbase64.h +2 -0
- package/deps/librdkafka/src/rdendian.h +10 -9
- package/deps/librdkafka/src/rdhttp.c +418 -100
- package/deps/librdkafka/src/rdhttp.h +23 -5
- package/deps/librdkafka/src/rdkafka.c +299 -145
- package/deps/librdkafka/src/rdkafka.h +89 -6
- package/deps/librdkafka/src/rdkafka_admin.c +482 -105
- package/deps/librdkafka/src/rdkafka_admin.h +42 -0
- package/deps/librdkafka/src/rdkafka_broker.c +463 -312
- package/deps/librdkafka/src/rdkafka_broker.h +68 -10
- package/deps/librdkafka/src/rdkafka_buf.c +8 -5
- package/deps/librdkafka/src/rdkafka_buf.h +4 -3
- package/deps/librdkafka/src/rdkafka_cert.c +25 -1
- package/deps/librdkafka/src/rdkafka_cert.h +4 -3
- package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
- package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
- package/deps/librdkafka/src/rdkafka_conf.c +526 -102
- package/deps/librdkafka/src/rdkafka_conf.h +68 -4
- package/deps/librdkafka/src/rdkafka_feature.c +472 -35
- package/deps/librdkafka/src/rdkafka_feature.h +2 -0
- package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
- package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
- package/deps/librdkafka/src/rdkafka_int.h +84 -46
- package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
- package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
- package/deps/librdkafka/src/rdkafka_mock.c +795 -19
- package/deps/librdkafka/src/rdkafka_mock.h +119 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
- package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
- package/deps/librdkafka/src/rdkafka_msg.c +35 -19
- package/deps/librdkafka/src/rdkafka_msg.h +3 -3
- package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
- package/deps/librdkafka/src/rdkafka_offset.c +33 -5
- package/deps/librdkafka/src/rdkafka_op.c +1 -1
- package/deps/librdkafka/src/rdkafka_op.h +45 -21
- package/deps/librdkafka/src/rdkafka_partition.c +118 -23
- package/deps/librdkafka/src/rdkafka_partition.h +16 -7
- package/deps/librdkafka/src/rdkafka_proto.h +4 -1
- package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
- package/deps/librdkafka/src/rdkafka_queue.c +125 -48
- package/deps/librdkafka/src/rdkafka_queue.h +19 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
- package/deps/librdkafka/src/rdkafka_request.c +336 -64
- package/deps/librdkafka/src/rdkafka_request.h +24 -1
- package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
- package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
- package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
- package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
- package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
- package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
- package/deps/librdkafka/src/rdkafka_topic.c +220 -137
- package/deps/librdkafka/src/rdkafka_topic.h +14 -8
- package/deps/librdkafka/src/rdkafka_transport.c +59 -47
- package/deps/librdkafka/src/rdkafka_transport.h +5 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
- package/deps/librdkafka/src/rdmap.c +6 -1
- package/deps/librdkafka/src/rdrand.c +11 -1
- package/deps/librdkafka/src/rdtime.h +48 -17
- package/deps/librdkafka/src/rdunittest.c +42 -25
- package/deps/librdkafka/src/rdunittest.h +2 -0
- package/deps/librdkafka/src/rdwin32.h +1 -1
- package/deps/librdkafka/src/regexp.c +47 -42
- package/deps/librdkafka/src/tinycthread_extra.c +45 -21
- package/deps/librdkafka/src/tinycthread_extra.h +7 -3
- package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
- package/deps/librdkafka/tests/0001-multiobj.c +4 -0
- package/deps/librdkafka/tests/0004-conf.c +103 -36
- package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
- package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
- package/deps/librdkafka/tests/0016-client_swname.c +18 -3
- package/deps/librdkafka/tests/0017-compression.c +6 -8
- package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
- package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
- package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
- package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
- package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
- package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
- package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
- package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
- package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
- package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
- package/deps/librdkafka/tests/0038-performance.c +1 -0
- package/deps/librdkafka/tests/0040-io_event.c +11 -5
- package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
- package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
- package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
- package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
- package/deps/librdkafka/tests/0048-partitioner.c +1 -1
- package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
- package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
- package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
- package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
- package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
- package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
- package/deps/librdkafka/tests/0058-log.cpp +3 -3
- package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
- package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
- package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
- package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
- package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
- package/deps/librdkafka/tests/0075-retry.c +38 -1
- package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
- package/deps/librdkafka/tests/0077-compaction.c +8 -2
- package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
- package/deps/librdkafka/tests/0081-admin.c +455 -155
- package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
- package/deps/librdkafka/tests/0083-cb_event.c +8 -3
- package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
- package/deps/librdkafka/tests/0085-headers.cpp +4 -0
- package/deps/librdkafka/tests/0086-purge.c +40 -7
- package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
- package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
- package/deps/librdkafka/tests/0090-idempotence.c +1 -2
- package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
- package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
- package/deps/librdkafka/tests/0093-holb.c +8 -5
- package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
- package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
- package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
- package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
- package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
- package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
- package/deps/librdkafka/tests/0103-transactions.c +7 -7
- package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
- package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
- package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
- package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
- package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
- package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
- package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
- package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
- package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
- package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
- package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
- package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
- package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
- package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
- package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
- package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
- package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
- package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
- package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
- package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
- package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
- package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
- package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
- package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
- package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
- 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 +9 -6
- 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/CMakeLists.txt +6 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
- package/deps/librdkafka/tests/autotest.sh +0 -0
- package/deps/librdkafka/tests/broker_version_tests.py +0 -0
- package/deps/librdkafka/tests/buildbox.sh +0 -0
- package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
- package/deps/librdkafka/tests/cluster_testing.py +0 -0
- package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
- package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -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 +42 -101
- package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
- package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
- package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
- package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
- package/deps/librdkafka/tests/java/Makefile +2 -1
- package/deps/librdkafka/tests/java/run-class.sh +0 -0
- package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
- package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
- package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
- package/deps/librdkafka/tests/performance_plot.py +0 -0
- package/deps/librdkafka/tests/requirements.txt +1 -1
- package/deps/librdkafka/tests/run-all-tests.sh +79 -0
- package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
- package/deps/librdkafka/tests/run-test-batches.py +157 -0
- package/deps/librdkafka/tests/run-test.sh +0 -0
- package/deps/librdkafka/tests/sasl_test.py +0 -0
- package/deps/librdkafka/tests/test.c +478 -18
- package/deps/librdkafka/tests/test.h +62 -13
- package/deps/librdkafka/tests/testcpp.cpp +6 -1
- package/deps/librdkafka/tests/testcpp.h +30 -2
- package/deps/librdkafka/tests/testshared.h +16 -2
- package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
- package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
- package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
- package/deps/librdkafka/tests/until-fail.sh +0 -0
- package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
- package/deps/librdkafka/vcpkg.json +1 -1
- package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
- package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
- package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
- package/deps/librdkafka/win32/wingetopt.h +5 -4
- package/errors.d.ts +27 -1
- package/lib/error.js +29 -3
- package/make_docs.sh +0 -0
- package/package.json +11 -11
- package/run_docker.sh +0 -0
- package/src/callbacks.cc +6 -9
- package/src/callbacks.h +1 -5
- package/test/kafka-consumer-worker.js +10 -7
- package/test/kafka-consumer.spec.js +32 -21
- package/ci/update-version.js +0 -123
- package/deps/librdkafka/.semaphore/project.yml +0 -43
- package/deps/librdkafka/.semaphore/project_public.yml +0 -20
- package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
|
@@ -82,9 +82,9 @@
|
|
|
82
82
|
static const int rd_kafka_max_block_ms = 1000;
|
|
83
83
|
|
|
84
84
|
const char *rd_kafka_broker_state_names[] = {
|
|
85
|
-
"INIT",
|
|
86
|
-
"AUTH_LEGACY", "UP",
|
|
87
|
-
"AUTH_REQ", "REAUTH"};
|
|
85
|
+
"INIT", "DOWN", "TRY_CONNECT", "CONNECT",
|
|
86
|
+
"SSL_HANDSHAKE", "AUTH_LEGACY", "UP", "APIVERSION_QUERY",
|
|
87
|
+
"AUTH_HANDSHAKE", "AUTH_REQ", "REAUTH"};
|
|
88
88
|
|
|
89
89
|
const char *rd_kafka_secproto_names[] = {
|
|
90
90
|
[RD_KAFKA_PROTO_PLAINTEXT] = "plaintext",
|
|
@@ -111,7 +111,6 @@ rd_kafka_broker_needs_persistent_connection(rd_kafka_broker_t *rkb) {
|
|
|
111
111
|
rd_atomic32_get(&rkb->rkb_persistconn.coord);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
|
|
115
114
|
/**
|
|
116
115
|
* @returns > 0 if a connection to this broker is needed, else 0.
|
|
117
116
|
* @locality broker thread
|
|
@@ -119,7 +118,7 @@ rd_kafka_broker_needs_persistent_connection(rd_kafka_broker_t *rkb) {
|
|
|
119
118
|
*/
|
|
120
119
|
static RD_INLINE int rd_kafka_broker_needs_connection(rd_kafka_broker_t *rkb) {
|
|
121
120
|
return rkb->rkb_state == RD_KAFKA_BROKER_STATE_INIT &&
|
|
122
|
-
!
|
|
121
|
+
!rd_kafka_broker_or_instance_terminating(rkb) &&
|
|
123
122
|
!rd_kafka_fatal_error_code(rkb->rkb_rk) &&
|
|
124
123
|
(!rkb->rkb_rk->rk_conf.sparse_connections ||
|
|
125
124
|
rd_kafka_broker_needs_persistent_connection(rkb));
|
|
@@ -311,6 +310,32 @@ int16_t rd_kafka_broker_ApiVersion_supported(rd_kafka_broker_t *rkb,
|
|
|
311
310
|
rkb, ApiKey, minver, maxver, featuresp, rd_true /* do_lock */);
|
|
312
311
|
}
|
|
313
312
|
|
|
313
|
+
/**
|
|
314
|
+
* @brief Check that at least a ApiVersion greater or equal to
|
|
315
|
+
* \p minver exists for \p ApiKey.
|
|
316
|
+
*
|
|
317
|
+
* @returns `rd_true` if the broker supports \p ApiKey with
|
|
318
|
+
* a version greater than or equal to \p minver, else `rd_false`.
|
|
319
|
+
* @locks none
|
|
320
|
+
* @locks_acquired rd_kafka_broker_lock()
|
|
321
|
+
* @locality any
|
|
322
|
+
*/
|
|
323
|
+
rd_bool_t rd_kafka_broker_ApiVersion_at_least(rd_kafka_broker_t *rkb,
|
|
324
|
+
int16_t ApiKey,
|
|
325
|
+
int16_t minver) {
|
|
326
|
+
return rd_kafka_broker_ApiVersion_supported0(
|
|
327
|
+
rkb, ApiKey, minver, RD_KAFKAP_RPC_VERSION_MAX, NULL,
|
|
328
|
+
rd_true /* do_lock */) != -1;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
rd_bool_t rd_kafka_broker_ApiVersion_at_least_no_lock(rd_kafka_broker_t *rkb,
|
|
332
|
+
int16_t ApiKey,
|
|
333
|
+
int16_t minver) {
|
|
334
|
+
return rd_kafka_broker_ApiVersion_supported0(
|
|
335
|
+
rkb, ApiKey, minver, RD_KAFKAP_RPC_VERSION_MAX, NULL,
|
|
336
|
+
rd_false /* don't lock rkb */) != -1;
|
|
337
|
+
}
|
|
338
|
+
|
|
314
339
|
/**
|
|
315
340
|
* @brief Set broker state.
|
|
316
341
|
*
|
|
@@ -321,7 +346,9 @@ int16_t rd_kafka_broker_ApiVersion_supported(rd_kafka_broker_t *rkb,
|
|
|
321
346
|
* @locality broker thread
|
|
322
347
|
*/
|
|
323
348
|
void rd_kafka_broker_set_state(rd_kafka_broker_t *rkb, int state) {
|
|
324
|
-
rd_bool_t trigger_monitors
|
|
349
|
+
rd_bool_t trigger_monitors = rd_false,
|
|
350
|
+
reset_any_broker_down_reported = rd_false,
|
|
351
|
+
skip_broker_down = rkb->rkb_c.skip_broker_down;
|
|
325
352
|
|
|
326
353
|
if ((int)rkb->rkb_state == state)
|
|
327
354
|
return;
|
|
@@ -331,57 +358,70 @@ void rd_kafka_broker_set_state(rd_kafka_broker_t *rkb, int state) {
|
|
|
331
358
|
rd_kafka_broker_state_names[rkb->rkb_state],
|
|
332
359
|
rd_kafka_broker_state_names[state]);
|
|
333
360
|
|
|
334
|
-
if (
|
|
361
|
+
if (rd_kafka_broker_state_is_down(state) && skip_broker_down)
|
|
362
|
+
/* Reset the flag so if it disconnects again it won't be
|
|
363
|
+
* treated as a planned disconnection. */
|
|
364
|
+
rkb->rkb_c.skip_broker_down = rd_false;
|
|
365
|
+
|
|
366
|
+
if (rkb->rkb_source == RD_KAFKA_INTERNAL ||
|
|
367
|
+
RD_KAFKA_BROKER_IS_LOGICAL(rkb)) {
|
|
335
368
|
/* no-op */
|
|
336
|
-
} else if (state
|
|
337
|
-
|
|
369
|
+
} else if (rd_kafka_broker_state_is_down(state) && !skip_broker_down &&
|
|
370
|
+
/* Only 0 -> 1 */
|
|
371
|
+
rd_atomic32_set(&rkb->rkb_down_reported, 1) == 0) {
|
|
372
|
+
|
|
338
373
|
/* Propagate ALL_BROKERS_DOWN event if all brokers are
|
|
339
|
-
* now down, unless we're terminating.
|
|
340
|
-
* Only trigger for brokers that has an address set,
|
|
341
|
-
* e.g., not logical brokers that lost their address. */
|
|
374
|
+
* now down, unless we're terminating. */
|
|
342
375
|
if (rd_atomic32_add(&rkb->rkb_rk->rk_broker_down_cnt, 1) ==
|
|
343
376
|
rd_atomic32_get(&rkb->rkb_rk->rk_broker_cnt) -
|
|
344
377
|
rd_atomic32_get(
|
|
345
|
-
&rkb->rkb_rk->
|
|
346
|
-
!
|
|
347
|
-
|
|
378
|
+
&rkb->rkb_rk->rk_logical_broker_cnt) &&
|
|
379
|
+
!rd_kafka_terminating(rkb->rkb_rk)) {
|
|
380
|
+
rd_kafka_rebootstrap(rkb->rkb_rk);
|
|
348
381
|
rd_kafka_op_err(
|
|
349
382
|
rkb->rkb_rk, RD_KAFKA_RESP_ERR__ALL_BROKERS_DOWN,
|
|
350
383
|
"%i/%i brokers are down",
|
|
351
384
|
rd_atomic32_get(&rkb->rkb_rk->rk_broker_down_cnt),
|
|
352
385
|
rd_atomic32_get(&rkb->rkb_rk->rk_broker_cnt) -
|
|
353
386
|
rd_atomic32_get(
|
|
354
|
-
&rkb->rkb_rk->
|
|
355
|
-
|
|
387
|
+
&rkb->rkb_rk->rk_logical_broker_cnt));
|
|
388
|
+
}
|
|
356
389
|
|
|
357
390
|
} else if (rd_kafka_broker_state_is_up(state) &&
|
|
358
|
-
|
|
391
|
+
/* Only 1 -> 0 */
|
|
392
|
+
rd_atomic32_set(&rkb->rkb_down_reported, 0) == 1) {
|
|
359
393
|
rd_atomic32_sub(&rkb->rkb_rk->rk_broker_down_cnt, 1);
|
|
360
|
-
rkb->rkb_down_reported = 0;
|
|
361
394
|
}
|
|
362
395
|
|
|
363
396
|
if (rkb->rkb_source != RD_KAFKA_INTERNAL) {
|
|
364
397
|
if (rd_kafka_broker_state_is_up(state) &&
|
|
365
398
|
!rd_kafka_broker_state_is_up(rkb->rkb_state)) {
|
|
366
|
-
/* Up ->
|
|
367
|
-
|
|
399
|
+
/* ~Up -> Up */
|
|
400
|
+
if (!RD_KAFKA_BROKER_IS_LOGICAL(rkb)) {
|
|
401
|
+
rd_atomic32_add(&rkb->rkb_rk->rk_broker_up_cnt,
|
|
402
|
+
1);
|
|
403
|
+
|
|
404
|
+
/* If at least one broker connects we reset
|
|
405
|
+
* the down counter to try again with rest of
|
|
406
|
+
* brokers. Otherwise, a single broker
|
|
407
|
+
* connection can cause `ALL_BROKERS_DOWN` to
|
|
408
|
+
* get triggered even if the connection to rest
|
|
409
|
+
* of brokers was restored but they didn't
|
|
410
|
+
* attempt a re-connection because of sparse
|
|
411
|
+
* broker connections. */
|
|
412
|
+
reset_any_broker_down_reported = rd_true;
|
|
413
|
+
}
|
|
368
414
|
|
|
369
415
|
trigger_monitors = rd_true;
|
|
370
416
|
|
|
371
|
-
if (RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
372
|
-
rd_atomic32_add(
|
|
373
|
-
&rkb->rkb_rk->rk_logical_broker_up_cnt, 1);
|
|
374
|
-
|
|
375
417
|
} else if (rd_kafka_broker_state_is_up(rkb->rkb_state) &&
|
|
376
418
|
!rd_kafka_broker_state_is_up(state)) {
|
|
377
|
-
/*
|
|
378
|
-
|
|
419
|
+
/* Up -> Down */
|
|
420
|
+
if (!RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
421
|
+
rd_atomic32_sub(&rkb->rkb_rk->rk_broker_up_cnt,
|
|
422
|
+
1);
|
|
379
423
|
|
|
380
424
|
trigger_monitors = rd_true;
|
|
381
|
-
|
|
382
|
-
if (RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
383
|
-
rd_atomic32_sub(
|
|
384
|
-
&rkb->rkb_rk->rk_logical_broker_up_cnt, 1);
|
|
385
425
|
}
|
|
386
426
|
|
|
387
427
|
/* If the connection or connection attempt failed and there
|
|
@@ -397,6 +437,14 @@ void rd_kafka_broker_set_state(rd_kafka_broker_t *rkb, int state) {
|
|
|
397
437
|
rkb->rkb_state = state;
|
|
398
438
|
rkb->rkb_ts_state = rd_clock();
|
|
399
439
|
|
|
440
|
+
if (reset_any_broker_down_reported) {
|
|
441
|
+
rd_kafka_broker_unlock(rkb);
|
|
442
|
+
/* Releases rkb->rkb_lock to respect
|
|
443
|
+
* lock ordering and avoid deadlocks */
|
|
444
|
+
rd_kafka_reset_any_broker_down_reported(rkb->rkb_rk);
|
|
445
|
+
rd_kafka_broker_lock(rkb);
|
|
446
|
+
}
|
|
447
|
+
|
|
400
448
|
if (trigger_monitors)
|
|
401
449
|
rd_kafka_broker_trigger_monitors(rkb);
|
|
402
450
|
|
|
@@ -456,34 +504,31 @@ static void rd_kafka_broker_set_error(rd_kafka_broker_t *rkb,
|
|
|
456
504
|
|
|
457
505
|
/* Provide more meaningful error messages in certain cases */
|
|
458
506
|
if (err == RD_KAFKA_RESP_ERR__TRANSPORT &&
|
|
459
|
-
|
|
507
|
+
rd_kafka_transport_error_disconnected(fmt)) {
|
|
460
508
|
if (rkb->rkb_state == RD_KAFKA_BROKER_STATE_APIVERSION_QUERY) {
|
|
461
509
|
/* A disconnect while requesting ApiVersion typically
|
|
462
510
|
* means we're connecting to a SSL-listener as
|
|
463
511
|
* PLAINTEXT, but may also be caused by connecting to
|
|
464
512
|
* a broker that does not support ApiVersion (<0.10). */
|
|
465
|
-
|
|
466
513
|
if (rkb->rkb_proto != RD_KAFKA_PROTO_SSL &&
|
|
467
|
-
rkb->rkb_proto != RD_KAFKA_PROTO_SASL_SSL)
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
"
|
|
514
|
+
rkb->rkb_proto != RD_KAFKA_PROTO_SASL_SSL) {
|
|
515
|
+
ofe = rd_snprintf(
|
|
516
|
+
errstr + of, sizeof(errstr) - of, "%s",
|
|
517
|
+
": requesting "
|
|
471
518
|
"ApiVersion: "
|
|
472
519
|
"might be caused by incorrect "
|
|
473
520
|
"security.protocol configuration "
|
|
474
521
|
"(connecting to a SSL listener?) or "
|
|
475
522
|
"broker version is < 0.10 "
|
|
476
|
-
"(see api.version.request)"
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
"Disconnected while requesting "
|
|
523
|
+
"(see api.version.request)");
|
|
524
|
+
} else {
|
|
525
|
+
ofe = rd_snprintf(
|
|
526
|
+
errstr + of, sizeof(errstr) - of, "%s",
|
|
527
|
+
": requesting "
|
|
482
528
|
"ApiVersion: "
|
|
483
529
|
"might be caused by broker version "
|
|
484
|
-
"< 0.10 (see api.version.request)"
|
|
485
|
-
|
|
486
|
-
return;
|
|
530
|
+
"< 0.10 (see api.version.request)");
|
|
531
|
+
}
|
|
487
532
|
|
|
488
533
|
} else if (rkb->rkb_state == RD_KAFKA_BROKER_STATE_UP &&
|
|
489
534
|
state_duration_ms < 2000 /*2s*/ &&
|
|
@@ -491,18 +536,20 @@ static void rd_kafka_broker_set_error(rd_kafka_broker_t *rkb,
|
|
|
491
536
|
RD_KAFKA_PROTO_SASL_SSL &&
|
|
492
537
|
rkb->rkb_rk->rk_conf.security_protocol !=
|
|
493
538
|
RD_KAFKA_PROTO_SASL_PLAINTEXT) {
|
|
539
|
+
|
|
494
540
|
/* If disconnected shortly after transitioning to UP
|
|
495
541
|
* state it typically means the broker listener is
|
|
496
542
|
* configured for SASL authentication but the client
|
|
497
543
|
* is not. */
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
ap /*ignored*/);
|
|
504
|
-
return;
|
|
544
|
+
ofe =
|
|
545
|
+
rd_snprintf(errstr + of, sizeof(errstr) - of, "%s",
|
|
546
|
+
": verify that security.protocol "
|
|
547
|
+
"is correctly configured, broker might "
|
|
548
|
+
"require SASL authentication");
|
|
505
549
|
}
|
|
550
|
+
if (ofe > sizeof(errstr) - of)
|
|
551
|
+
ofe = sizeof(errstr) - of;
|
|
552
|
+
of += ofe;
|
|
506
553
|
}
|
|
507
554
|
|
|
508
555
|
/* Check if error is identical to last error (prior to appending
|
|
@@ -554,13 +601,14 @@ static void rd_kafka_broker_set_error(rd_kafka_broker_t *rkb,
|
|
|
554
601
|
identical ? ": identical to last error" : "",
|
|
555
602
|
suppress ? ": error log suppressed" : "");
|
|
556
603
|
|
|
557
|
-
if (level
|
|
604
|
+
if (level <= LOG_CRIT || (level <= LOG_INFO && !suppress)) {
|
|
558
605
|
rd_kafka_log(rkb->rkb_rk, level, "FAIL", "%s: %s",
|
|
559
606
|
rkb->rkb_name, errstr);
|
|
560
607
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
608
|
+
if (level <= LOG_ERR)
|
|
609
|
+
/* Send ERR op to application for processing. */
|
|
610
|
+
rd_kafka_q_op_err(rkb->rkb_rk->rk_rep, err, "%s: %s",
|
|
611
|
+
rkb->rkb_name, errstr);
|
|
564
612
|
}
|
|
565
613
|
}
|
|
566
614
|
|
|
@@ -692,6 +740,13 @@ void rd_kafka_broker_fail(rd_kafka_broker_t *rkb,
|
|
|
692
740
|
|
|
693
741
|
if (rktp->rktp_leader_id != rktp->rktp_broker_id) {
|
|
694
742
|
rd_kafka_toppar_delegate_to_leader(rktp);
|
|
743
|
+
} else if (rd_kafka_broker_termination_in_progress(rkb)) {
|
|
744
|
+
/* Remove `rktp_broker` and `rktp_leader`
|
|
745
|
+
* references in `rktp`, even if this broker
|
|
746
|
+
* is still the leader, to allow to
|
|
747
|
+
* decommission it. */
|
|
748
|
+
rd_kafka_toppar_undelegate(rktp);
|
|
749
|
+
rd_kafka_toppar_forget_leader(rktp);
|
|
695
750
|
}
|
|
696
751
|
}
|
|
697
752
|
|
|
@@ -710,12 +765,18 @@ void rd_kafka_broker_fail(rd_kafka_broker_t *rkb,
|
|
|
710
765
|
|
|
711
766
|
/* Query for topic leaders to quickly pick up on failover. */
|
|
712
767
|
if (err != RD_KAFKA_RESP_ERR__DESTROY &&
|
|
768
|
+
err != RD_KAFKA_RESP_ERR__DESTROY_BROKER &&
|
|
713
769
|
old_state >= RD_KAFKA_BROKER_STATE_UP)
|
|
714
770
|
rd_kafka_metadata_refresh_known_topics(
|
|
715
771
|
rkb->rkb_rk, NULL, rd_true /*force*/, "broker down");
|
|
716
772
|
}
|
|
717
773
|
|
|
718
774
|
|
|
775
|
+
#define rd_kafka_broker_planned_fail(RKB, ERR, FMT, ...) \
|
|
776
|
+
do { \
|
|
777
|
+
(RKB)->rkb_c.skip_broker_down = rd_true; \
|
|
778
|
+
rd_kafka_broker_fail(RKB, LOG_DEBUG, ERR, FMT, __VA_ARGS__); \
|
|
779
|
+
} while (0)
|
|
719
780
|
|
|
720
781
|
/**
|
|
721
782
|
* @brief Handle broker connection close.
|
|
@@ -999,11 +1060,11 @@ static void rd_kafka_broker_timeout_scan(rd_kafka_broker_t *rkb, rd_ts_t now) {
|
|
|
999
1060
|
1000.0f));
|
|
1000
1061
|
else
|
|
1001
1062
|
rttinfo[0] = 0;
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1063
|
+
rd_kafka_broker_planned_fail(
|
|
1064
|
+
rkb, RD_KAFKA_RESP_ERR__TIMED_OUT,
|
|
1065
|
+
"%i request(s) timed out: "
|
|
1066
|
+
"disconnect%s",
|
|
1067
|
+
rkb->rkb_req_timeouts, rttinfo);
|
|
1007
1068
|
}
|
|
1008
1069
|
}
|
|
1009
1070
|
}
|
|
@@ -1042,8 +1103,9 @@ static int rd_kafka_broker_resolve(rd_kafka_broker_t *rkb,
|
|
|
1042
1103
|
int save_idx = 0;
|
|
1043
1104
|
|
|
1044
1105
|
if (!*nodename && rkb->rkb_source == RD_KAFKA_LOGICAL) {
|
|
1045
|
-
|
|
1046
|
-
|
|
1106
|
+
rd_kafka_broker_planned_fail(
|
|
1107
|
+
rkb, RD_KAFKA_RESP_ERR__RESOLVE, "%s",
|
|
1108
|
+
"Logical broker has no address yet");
|
|
1047
1109
|
return -1;
|
|
1048
1110
|
}
|
|
1049
1111
|
|
|
@@ -1403,12 +1465,13 @@ rd_kafka_broker_t *rd_kafka_broker_random0(const char *func,
|
|
|
1403
1465
|
int fcnt = 0;
|
|
1404
1466
|
|
|
1405
1467
|
TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
|
|
1406
|
-
if (
|
|
1468
|
+
if (rd_kafka_broker_or_instance_terminating(rkb) ||
|
|
1469
|
+
RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
1407
1470
|
continue;
|
|
1408
1471
|
|
|
1409
1472
|
rd_kafka_broker_lock(rkb);
|
|
1410
1473
|
if ((is_up && rd_kafka_broker_state_is_up(rkb->rkb_state)) ||
|
|
1411
|
-
(!is_up && (int)rkb->rkb_state == state)) {
|
|
1474
|
+
(!is_up && (state == -1 || (int)rkb->rkb_state == state))) {
|
|
1412
1475
|
if (filter && filter(rkb, opaque)) {
|
|
1413
1476
|
/* Filtered out */
|
|
1414
1477
|
fcnt++;
|
|
@@ -1459,6 +1522,8 @@ rd_kafka_broker_weighted(rd_kafka_t *rk,
|
|
|
1459
1522
|
|
|
1460
1523
|
TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
|
|
1461
1524
|
int weight;
|
|
1525
|
+
if (rd_kafka_broker_or_instance_terminating(rkb))
|
|
1526
|
+
continue;
|
|
1462
1527
|
|
|
1463
1528
|
rd_kafka_broker_lock(rkb);
|
|
1464
1529
|
if (features && (rkb->rkb_features & features) != features)
|
|
@@ -1512,12 +1577,11 @@ rd_kafka_broker_weighted(rd_kafka_t *rk,
|
|
|
1512
1577
|
static int rd_kafka_broker_weight_usable(rd_kafka_broker_t *rkb) {
|
|
1513
1578
|
int weight = 0;
|
|
1514
1579
|
|
|
1515
|
-
if (!rd_kafka_broker_state_is_up(rkb->rkb_state)
|
|
1580
|
+
if (!rd_kafka_broker_state_is_up(rkb->rkb_state) ||
|
|
1581
|
+
RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
1516
1582
|
return 0;
|
|
1517
1583
|
|
|
1518
|
-
weight +=
|
|
1519
|
-
2000 * (rkb->rkb_nodeid != -1 && !RD_KAFKA_BROKER_IS_LOGICAL(rkb));
|
|
1520
|
-
weight += 10 * !RD_KAFKA_BROKER_IS_LOGICAL(rkb);
|
|
1584
|
+
weight += 2000;
|
|
1521
1585
|
|
|
1522
1586
|
if (likely(!rd_atomic32_get(&rkb->rkb_blocking_request_cnt))) {
|
|
1523
1587
|
rd_ts_t tx_last = rd_atomic64_get(&rkb->rkb_c.ts_send);
|
|
@@ -1526,6 +1590,9 @@ static int rd_kafka_broker_weight_usable(rd_kafka_broker_t *rkb) {
|
|
|
1526
1590
|
1000000);
|
|
1527
1591
|
|
|
1528
1592
|
weight += 1; /* is not blocking */
|
|
1593
|
+
if (rkb->rkb_source == RD_KAFKA_LEARNED)
|
|
1594
|
+
/* Prefer learned brokers */
|
|
1595
|
+
weight += 1000;
|
|
1529
1596
|
|
|
1530
1597
|
/* Prefer least idle broker (based on last 10 minutes use) */
|
|
1531
1598
|
if (idle < 0)
|
|
@@ -1740,6 +1807,9 @@ rd_list_t *rd_kafka_brokers_get_nodeids_async(rd_kafka_t *rk,
|
|
|
1740
1807
|
}
|
|
1741
1808
|
i = 0;
|
|
1742
1809
|
TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
|
|
1810
|
+
if (rd_kafka_broker_or_instance_terminating(rkb))
|
|
1811
|
+
continue;
|
|
1812
|
+
|
|
1743
1813
|
rd_kafka_broker_lock(rkb);
|
|
1744
1814
|
if (rkb->rkb_nodeid != -1 &&
|
|
1745
1815
|
!RD_KAFKA_BROKER_IS_LOGICAL(rkb)) {
|
|
@@ -2098,7 +2168,7 @@ int rd_kafka_recv(rd_kafka_broker_t *rkb) {
|
|
|
2098
2168
|
err_parse:
|
|
2099
2169
|
err = rkbuf->rkbuf_err;
|
|
2100
2170
|
err:
|
|
2101
|
-
if (
|
|
2171
|
+
if (rd_kafka_transport_error_disconnected(errstr))
|
|
2102
2172
|
rd_kafka_broker_conn_closed(rkb, err, errstr);
|
|
2103
2173
|
else
|
|
2104
2174
|
rd_kafka_broker_fail(rkb, LOG_ERR, err, "Receive failed: %s",
|
|
@@ -2201,53 +2271,6 @@ rd_kafka_broker_reconnect_backoff(const rd_kafka_broker_t *rkb, rd_ts_t now) {
|
|
|
2201
2271
|
return (int)(remains / 1000);
|
|
2202
2272
|
}
|
|
2203
2273
|
|
|
2204
|
-
|
|
2205
|
-
/**
|
|
2206
|
-
* @brief Unittest for reconnect.backoff.ms
|
|
2207
|
-
*/
|
|
2208
|
-
static int rd_ut_reconnect_backoff(void) {
|
|
2209
|
-
rd_kafka_broker_t rkb = RD_ZERO_INIT;
|
|
2210
|
-
rd_kafka_conf_t conf = {.reconnect_backoff_ms = 10,
|
|
2211
|
-
.reconnect_backoff_max_ms = 90};
|
|
2212
|
-
rd_ts_t now = 1000000;
|
|
2213
|
-
int backoff;
|
|
2214
|
-
|
|
2215
|
-
rkb.rkb_reconnect_backoff_ms = conf.reconnect_backoff_ms;
|
|
2216
|
-
|
|
2217
|
-
/* broker's backoff is the initial reconnect.backoff.ms=10 */
|
|
2218
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2219
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2220
|
-
RD_UT_ASSERT_RANGE(backoff, 7, 15, "%d");
|
|
2221
|
-
|
|
2222
|
-
/* .. 20 */
|
|
2223
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2224
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2225
|
-
RD_UT_ASSERT_RANGE(backoff, 15, 30, "%d");
|
|
2226
|
-
|
|
2227
|
-
/* .. 40 */
|
|
2228
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2229
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2230
|
-
RD_UT_ASSERT_RANGE(backoff, 30, 60, "%d");
|
|
2231
|
-
|
|
2232
|
-
/* .. 80, the jitter is capped at reconnect.backoff.max.ms=90 */
|
|
2233
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2234
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2235
|
-
RD_UT_ASSERT_RANGE(backoff, 60, conf.reconnect_backoff_max_ms, "%d");
|
|
2236
|
-
|
|
2237
|
-
/* .. 90, capped by reconnect.backoff.max.ms */
|
|
2238
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2239
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2240
|
-
RD_UT_ASSERT_RANGE(backoff, 67, conf.reconnect_backoff_max_ms, "%d");
|
|
2241
|
-
|
|
2242
|
-
/* .. 90, should remain at capped value. */
|
|
2243
|
-
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
2244
|
-
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
2245
|
-
RD_UT_ASSERT_RANGE(backoff, 67, conf.reconnect_backoff_max_ms, "%d");
|
|
2246
|
-
|
|
2247
|
-
RD_UT_PASS();
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
2274
|
/**
|
|
2252
2275
|
* @brief Initiate asynchronous connection attempt to the next address
|
|
2253
2276
|
* in the broker's address list.
|
|
@@ -2337,6 +2360,7 @@ void rd_kafka_broker_connect_up(rd_kafka_broker_t *rkb) {
|
|
|
2337
2360
|
if (rd_kafka_broker_ApiVersion_supported(
|
|
2338
2361
|
rkb, RD_KAFKAP_GetTelemetrySubscriptions, 0, 0, &features) !=
|
|
2339
2362
|
-1 &&
|
|
2363
|
+
rkb->rkb_source == RD_KAFKA_LEARNED &&
|
|
2340
2364
|
rkb->rkb_rk->rk_conf.enable_metrics_push) {
|
|
2341
2365
|
rd_kafka_t *rk = rkb->rkb_rk;
|
|
2342
2366
|
rd_kafka_op_t *rko =
|
|
@@ -2370,7 +2394,7 @@ static void rd_kafka_broker_handle_SaslHandshake(rd_kafka_t *rk,
|
|
|
2370
2394
|
char *mechs = "(n/a)";
|
|
2371
2395
|
size_t msz, mof = 0;
|
|
2372
2396
|
|
|
2373
|
-
if (err
|
|
2397
|
+
if (rd_kafka_broker_is_any_err_destroy(err))
|
|
2374
2398
|
return;
|
|
2375
2399
|
|
|
2376
2400
|
if (err)
|
|
@@ -2549,7 +2573,7 @@ static void rd_kafka_broker_handle_ApiVersion(rd_kafka_t *rk,
|
|
|
2549
2573
|
size_t api_cnt = 0;
|
|
2550
2574
|
int16_t retry_ApiVersion = -1;
|
|
2551
2575
|
|
|
2552
|
-
if (err
|
|
2576
|
+
if (rd_kafka_broker_is_any_err_destroy(err))
|
|
2553
2577
|
return;
|
|
2554
2578
|
|
|
2555
2579
|
err = rd_kafka_handle_ApiVersion(rk, rkb, err, rkbuf, request, &apis,
|
|
@@ -2942,10 +2966,18 @@ void rd_kafka_broker_buf_retry(rd_kafka_broker_t *rkb, rd_kafka_buf_t *rkbuf) {
|
|
|
2942
2966
|
rd_atomic64_add(&rkb->rkb_c.tx_retries, 1);
|
|
2943
2967
|
/* In some cases, failed Produce requests do not increment the retry
|
|
2944
2968
|
* count, see rd_kafka_handle_Produce_error. */
|
|
2945
|
-
if (rkbuf->rkbuf_retries > 0)
|
|
2946
|
-
|
|
2969
|
+
if (rkbuf->rkbuf_retries > 0) {
|
|
2970
|
+
int shift = rkbuf->rkbuf_retries - 1;
|
|
2971
|
+
|
|
2972
|
+
/* Cap shift at 34 to prevent overflow in final calculation.
|
|
2973
|
+
* Accounts for multiplication by retry_backoff_ms (max 300000)
|
|
2974
|
+
* and jitter (max 1200). */
|
|
2975
|
+
if (shift > 34)
|
|
2976
|
+
shift = 34;
|
|
2977
|
+
|
|
2978
|
+
backoff = ((int64_t)1 << shift) *
|
|
2947
2979
|
(rkb->rkb_rk->rk_conf.retry_backoff_ms);
|
|
2948
|
-
else
|
|
2980
|
+
} else
|
|
2949
2981
|
backoff = rkb->rkb_rk->rk_conf.retry_backoff_ms;
|
|
2950
2982
|
|
|
2951
2983
|
/* We are multiplying by 10 as (backoff_ms * percent * 1000)/100 ->
|
|
@@ -3101,53 +3133,6 @@ void rd_kafka_dr_implicit_ack(rd_kafka_broker_t *rkb,
|
|
|
3101
3133
|
rd_kafka_dr_msgq(rktp->rktp_rkt, &acked, RD_KAFKA_RESP_ERR_NO_ERROR);
|
|
3102
3134
|
}
|
|
3103
3135
|
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
/**
|
|
3107
|
-
* @brief Map existing partitions to this broker using the
|
|
3108
|
-
* toppar's leader_id. Only undelegated partitions
|
|
3109
|
-
* matching this broker are mapped.
|
|
3110
|
-
*
|
|
3111
|
-
* @locks none
|
|
3112
|
-
* @locality any
|
|
3113
|
-
*/
|
|
3114
|
-
static void rd_kafka_broker_map_partitions(rd_kafka_broker_t *rkb) {
|
|
3115
|
-
rd_kafka_t *rk = rkb->rkb_rk;
|
|
3116
|
-
rd_kafka_topic_t *rkt;
|
|
3117
|
-
int cnt = 0;
|
|
3118
|
-
|
|
3119
|
-
if (rkb->rkb_nodeid == -1 || RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
3120
|
-
return;
|
|
3121
|
-
|
|
3122
|
-
rd_kafka_rdlock(rk);
|
|
3123
|
-
TAILQ_FOREACH(rkt, &rk->rk_topics, rkt_link) {
|
|
3124
|
-
int i;
|
|
3125
|
-
|
|
3126
|
-
rd_kafka_topic_wrlock(rkt);
|
|
3127
|
-
for (i = 0; i < rkt->rkt_partition_cnt; i++) {
|
|
3128
|
-
rd_kafka_toppar_t *rktp = rkt->rkt_p[i];
|
|
3129
|
-
|
|
3130
|
-
/* Only map undelegated partitions matching this
|
|
3131
|
-
* broker*/
|
|
3132
|
-
rd_kafka_toppar_lock(rktp);
|
|
3133
|
-
if (rktp->rktp_leader_id == rkb->rkb_nodeid &&
|
|
3134
|
-
!(rktp->rktp_broker && rktp->rktp_next_broker)) {
|
|
3135
|
-
rd_kafka_toppar_broker_update(
|
|
3136
|
-
rktp, rktp->rktp_leader_id, rkb,
|
|
3137
|
-
"broker node information updated");
|
|
3138
|
-
cnt++;
|
|
3139
|
-
}
|
|
3140
|
-
rd_kafka_toppar_unlock(rktp);
|
|
3141
|
-
}
|
|
3142
|
-
rd_kafka_topic_wrunlock(rkt);
|
|
3143
|
-
}
|
|
3144
|
-
rd_kafka_rdunlock(rk);
|
|
3145
|
-
|
|
3146
|
-
rd_rkb_dbg(rkb, TOPIC | RD_KAFKA_DBG_BROKER, "LEADER",
|
|
3147
|
-
"Mapped %d partition(s) to broker", cnt);
|
|
3148
|
-
}
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
3136
|
/**
|
|
3152
3137
|
* @brief Broker id comparator
|
|
3153
3138
|
*/
|
|
@@ -3188,6 +3173,10 @@ static void rd_kafka_broker_prepare_destroy(rd_kafka_broker_t *rkb) {
|
|
|
3188
3173
|
rd_kafka_broker_monitor_del(&rkb->rkb_coord_monitor);
|
|
3189
3174
|
}
|
|
3190
3175
|
|
|
3176
|
+
static rd_kafka_resp_err_t rd_kafka_broker_destroy_error(rd_kafka_t *rk) {
|
|
3177
|
+
return rd_kafka_terminating(rk) ? RD_KAFKA_RESP_ERR__DESTROY
|
|
3178
|
+
: RD_KAFKA_RESP_ERR__DESTROY_BROKER;
|
|
3179
|
+
}
|
|
3191
3180
|
|
|
3192
3181
|
/**
|
|
3193
3182
|
* @brief Serve a broker op (an op posted by another thread to be handled by
|
|
@@ -3207,7 +3196,7 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3207
3196
|
|
|
3208
3197
|
switch (rko->rko_type) {
|
|
3209
3198
|
case RD_KAFKA_OP_NODE_UPDATE: {
|
|
3210
|
-
|
|
3199
|
+
rd_bool_t updated = rd_false;
|
|
3211
3200
|
char brokername[RD_KAFKA_NODENAME_SIZE];
|
|
3212
3201
|
|
|
3213
3202
|
/* Need kafka_wrlock for updating rk_broker_by_id */
|
|
@@ -3221,31 +3210,7 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3221
3210
|
rd_strlcpy(rkb->rkb_nodename, rko->rko_u.node.nodename,
|
|
3222
3211
|
sizeof(rkb->rkb_nodename));
|
|
3223
3212
|
rkb->rkb_nodename_epoch++;
|
|
3224
|
-
updated
|
|
3225
|
-
}
|
|
3226
|
-
|
|
3227
|
-
if (rko->rko_u.node.nodeid != -1 &&
|
|
3228
|
-
!RD_KAFKA_BROKER_IS_LOGICAL(rkb) &&
|
|
3229
|
-
rko->rko_u.node.nodeid != rkb->rkb_nodeid) {
|
|
3230
|
-
int32_t old_nodeid = rkb->rkb_nodeid;
|
|
3231
|
-
rd_rkb_dbg(rkb, BROKER, "UPDATE",
|
|
3232
|
-
"NodeId changed from %" PRId32
|
|
3233
|
-
" to %" PRId32,
|
|
3234
|
-
rkb->rkb_nodeid, rko->rko_u.node.nodeid);
|
|
3235
|
-
|
|
3236
|
-
rkb->rkb_nodeid = rko->rko_u.node.nodeid;
|
|
3237
|
-
|
|
3238
|
-
/* Update system thread name */
|
|
3239
|
-
rd_kafka_set_thread_sysname("rdk:broker%" PRId32,
|
|
3240
|
-
rkb->rkb_nodeid);
|
|
3241
|
-
|
|
3242
|
-
/* Update broker_by_id sorted list */
|
|
3243
|
-
if (old_nodeid == -1)
|
|
3244
|
-
rd_list_add(&rkb->rkb_rk->rk_broker_by_id, rkb);
|
|
3245
|
-
rd_list_sort(&rkb->rkb_rk->rk_broker_by_id,
|
|
3246
|
-
rd_kafka_broker_cmp_by_id);
|
|
3247
|
-
|
|
3248
|
-
updated |= _UPD_ID;
|
|
3213
|
+
updated = rd_true;
|
|
3249
3214
|
}
|
|
3250
3215
|
|
|
3251
3216
|
rd_kafka_mk_brokername(brokername, sizeof(brokername),
|
|
@@ -3264,22 +3229,10 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3264
3229
|
rd_kafka_broker_unlock(rkb);
|
|
3265
3230
|
rd_kafka_wrunlock(rkb->rkb_rk);
|
|
3266
3231
|
|
|
3267
|
-
if (updated
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
else if (updated & _UPD_ID) {
|
|
3272
|
-
/* Map existing partitions to this broker. */
|
|
3273
|
-
rd_kafka_broker_map_partitions(rkb);
|
|
3274
|
-
|
|
3275
|
-
/* If broker is currently in state up we need
|
|
3276
|
-
* to trigger a state change so it exits its
|
|
3277
|
-
* state&type based .._serve() loop. */
|
|
3278
|
-
rd_kafka_broker_lock(rkb);
|
|
3279
|
-
if (rkb->rkb_state == RD_KAFKA_BROKER_STATE_UP)
|
|
3280
|
-
rd_kafka_broker_set_state(
|
|
3281
|
-
rkb, RD_KAFKA_BROKER_STATE_UPDATE);
|
|
3282
|
-
rd_kafka_broker_unlock(rkb);
|
|
3232
|
+
if (updated) {
|
|
3233
|
+
rd_kafka_broker_planned_fail(
|
|
3234
|
+
rkb, RD_KAFKA_RESP_ERR__TRANSPORT, "%s",
|
|
3235
|
+
"Broker hostname updated");
|
|
3283
3236
|
}
|
|
3284
3237
|
|
|
3285
3238
|
rd_kafka_brokers_broadcast_state_change(rkb->rkb_rk);
|
|
@@ -3308,17 +3261,20 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3308
3261
|
rd_kafka_toppar_lock(rktp);
|
|
3309
3262
|
|
|
3310
3263
|
/* Abort join if instance is terminating */
|
|
3311
|
-
if (
|
|
3264
|
+
if (rd_kafka_broker_or_instance_terminating(rkb) ||
|
|
3312
3265
|
(rktp->rktp_flags & RD_KAFKA_TOPPAR_F_REMOVE)) {
|
|
3313
|
-
rd_rkb_dbg(
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3266
|
+
rd_rkb_dbg(
|
|
3267
|
+
rkb, BROKER | RD_KAFKA_DBG_TOPIC, "TOPBRK",
|
|
3268
|
+
"Topic %s [%" PRId32
|
|
3269
|
+
"]: not joining broker: "
|
|
3270
|
+
"%s",
|
|
3271
|
+
rktp->rktp_rkt->rkt_topic->str,
|
|
3272
|
+
rktp->rktp_partition,
|
|
3273
|
+
rd_kafka_terminating(rkb->rkb_rk)
|
|
3274
|
+
? "instance is terminating"
|
|
3275
|
+
: rd_kafka_broker_termination_in_progress(rkb)
|
|
3276
|
+
? "broker is terminating"
|
|
3277
|
+
: "partition removed");
|
|
3322
3278
|
|
|
3323
3279
|
rd_kafka_broker_destroy(rktp->rktp_next_broker);
|
|
3324
3280
|
rktp->rktp_next_broker = NULL;
|
|
@@ -3386,6 +3342,8 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3386
3342
|
"finish before producing to "
|
|
3387
3343
|
"new leader");
|
|
3388
3344
|
}
|
|
3345
|
+
} else if (rkb->rkb_rk->rk_type == RD_KAFKA_CONSUMER) {
|
|
3346
|
+
rktp->rktp_ts_fetch_backoff = 0;
|
|
3389
3347
|
}
|
|
3390
3348
|
|
|
3391
3349
|
rd_kafka_broker_destroy(rktp->rktp_next_broker);
|
|
@@ -3525,10 +3483,13 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3525
3483
|
* and trigger a state change.
|
|
3526
3484
|
* This makes sure any eonce dependent on state changes
|
|
3527
3485
|
* are triggered. */
|
|
3528
|
-
rd_kafka_broker_fail(rkb, LOG_DEBUG,
|
|
3529
|
-
|
|
3486
|
+
rd_kafka_broker_fail(rkb, LOG_DEBUG,
|
|
3487
|
+
rd_kafka_broker_destroy_error(rkb->rkb_rk),
|
|
3488
|
+
"Decommissioning this broker");
|
|
3530
3489
|
|
|
3531
3490
|
rd_kafka_broker_prepare_destroy(rkb);
|
|
3491
|
+
/* Release main thread reference here */
|
|
3492
|
+
rd_kafka_broker_destroy(rkb);
|
|
3532
3493
|
wakeup = rd_true;
|
|
3533
3494
|
break;
|
|
3534
3495
|
|
|
@@ -3566,9 +3527,8 @@ rd_kafka_broker_op_serve(rd_kafka_broker_t *rkb, rd_kafka_op_t *rko) {
|
|
|
3566
3527
|
rd_kafka_broker_unlock(rkb);
|
|
3567
3528
|
|
|
3568
3529
|
if (do_disconnect)
|
|
3569
|
-
|
|
3570
|
-
rkb,
|
|
3571
|
-
RD_KAFKA_RESP_ERR__TRANSPORT,
|
|
3530
|
+
rd_kafka_broker_planned_fail(
|
|
3531
|
+
rkb, RD_KAFKA_RESP_ERR__TRANSPORT, "%s",
|
|
3572
3532
|
"Closing connection due to "
|
|
3573
3533
|
"nodename change");
|
|
3574
3534
|
}
|
|
@@ -3646,7 +3606,7 @@ rd_kafka_broker_ops_io_serve(rd_kafka_broker_t *rkb, rd_ts_t abs_timeout) {
|
|
|
3646
3606
|
rd_ts_t now;
|
|
3647
3607
|
rd_bool_t wakeup;
|
|
3648
3608
|
|
|
3649
|
-
if (unlikely(
|
|
3609
|
+
if (unlikely(rd_kafka_broker_or_instance_terminating(rkb)))
|
|
3650
3610
|
abs_timeout = rd_clock() + 1000;
|
|
3651
3611
|
else if (unlikely(rd_kafka_broker_needs_connection(rkb)))
|
|
3652
3612
|
abs_timeout = RD_POLL_NOWAIT;
|
|
@@ -4395,6 +4355,8 @@ static RD_INLINE void rd_kafka_broker_idle_check(rd_kafka_broker_t *rkb) {
|
|
|
4395
4355
|
rd_ts_t ts_recv = rd_atomic64_get(&rkb->rkb_c.ts_recv);
|
|
4396
4356
|
rd_ts_t ts_last_activity = RD_MAX(ts_send, ts_recv);
|
|
4397
4357
|
int idle_ms;
|
|
4358
|
+
const int max_jitter_ms = 2000;
|
|
4359
|
+
rd_dassert(rkb->rkb_rk->rk_conf.connections_max_idle_ms > 0);
|
|
4398
4360
|
|
|
4399
4361
|
/* If nothing has been sent yet, use the connection time as
|
|
4400
4362
|
* last activity. */
|
|
@@ -4403,13 +4365,22 @@ static RD_INLINE void rd_kafka_broker_idle_check(rd_kafka_broker_t *rkb) {
|
|
|
4403
4365
|
|
|
4404
4366
|
idle_ms = (int)((rd_clock() - ts_last_activity) / 1000);
|
|
4405
4367
|
|
|
4406
|
-
if (
|
|
4368
|
+
if (unlikely(rkb->rkb_c.connections_max_idle_ms == -1)) {
|
|
4369
|
+
/* Add a different jitter for each broker. */
|
|
4370
|
+
rkb->rkb_c.connections_max_idle_ms =
|
|
4371
|
+
rkb->rkb_rk->rk_conf.connections_max_idle_ms;
|
|
4372
|
+
if (rkb->rkb_c.connections_max_idle_ms >= 2 * max_jitter_ms)
|
|
4373
|
+
rkb->rkb_c.connections_max_idle_ms -=
|
|
4374
|
+
rd_jitter(0, max_jitter_ms);
|
|
4375
|
+
}
|
|
4376
|
+
|
|
4377
|
+
if (likely(idle_ms < rkb->rkb_c.connections_max_idle_ms))
|
|
4407
4378
|
return;
|
|
4408
4379
|
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4380
|
+
rd_kafka_broker_planned_fail(rkb, RD_KAFKA_RESP_ERR__TRANSPORT,
|
|
4381
|
+
"Connection max idle time exceeded "
|
|
4382
|
+
"(%dms since last activity)",
|
|
4383
|
+
idle_ms);
|
|
4413
4384
|
}
|
|
4414
4385
|
|
|
4415
4386
|
|
|
@@ -4485,7 +4456,7 @@ static RD_INLINE void rd_kafka_broker_idle_check(rd_kafka_broker_t *rkb) {
|
|
|
4485
4456
|
static void rd_kafka_broker_serve(rd_kafka_broker_t *rkb, int timeout_ms) {
|
|
4486
4457
|
rd_ts_t abs_timeout;
|
|
4487
4458
|
|
|
4488
|
-
if (unlikely(
|
|
4459
|
+
if (unlikely(rd_kafka_broker_or_instance_terminating(rkb) ||
|
|
4489
4460
|
timeout_ms == RD_POLL_NOWAIT))
|
|
4490
4461
|
timeout_ms = 1;
|
|
4491
4462
|
else if (timeout_ms == RD_POLL_INFINITE)
|
|
@@ -4537,6 +4508,7 @@ rd_kafka_broker_addresses_exhausted(const rd_kafka_broker_t *rkb) {
|
|
|
4537
4508
|
static int rd_kafka_broker_thread_main(void *arg) {
|
|
4538
4509
|
rd_kafka_broker_t *rkb = arg;
|
|
4539
4510
|
rd_kafka_t *rk = rkb->rkb_rk;
|
|
4511
|
+
rd_kafka_op_t *terminate_op;
|
|
4540
4512
|
|
|
4541
4513
|
rd_kafka_set_thread_name("%s", rkb->rkb_name);
|
|
4542
4514
|
rd_kafka_set_thread_sysname("rdk:broker%" PRId32, rkb->rkb_nodeid);
|
|
@@ -4603,8 +4575,11 @@ static int rd_kafka_broker_thread_main(void *arg) {
|
|
|
4603
4575
|
break;
|
|
4604
4576
|
}
|
|
4605
4577
|
|
|
4606
|
-
if (unlikely(
|
|
4578
|
+
if (unlikely(
|
|
4579
|
+
rd_kafka_broker_or_instance_terminating(rkb))) {
|
|
4607
4580
|
rd_kafka_broker_serve(rkb, 1000);
|
|
4581
|
+
break;
|
|
4582
|
+
}
|
|
4608
4583
|
|
|
4609
4584
|
if (!rd_kafka_sasl_ready(rkb->rkb_rk)) {
|
|
4610
4585
|
/* SASL provider not yet ready. */
|
|
@@ -4709,30 +4684,21 @@ static int rd_kafka_broker_thread_main(void *arg) {
|
|
|
4709
4684
|
rd_kafka_broker_connect_auth(rkb);
|
|
4710
4685
|
break;
|
|
4711
4686
|
|
|
4712
|
-
case RD_KAFKA_BROKER_STATE_UPDATE:
|
|
4713
|
-
/* FALLTHRU */
|
|
4714
4687
|
case RD_KAFKA_BROKER_STATE_UP:
|
|
4715
4688
|
rd_kafka_broker_serve(rkb, rd_kafka_max_block_ms);
|
|
4716
|
-
|
|
4717
|
-
if (rkb->rkb_state == RD_KAFKA_BROKER_STATE_UPDATE) {
|
|
4718
|
-
rd_kafka_broker_lock(rkb);
|
|
4719
|
-
rd_kafka_broker_set_state(
|
|
4720
|
-
rkb, RD_KAFKA_BROKER_STATE_UP);
|
|
4721
|
-
rd_kafka_broker_unlock(rkb);
|
|
4722
|
-
}
|
|
4723
4689
|
break;
|
|
4724
4690
|
}
|
|
4725
4691
|
|
|
4726
|
-
if (
|
|
4692
|
+
if (rd_kafka_broker_or_instance_terminating(rkb)) {
|
|
4727
4693
|
/* Handle is terminating: fail the send+retry queue
|
|
4728
4694
|
* to speed up termination, otherwise we'll
|
|
4729
4695
|
* need to wait for request timeouts. */
|
|
4730
4696
|
r = rd_kafka_broker_bufq_timeout_scan(
|
|
4731
4697
|
rkb, 0, &rkb->rkb_outbufs, NULL, -1,
|
|
4732
|
-
|
|
4698
|
+
rd_kafka_broker_destroy_error(rk), 0, NULL, 0);
|
|
4733
4699
|
r += rd_kafka_broker_bufq_timeout_scan(
|
|
4734
4700
|
rkb, 0, &rkb->rkb_retrybufs, NULL, -1,
|
|
4735
|
-
|
|
4701
|
+
rd_kafka_broker_destroy_error(rk), 0, NULL, 0);
|
|
4736
4702
|
rd_rkb_dbg(
|
|
4737
4703
|
rkb, BROKER, "TERMINATE",
|
|
4738
4704
|
"Handle is terminating in state %s: "
|
|
@@ -4749,28 +4715,46 @@ static int rd_kafka_broker_thread_main(void *arg) {
|
|
|
4749
4715
|
}
|
|
4750
4716
|
}
|
|
4751
4717
|
|
|
4752
|
-
if (rkb->rkb_source != RD_KAFKA_INTERNAL) {
|
|
4753
|
-
rd_kafka_wrlock(rkb->rkb_rk);
|
|
4754
|
-
TAILQ_REMOVE(&rkb->rkb_rk->rk_brokers, rkb, rkb_link);
|
|
4755
|
-
if (rkb->rkb_nodeid != -1 && !RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
4756
|
-
rd_list_remove(&rkb->rkb_rk->rk_broker_by_id, rkb);
|
|
4757
|
-
(void)rd_atomic32_sub(&rkb->rkb_rk->rk_broker_cnt, 1);
|
|
4758
|
-
rd_kafka_wrunlock(rkb->rkb_rk);
|
|
4759
|
-
}
|
|
4760
|
-
|
|
4761
|
-
rd_kafka_broker_fail(rkb, LOG_DEBUG, RD_KAFKA_RESP_ERR__DESTROY,
|
|
4762
|
-
"Broker handle is terminating");
|
|
4763
|
-
|
|
4764
4718
|
/* Disable and drain ops queue.
|
|
4765
4719
|
* Simply purging the ops queue risks leaving dangling references
|
|
4766
4720
|
* for ops such as PARTITION_JOIN/PARTITION_LEAVE where the broker
|
|
4767
4721
|
* reference is not maintained in the rko (but in rktp_next_leader).
|
|
4768
|
-
* #1596
|
|
4722
|
+
* #1596.
|
|
4723
|
+
* Do this before failing the broker to make sure no buffers
|
|
4724
|
+
* are enqueued after that. */
|
|
4769
4725
|
rd_kafka_q_disable(rkb->rkb_ops);
|
|
4770
4726
|
while (rd_kafka_broker_ops_serve(rkb, RD_POLL_NOWAIT))
|
|
4771
4727
|
;
|
|
4772
4728
|
|
|
4773
|
-
|
|
4729
|
+
rd_kafka_broker_fail(rkb, LOG_DEBUG, rd_kafka_broker_destroy_error(rk),
|
|
4730
|
+
"Broker handle is terminating");
|
|
4731
|
+
|
|
4732
|
+
rd_rkb_dbg(rkb, BROKER, "TERMINATE",
|
|
4733
|
+
"Handle terminates in state %s: "
|
|
4734
|
+
"%d refcnts (%p), %d toppar(s), "
|
|
4735
|
+
"%d active toppar(s), "
|
|
4736
|
+
"%d outbufs, %d waitresps, %d retrybufs",
|
|
4737
|
+
rd_kafka_broker_state_names[rkb->rkb_state],
|
|
4738
|
+
rd_refcnt_get(&rkb->rkb_refcnt), &rkb->rkb_refcnt,
|
|
4739
|
+
rkb->rkb_toppar_cnt, rkb->rkb_active_toppar_cnt,
|
|
4740
|
+
(int)rd_kafka_bufq_cnt(&rkb->rkb_outbufs),
|
|
4741
|
+
(int)rd_kafka_bufq_cnt(&rkb->rkb_waitresps),
|
|
4742
|
+
(int)rd_kafka_bufq_cnt(&rkb->rkb_retrybufs));
|
|
4743
|
+
|
|
4744
|
+
rd_dassert(rkb->rkb_state == RD_KAFKA_BROKER_STATE_DOWN);
|
|
4745
|
+
if (rkb->rkb_source != RD_KAFKA_INTERNAL) {
|
|
4746
|
+
rd_kafka_wrlock(rkb->rkb_rk);
|
|
4747
|
+
TAILQ_REMOVE(&rkb->rkb_rk->rk_brokers, rkb, rkb_link);
|
|
4748
|
+
|
|
4749
|
+
if (RD_KAFKA_BROKER_IS_LOGICAL(rkb)) {
|
|
4750
|
+
rd_atomic32_sub(&rkb->rkb_rk->rk_logical_broker_cnt, 1);
|
|
4751
|
+
} else if (rd_atomic32_set(&rkb->rkb_down_reported, 0) == 1) {
|
|
4752
|
+
/* Only 1 -> 0 */
|
|
4753
|
+
rd_atomic32_sub(&rkb->rkb_rk->rk_broker_down_cnt, 1);
|
|
4754
|
+
}
|
|
4755
|
+
rd_atomic32_sub(&rkb->rkb_rk->rk_broker_cnt, 1);
|
|
4756
|
+
rd_kafka_wrunlock(rkb->rkb_rk);
|
|
4757
|
+
}
|
|
4774
4758
|
|
|
4775
4759
|
#if WITH_SSL
|
|
4776
4760
|
/* Remove OpenSSL per-thread error state to avoid memory leaks */
|
|
@@ -4786,6 +4770,15 @@ static int rd_kafka_broker_thread_main(void *arg) {
|
|
|
4786
4770
|
|
|
4787
4771
|
rd_atomic32_sub(&rd_kafka_thread_cnt_curr, 1);
|
|
4788
4772
|
|
|
4773
|
+
terminate_op = rd_kafka_op_new(RD_KAFKA_OP_TERMINATE);
|
|
4774
|
+
terminate_op->rko_u.terminated.rkb = rkb;
|
|
4775
|
+
terminate_op->rko_u.terminated.cb =
|
|
4776
|
+
rd_kafka_decommissioned_broker_thread_join;
|
|
4777
|
+
rd_kafka_q_enq(rk->rk_ops, terminate_op);
|
|
4778
|
+
|
|
4779
|
+
/* Release broker thread reference here and call destroy final. */
|
|
4780
|
+
rd_kafka_broker_destroy(rkb);
|
|
4781
|
+
|
|
4789
4782
|
return 0;
|
|
4790
4783
|
}
|
|
4791
4784
|
|
|
@@ -4919,13 +4912,14 @@ rd_kafka_broker_t *rd_kafka_broker_add(rd_kafka_t *rk,
|
|
|
4919
4912
|
rd_snprintf(rkb->rkb_name, sizeof(rkb->rkb_name), "%s", name);
|
|
4920
4913
|
}
|
|
4921
4914
|
|
|
4922
|
-
rkb->rkb_source
|
|
4923
|
-
rkb->rkb_rk
|
|
4924
|
-
rkb->rkb_ts_state
|
|
4925
|
-
rkb->rkb_nodeid
|
|
4926
|
-
rkb->rkb_proto
|
|
4927
|
-
rkb->rkb_port
|
|
4928
|
-
rkb->rkb_origname
|
|
4915
|
+
rkb->rkb_source = source;
|
|
4916
|
+
rkb->rkb_rk = rk;
|
|
4917
|
+
rkb->rkb_ts_state = rd_clock();
|
|
4918
|
+
rkb->rkb_nodeid = nodeid;
|
|
4919
|
+
rkb->rkb_proto = proto;
|
|
4920
|
+
rkb->rkb_port = port;
|
|
4921
|
+
rkb->rkb_origname = rd_strdup(name);
|
|
4922
|
+
rkb->rkb_c.connections_max_idle_ms = -1;
|
|
4929
4923
|
|
|
4930
4924
|
mtx_init(&rkb->rkb_lock, mtx_plain);
|
|
4931
4925
|
mtx_init(&rkb->rkb_logname_lock, mtx_plain);
|
|
@@ -4987,6 +4981,8 @@ rd_kafka_broker_t *rd_kafka_broker_add(rd_kafka_t *rk,
|
|
|
4987
4981
|
|
|
4988
4982
|
rkb->rkb_reconnect_backoff_ms = rk->rk_conf.reconnect_backoff_ms;
|
|
4989
4983
|
rd_atomic32_init(&rkb->rkb_persistconn.coord, 0);
|
|
4984
|
+
rd_atomic32_init(&rkb->termination_in_progress, 0);
|
|
4985
|
+
rd_atomic32_init(&rkb->rkb_down_reported, 0);
|
|
4990
4986
|
|
|
4991
4987
|
rd_atomic64_init(&rkb->rkb_c.ts_send, 0);
|
|
4992
4988
|
rd_atomic64_init(&rkb->rkb_c.ts_recv, 0);
|
|
@@ -5155,7 +5151,7 @@ rd_kafka_broker_t *rd_kafka_broker_add_logical(rd_kafka_t *rk,
|
|
|
5155
5151
|
rd_assert(rkb && *"failed to create broker thread");
|
|
5156
5152
|
rd_kafka_wrunlock(rk);
|
|
5157
5153
|
|
|
5158
|
-
rd_atomic32_add(&rk->
|
|
5154
|
+
rd_atomic32_add(&rk->rk_logical_broker_cnt, 1);
|
|
5159
5155
|
|
|
5160
5156
|
rd_dassert(RD_KAFKA_BROKER_IS_LOGICAL(rkb));
|
|
5161
5157
|
rd_kafka_broker_keep(rkb);
|
|
@@ -5214,14 +5210,6 @@ void rd_kafka_broker_set_nodename(rd_kafka_broker_t *rkb,
|
|
|
5214
5210
|
rkb->rkb_nodename_epoch++;
|
|
5215
5211
|
changed = rd_true;
|
|
5216
5212
|
}
|
|
5217
|
-
|
|
5218
|
-
if (rkb->rkb_nodeid != nodeid) {
|
|
5219
|
-
rd_rkb_dbg(rkb, BROKER, "NODEID",
|
|
5220
|
-
"Broker nodeid changed from %" PRId32 " to %" PRId32,
|
|
5221
|
-
rkb->rkb_nodeid, nodeid);
|
|
5222
|
-
rkb->rkb_nodeid = nodeid;
|
|
5223
|
-
}
|
|
5224
|
-
|
|
5225
5213
|
rd_kafka_broker_unlock(rkb);
|
|
5226
5214
|
|
|
5227
5215
|
/* Update the log name to include (or exclude) the nodeid.
|
|
@@ -5234,11 +5222,6 @@ void rd_kafka_broker_set_nodename(rd_kafka_broker_t *rkb,
|
|
|
5234
5222
|
if (!changed)
|
|
5235
5223
|
return;
|
|
5236
5224
|
|
|
5237
|
-
if (!rd_kafka_broker_is_addrless(rkb))
|
|
5238
|
-
rd_atomic32_sub(&rkb->rkb_rk->rk_broker_addrless_cnt, 1);
|
|
5239
|
-
else
|
|
5240
|
-
rd_atomic32_add(&rkb->rkb_rk->rk_broker_addrless_cnt, 1);
|
|
5241
|
-
|
|
5242
5225
|
/* Trigger a disconnect & reconnect */
|
|
5243
5226
|
rd_kafka_broker_schedule_connection(rkb);
|
|
5244
5227
|
}
|
|
@@ -5305,11 +5288,12 @@ static rd_kafka_broker_t *rd_kafka_broker_find(rd_kafka_t *rk,
|
|
|
5305
5288
|
rd_kafka_mk_nodename(nodename, sizeof(nodename), name, port);
|
|
5306
5289
|
|
|
5307
5290
|
TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
|
|
5308
|
-
if (
|
|
5291
|
+
if (rd_kafka_broker_or_instance_terminating(rkb) ||
|
|
5292
|
+
RD_KAFKA_BROKER_IS_LOGICAL(rkb))
|
|
5309
5293
|
continue;
|
|
5310
5294
|
|
|
5311
5295
|
rd_kafka_broker_lock(rkb);
|
|
5312
|
-
if (
|
|
5296
|
+
if (rkb->rkb_proto == proto &&
|
|
5313
5297
|
!strcmp(rkb->rkb_nodename, nodename)) {
|
|
5314
5298
|
rd_kafka_broker_keep(rkb);
|
|
5315
5299
|
rd_kafka_broker_unlock(rkb);
|
|
@@ -5552,6 +5536,9 @@ int rd_kafka_brokers_add0(rd_kafka_t *rk,
|
|
|
5552
5536
|
|
|
5553
5537
|
|
|
5554
5538
|
int rd_kafka_brokers_add(rd_kafka_t *rk, const char *brokerlist) {
|
|
5539
|
+
rd_kafka_wrlock(rk);
|
|
5540
|
+
rd_list_add(&rk->additional_brokerlists, rd_strdup(brokerlist));
|
|
5541
|
+
rd_kafka_wrunlock(rk);
|
|
5555
5542
|
return rd_kafka_brokers_add0(rk, brokerlist, rd_false);
|
|
5556
5543
|
}
|
|
5557
5544
|
|
|
@@ -5590,12 +5577,6 @@ void rd_kafka_broker_update(rd_kafka_t *rk,
|
|
|
5590
5577
|
* the hostname. */
|
|
5591
5578
|
if (strcmp(rkb->rkb_nodename, nodename))
|
|
5592
5579
|
needs_update = 1;
|
|
5593
|
-
} else if ((rkb = rd_kafka_broker_find(rk, proto, mdb->host,
|
|
5594
|
-
mdb->port))) {
|
|
5595
|
-
/* Broker matched by hostname (but not by nodeid),
|
|
5596
|
-
* update the nodeid. */
|
|
5597
|
-
needs_update = 1;
|
|
5598
|
-
|
|
5599
5580
|
} else if ((rkb = rd_kafka_broker_add(rk, RD_KAFKA_LEARNED, proto,
|
|
5600
5581
|
mdb->host, mdb->port, mdb->id))) {
|
|
5601
5582
|
rd_kafka_broker_keep(rkb);
|
|
@@ -5610,7 +5591,6 @@ void rd_kafka_broker_update(rd_kafka_t *rk,
|
|
|
5610
5591
|
rko = rd_kafka_op_new(RD_KAFKA_OP_NODE_UPDATE);
|
|
5611
5592
|
rd_strlcpy(rko->rko_u.node.nodename, nodename,
|
|
5612
5593
|
sizeof(rko->rko_u.node.nodename));
|
|
5613
|
-
rko->rko_u.node.nodeid = mdb->id;
|
|
5614
5594
|
/* Perform a blocking op request so that all
|
|
5615
5595
|
* broker-related state, such as the rk broker list,
|
|
5616
5596
|
* is up to date by the time this call returns.
|
|
@@ -5631,24 +5611,12 @@ void rd_kafka_broker_update(rd_kafka_t *rk,
|
|
|
5631
5611
|
* @returns the broker id, or RD_KAFKA_NODEID_UA if \p rkb is NULL.
|
|
5632
5612
|
*
|
|
5633
5613
|
* @locality any
|
|
5634
|
-
* @locks_required none
|
|
5635
|
-
* @locks_acquired rkb_lock
|
|
5636
5614
|
*/
|
|
5637
5615
|
int32_t rd_kafka_broker_id(rd_kafka_broker_t *rkb) {
|
|
5638
|
-
int32_t broker_id;
|
|
5639
|
-
|
|
5640
5616
|
if (unlikely(!rkb))
|
|
5641
5617
|
return RD_KAFKA_NODEID_UA;
|
|
5642
5618
|
|
|
5643
|
-
|
|
5644
|
-
if (thrd_is_current(rkb->rkb_thread))
|
|
5645
|
-
return rkb->rkb_nodeid;
|
|
5646
|
-
|
|
5647
|
-
rd_kafka_broker_lock(rkb);
|
|
5648
|
-
broker_id = rkb->rkb_nodeid;
|
|
5649
|
-
rd_kafka_broker_unlock(rkb);
|
|
5650
|
-
|
|
5651
|
-
return broker_id;
|
|
5619
|
+
return rkb->rkb_nodeid;
|
|
5652
5620
|
}
|
|
5653
5621
|
|
|
5654
5622
|
|
|
@@ -5733,6 +5701,17 @@ static int rd_kafka_broker_filter_never_connected(rd_kafka_broker_t *rkb,
|
|
|
5733
5701
|
return rd_atomic32_get(&rkb->rkb_c.connects);
|
|
5734
5702
|
}
|
|
5735
5703
|
|
|
5704
|
+
static void rd_kafka_connect_any_timer_cb(rd_kafka_timers_t *rkts, void *arg) {
|
|
5705
|
+
const char *reason = (const char *)arg;
|
|
5706
|
+
rd_kafka_t *rk = rkts->rkts_rk;
|
|
5707
|
+
if (rd_kafka_terminating(rk))
|
|
5708
|
+
return;
|
|
5709
|
+
|
|
5710
|
+
/* Acquire the read lock for `rd_kafka_connect_any` */
|
|
5711
|
+
rd_kafka_rdlock(rk);
|
|
5712
|
+
rd_kafka_connect_any(rk, reason);
|
|
5713
|
+
rd_kafka_rdunlock(rk);
|
|
5714
|
+
}
|
|
5736
5715
|
|
|
5737
5716
|
/**
|
|
5738
5717
|
* @brief Sparse connections:
|
|
@@ -5752,15 +5731,14 @@ void rd_kafka_connect_any(rd_kafka_t *rk, const char *reason) {
|
|
|
5752
5731
|
* a specific purpose (group coordinator) and their connections
|
|
5753
5732
|
* should not be reused for other purposes.
|
|
5754
5733
|
* rd_kafka_broker_random() will not return LOGICAL brokers. */
|
|
5755
|
-
if (rd_atomic32_get(&rk->rk_broker_up_cnt)
|
|
5756
|
-
rd_atomic32_get(&rk->rk_logical_broker_up_cnt) >
|
|
5757
|
-
0 ||
|
|
5734
|
+
if (rd_atomic32_get(&rk->rk_broker_up_cnt) > 0 ||
|
|
5758
5735
|
rd_atomic32_get(&rk->rk_broker_cnt) -
|
|
5759
|
-
rd_atomic32_get(&rk->
|
|
5736
|
+
rd_atomic32_get(&rk->rk_logical_broker_cnt) ==
|
|
5760
5737
|
0)
|
|
5761
5738
|
return;
|
|
5762
5739
|
|
|
5763
5740
|
mtx_lock(&rk->rk_suppress.sparse_connect_lock);
|
|
5741
|
+
|
|
5764
5742
|
suppr = rd_interval(&rk->rk_suppress.sparse_connect_random,
|
|
5765
5743
|
rk->rk_conf.sparse_connect_intvl * 1000, 0);
|
|
5766
5744
|
mtx_unlock(&rk->rk_suppress.sparse_connect_lock);
|
|
@@ -5770,6 +5748,11 @@ void rd_kafka_connect_any(rd_kafka_t *rk, const char *reason) {
|
|
|
5770
5748
|
"Not selecting any broker for cluster connection: "
|
|
5771
5749
|
"still suppressed for %" PRId64 "ms: %s",
|
|
5772
5750
|
-suppr / 1000, reason);
|
|
5751
|
+
/* Retry after interval + 1ms has passed */
|
|
5752
|
+
rd_kafka_timer_start_oneshot(
|
|
5753
|
+
&rk->rk_timers, &rk->rk_suppress.sparse_connect_random_tmr,
|
|
5754
|
+
rd_false /* don't restart */, 1000LL - suppr,
|
|
5755
|
+
rd_kafka_connect_any_timer_cb, (void *)reason);
|
|
5773
5756
|
return;
|
|
5774
5757
|
}
|
|
5775
5758
|
|
|
@@ -5786,7 +5769,7 @@ void rd_kafka_connect_any(rd_kafka_t *rk, const char *reason) {
|
|
|
5786
5769
|
|
|
5787
5770
|
if (!rkb) {
|
|
5788
5771
|
/* No brokers matched:
|
|
5789
|
-
* this happens if
|
|
5772
|
+
* this happens if all brokers are in > INIT state,
|
|
5790
5773
|
* in which case they're already connecting. */
|
|
5791
5774
|
|
|
5792
5775
|
rd_kafka_dbg(rk, BROKER | RD_KAFKA_DBG_GENERIC, "CONNECT",
|
|
@@ -5868,8 +5851,8 @@ static void rd_kafka_broker_handle_purge_queues(rd_kafka_broker_t *rkb,
|
|
|
5868
5851
|
* the protocol stream, so we need to disconnect from the broker
|
|
5869
5852
|
* to get a clean protocol socket. */
|
|
5870
5853
|
if (partial_cnt)
|
|
5871
|
-
|
|
5872
|
-
rkb,
|
|
5854
|
+
rd_kafka_broker_planned_fail(
|
|
5855
|
+
rkb, RD_KAFKA_RESP_ERR__PURGE_QUEUE,
|
|
5873
5856
|
"Purged %d partially sent request: "
|
|
5874
5857
|
"forcing disconnect",
|
|
5875
5858
|
partial_cnt);
|
|
@@ -5992,7 +5975,6 @@ void rd_kafka_broker_active_toppar_del(rd_kafka_broker_t *rkb,
|
|
|
5992
5975
|
*/
|
|
5993
5976
|
void rd_kafka_broker_schedule_connection(rd_kafka_broker_t *rkb) {
|
|
5994
5977
|
rd_kafka_op_t *rko;
|
|
5995
|
-
|
|
5996
5978
|
rko = rd_kafka_op_new(RD_KAFKA_OP_CONNECT);
|
|
5997
5979
|
rd_kafka_op_set_prio(rko, RD_KAFKA_PRIO_FLASH);
|
|
5998
5980
|
rd_kafka_q_enq(rkb->rkb_ops, rko);
|
|
@@ -6170,6 +6152,174 @@ void rd_kafka_broker_start_reauth_cb(rd_kafka_timers_t *rkts, void *_rkb) {
|
|
|
6170
6152
|
rd_kafka_q_enq(rkb->rkb_ops, rko);
|
|
6171
6153
|
}
|
|
6172
6154
|
|
|
6155
|
+
int32_t *rd_kafka_brokers_learned_ids(rd_kafka_t *rk, size_t *cntp) {
|
|
6156
|
+
rd_kafka_broker_t *rkb;
|
|
6157
|
+
int32_t *ids, *p;
|
|
6158
|
+
int32_t i;
|
|
6159
|
+
|
|
6160
|
+
*cntp = 0;
|
|
6161
|
+
rd_kafka_rdlock(rk);
|
|
6162
|
+
ids = malloc(sizeof(*ids) * rd_list_cnt(&rk->rk_broker_by_id));
|
|
6163
|
+
p = ids;
|
|
6164
|
+
RD_LIST_FOREACH(rkb, &rk->rk_broker_by_id, i) {
|
|
6165
|
+
*p++ = rkb->rkb_nodeid;
|
|
6166
|
+
(*cntp)++;
|
|
6167
|
+
}
|
|
6168
|
+
rd_kafka_rdunlock(rk);
|
|
6169
|
+
|
|
6170
|
+
return ids;
|
|
6171
|
+
}
|
|
6172
|
+
|
|
6173
|
+
/**
|
|
6174
|
+
* @brief Decommission a broker.
|
|
6175
|
+
*
|
|
6176
|
+
* @param rk Client instance.
|
|
6177
|
+
* @param rkb Broker to decommission.
|
|
6178
|
+
* @param wait_thrds Add the broker's thread to this list if not NULL.
|
|
6179
|
+
*
|
|
6180
|
+
* @locks rd_kafka_wrlock() is dropped and reacquired.
|
|
6181
|
+
*
|
|
6182
|
+
* Broker threads hold a refcount and detect when it reaches 1 and then
|
|
6183
|
+
* decommissions itself. Callers can wait for this to happen by calling
|
|
6184
|
+
* thrd_join() on elements of \p wait_thrds. Callers are responsible for
|
|
6185
|
+
* managing the creation and destruction of \p wait_thrds which can be NULL.
|
|
6186
|
+
*/
|
|
6187
|
+
void rd_kafka_broker_decommission(rd_kafka_t *rk,
|
|
6188
|
+
rd_kafka_broker_t *rkb,
|
|
6189
|
+
rd_list_t *wait_thrds) {
|
|
6190
|
+
|
|
6191
|
+
if (rd_atomic32_get(&rkb->termination_in_progress) > 0)
|
|
6192
|
+
return;
|
|
6193
|
+
|
|
6194
|
+
rd_atomic32_add(&rkb->termination_in_progress, 1);
|
|
6195
|
+
|
|
6196
|
+
/* Add broker's thread to wait_thrds list for later joining */
|
|
6197
|
+
if (wait_thrds) {
|
|
6198
|
+
thrd_t *thrd = rd_malloc(sizeof(*thrd));
|
|
6199
|
+
*thrd = rkb->rkb_thread;
|
|
6200
|
+
|
|
6201
|
+
rd_list_add(wait_thrds, thrd);
|
|
6202
|
+
}
|
|
6203
|
+
|
|
6204
|
+
rd_list_remove(&rk->rk_broker_by_id, rkb);
|
|
6205
|
+
rd_kafka_wrunlock(rk);
|
|
6206
|
+
|
|
6207
|
+
rd_kafka_dbg(rk, BROKER, "DESTROY", "Sending TERMINATE to %s",
|
|
6208
|
+
rd_kafka_broker_name(rkb));
|
|
6209
|
+
|
|
6210
|
+
#ifndef _WIN32
|
|
6211
|
+
/* Interrupt IO threads to speed up termination. */
|
|
6212
|
+
if (rk->rk_conf.term_sig)
|
|
6213
|
+
pthread_kill(rkb->rkb_thread, rk->rk_conf.term_sig);
|
|
6214
|
+
#endif
|
|
6215
|
+
|
|
6216
|
+
if (rk->rk_cgrp && rk->rk_cgrp->rkcg_curr_coord &&
|
|
6217
|
+
rk->rk_cgrp->rkcg_curr_coord == rkb)
|
|
6218
|
+
/* If we're decommissioning current coordinator handle,
|
|
6219
|
+
* mark it as dead and decrease its reference count. */
|
|
6220
|
+
rd_kafka_cgrp_coord_dead(rk->rk_cgrp,
|
|
6221
|
+
RD_KAFKA_RESP_ERR__DESTROY_BROKER,
|
|
6222
|
+
"Group coordinator decommissioned");
|
|
6223
|
+
/* Send op to trigger queue/io wake-up.
|
|
6224
|
+
* Broker thread will destroy this thread reference.
|
|
6225
|
+
* WARNING: This is last time we can read from rkb in this thread! */
|
|
6226
|
+
rd_kafka_q_enq(rkb->rkb_ops, rd_kafka_op_new(RD_KAFKA_OP_TERMINATE));
|
|
6227
|
+
|
|
6228
|
+
rd_kafka_wrlock(rk);
|
|
6229
|
+
}
|
|
6230
|
+
|
|
6231
|
+
/**
|
|
6232
|
+
* @brief Unittest for reconnect.backoff.ms
|
|
6233
|
+
*/
|
|
6234
|
+
static int rd_ut_reconnect_backoff(void) {
|
|
6235
|
+
rd_kafka_broker_t rkb = RD_ZERO_INIT;
|
|
6236
|
+
rd_kafka_conf_t conf = {.reconnect_backoff_ms = 10,
|
|
6237
|
+
.reconnect_backoff_max_ms = 90};
|
|
6238
|
+
rd_ts_t now = 1000000;
|
|
6239
|
+
int backoff;
|
|
6240
|
+
|
|
6241
|
+
rkb.rkb_reconnect_backoff_ms = conf.reconnect_backoff_ms;
|
|
6242
|
+
|
|
6243
|
+
/* broker's backoff is the initial reconnect.backoff.ms=10 */
|
|
6244
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6245
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6246
|
+
RD_UT_ASSERT_RANGE(backoff, 7, 15, "%d");
|
|
6247
|
+
|
|
6248
|
+
/* .. 20 */
|
|
6249
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6250
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6251
|
+
RD_UT_ASSERT_RANGE(backoff, 15, 30, "%d");
|
|
6252
|
+
|
|
6253
|
+
/* .. 40 */
|
|
6254
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6255
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6256
|
+
RD_UT_ASSERT_RANGE(backoff, 30, 60, "%d");
|
|
6257
|
+
|
|
6258
|
+
/* .. 80, the jitter is capped at reconnect.backoff.max.ms=90 */
|
|
6259
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6260
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6261
|
+
RD_UT_ASSERT_RANGE(backoff, 60, conf.reconnect_backoff_max_ms, "%d");
|
|
6262
|
+
|
|
6263
|
+
/* .. 90, capped by reconnect.backoff.max.ms */
|
|
6264
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6265
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6266
|
+
RD_UT_ASSERT_RANGE(backoff, 67, conf.reconnect_backoff_max_ms, "%d");
|
|
6267
|
+
|
|
6268
|
+
/* .. 90, should remain at capped value. */
|
|
6269
|
+
rd_kafka_broker_update_reconnect_backoff(&rkb, &conf, now);
|
|
6270
|
+
backoff = rd_kafka_broker_reconnect_backoff(&rkb, now);
|
|
6271
|
+
RD_UT_ASSERT_RANGE(backoff, 67, conf.reconnect_backoff_max_ms, "%d");
|
|
6272
|
+
|
|
6273
|
+
RD_UT_PASS();
|
|
6274
|
+
}
|
|
6275
|
+
|
|
6276
|
+
/**
|
|
6277
|
+
* @brief Unittest for reconnect.backoff.ms
|
|
6278
|
+
*/
|
|
6279
|
+
static int rd_ut_ApiVersion_at_least(void) {
|
|
6280
|
+
rd_kafka_broker_t rkb = RD_ZERO_INIT;
|
|
6281
|
+
mtx_init(&rkb.rkb_lock, mtx_plain);
|
|
6282
|
+
|
|
6283
|
+
struct rd_kafka_ApiVersion av = {
|
|
6284
|
+
.ApiKey = RD_KAFKAP_Metadata,
|
|
6285
|
+
.MinVer = 5,
|
|
6286
|
+
.MaxVer = 10,
|
|
6287
|
+
};
|
|
6288
|
+
|
|
6289
|
+
rkb.rkb_ApiVersions_cnt = 1;
|
|
6290
|
+
rkb.rkb_ApiVersions = &av;
|
|
6291
|
+
|
|
6292
|
+
RD_UT_ASSERT(
|
|
6293
|
+
rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 0),
|
|
6294
|
+
"Metadata API version should be at least 0");
|
|
6295
|
+
RD_UT_ASSERT(
|
|
6296
|
+
rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 3),
|
|
6297
|
+
"Metadata API version should be at least 3");
|
|
6298
|
+
RD_UT_ASSERT(
|
|
6299
|
+
rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 5),
|
|
6300
|
+
"Metadata API version should be at least 5");
|
|
6301
|
+
RD_UT_ASSERT(
|
|
6302
|
+
rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 7),
|
|
6303
|
+
"Metadata API version should be at least 7");
|
|
6304
|
+
RD_UT_ASSERT(
|
|
6305
|
+
rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 10),
|
|
6306
|
+
"Metadata API version should be at least 10");
|
|
6307
|
+
RD_UT_ASSERT(
|
|
6308
|
+
!rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 11),
|
|
6309
|
+
"Metadata API version shouldn't be at least 11");
|
|
6310
|
+
|
|
6311
|
+
rkb.rkb_ApiVersions_cnt = 0;
|
|
6312
|
+
RD_UT_ASSERT(
|
|
6313
|
+
!rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 0),
|
|
6314
|
+
"Metadata API version shouldn't be at least 0");
|
|
6315
|
+
RD_UT_ASSERT(
|
|
6316
|
+
!rd_kafka_broker_ApiVersion_at_least(&rkb, RD_KAFKAP_Metadata, 3),
|
|
6317
|
+
"Metadata API version shouldn't be at least 3");
|
|
6318
|
+
|
|
6319
|
+
mtx_destroy(&rkb.rkb_lock);
|
|
6320
|
+
RD_UT_PASS();
|
|
6321
|
+
}
|
|
6322
|
+
|
|
6173
6323
|
/**
|
|
6174
6324
|
* @name Unit tests
|
|
6175
6325
|
* @{
|
|
@@ -6179,6 +6329,7 @@ int unittest_broker(void) {
|
|
|
6179
6329
|
int fails = 0;
|
|
6180
6330
|
|
|
6181
6331
|
fails += rd_ut_reconnect_backoff();
|
|
6332
|
+
fails += rd_ut_ApiVersion_at_least();
|
|
6182
6333
|
|
|
6183
6334
|
return fails;
|
|
6184
6335
|
}
|