@platformatic/rdkafka 4.0.1 → 4.1.0-alpha.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.
Files changed (292) hide show
  1. package/README.md +5 -5
  2. package/bench/seed.sh +0 -0
  3. package/binding.gyp +8 -1
  4. package/ci/prepublish.js +4 -4
  5. package/config.d.ts +126 -10
  6. package/configure +0 -0
  7. package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
  8. package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
  9. package/deps/librdkafka/.semaphore/semaphore.yml +67 -44
  10. package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
  11. package/deps/librdkafka/CHANGELOG.md +471 -1
  12. package/deps/librdkafka/CONFIGURATION.md +29 -9
  13. package/deps/librdkafka/INTRODUCTION.md +909 -601
  14. package/deps/librdkafka/LICENSES.txt +592 -1
  15. package/deps/librdkafka/Makefile +2 -1
  16. package/deps/librdkafka/configure +0 -0
  17. package/deps/librdkafka/debian/rules +0 -0
  18. package/deps/librdkafka/dev-conf.sh +0 -0
  19. package/deps/librdkafka/examples/consumer.c +18 -8
  20. package/deps/librdkafka/examples/describe_consumer_groups.c +25 -6
  21. package/deps/librdkafka/examples/incremental_alter_configs.c +4 -5
  22. package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +26 -42
  23. package/deps/librdkafka/examples/openssl_engine_example.cpp +3 -4
  24. package/deps/librdkafka/examples/producer.cpp +2 -2
  25. package/deps/librdkafka/examples/user_scram.c +4 -5
  26. package/deps/librdkafka/examples/win_ssl_cert_store.cpp +4 -3
  27. package/deps/librdkafka/lds-gen.py +0 -0
  28. package/deps/librdkafka/mklove/Makefile.base +0 -0
  29. package/deps/librdkafka/packaging/RELEASE.md +8 -0
  30. package/deps/librdkafka/packaging/alpine/build-alpine.sh +0 -0
  31. package/deps/librdkafka/packaging/cp/README.md +4 -1
  32. package/deps/librdkafka/packaging/cp/check_features.c +12 -4
  33. package/deps/librdkafka/packaging/cp/verify-deb.sh +6 -6
  34. package/deps/librdkafka/packaging/cp/verify-packages.sh +52 -31
  35. package/deps/librdkafka/packaging/cp/verify-rpm.sh +6 -13
  36. package/deps/librdkafka/packaging/debian/rules +0 -0
  37. package/deps/librdkafka/packaging/get_version.py +0 -0
  38. package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +0 -0
  39. package/deps/librdkafka/packaging/mingw-w64/{travis-before-install.sh → export-variables.sh} +0 -7
  40. package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +1 -1
  41. package/deps/librdkafka/packaging/nuget/artifact.py +0 -0
  42. package/deps/librdkafka/packaging/nuget/cleanup-s3.py +0 -0
  43. package/deps/librdkafka/packaging/nuget/nuget.sh +0 -0
  44. package/deps/librdkafka/packaging/nuget/packaging.py +0 -0
  45. package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +0 -0
  46. package/deps/librdkafka/packaging/nuget/release.py +0 -0
  47. package/deps/librdkafka/packaging/nuget/requirements.txt +3 -3
  48. package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +0 -0
  49. package/deps/librdkafka/packaging/rpm/tests/run-test.sh +0 -0
  50. package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +0 -0
  51. package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +3 -1
  52. package/deps/librdkafka/packaging/tools/build-deb-package.sh +0 -0
  53. package/deps/librdkafka/packaging/tools/build-debian.sh +0 -0
  54. package/deps/librdkafka/packaging/tools/build-manylinux.sh +0 -0
  55. package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +0 -0
  56. package/deps/librdkafka/packaging/tools/distro-build.sh +0 -0
  57. package/deps/librdkafka/packaging/tools/gh-release-checksums.py +0 -0
  58. package/deps/librdkafka/packaging/tools/rdutcoverage.sh +0 -0
  59. package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
  60. package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
  61. package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
  62. package/deps/librdkafka/packaging/tools/style-format.sh +6 -5
  63. package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
  64. package/deps/librdkafka/service.yml +154 -0
  65. package/deps/librdkafka/src/generate_proto.sh +0 -0
  66. package/deps/librdkafka/src/rd.h +145 -2
  67. package/deps/librdkafka/src/rdaddr.h +6 -7
  68. package/deps/librdkafka/src/rdatomic.h +15 -11
  69. package/deps/librdkafka/src/rdavg.h +3 -2
  70. package/deps/librdkafka/src/rdbase64.c +33 -2
  71. package/deps/librdkafka/src/rdbase64.h +2 -0
  72. package/deps/librdkafka/src/rdendian.h +10 -9
  73. package/deps/librdkafka/src/rdhttp.c +418 -100
  74. package/deps/librdkafka/src/rdhttp.h +23 -5
  75. package/deps/librdkafka/src/rdkafka.c +299 -145
  76. package/deps/librdkafka/src/rdkafka.h +89 -6
  77. package/deps/librdkafka/src/rdkafka_admin.c +482 -105
  78. package/deps/librdkafka/src/rdkafka_admin.h +42 -0
  79. package/deps/librdkafka/src/rdkafka_broker.c +463 -312
  80. package/deps/librdkafka/src/rdkafka_broker.h +68 -10
  81. package/deps/librdkafka/src/rdkafka_buf.c +8 -5
  82. package/deps/librdkafka/src/rdkafka_buf.h +4 -3
  83. package/deps/librdkafka/src/rdkafka_cert.c +25 -1
  84. package/deps/librdkafka/src/rdkafka_cert.h +4 -3
  85. package/deps/librdkafka/src/rdkafka_cgrp.c +468 -143
  86. package/deps/librdkafka/src/rdkafka_cgrp.h +36 -2
  87. package/deps/librdkafka/src/rdkafka_conf.c +526 -102
  88. package/deps/librdkafka/src/rdkafka_conf.h +68 -4
  89. package/deps/librdkafka/src/rdkafka_feature.c +472 -35
  90. package/deps/librdkafka/src/rdkafka_feature.h +2 -0
  91. package/deps/librdkafka/src/rdkafka_fetcher.c +22 -2
  92. package/deps/librdkafka/src/rdkafka_fetcher.h +2 -2
  93. package/deps/librdkafka/src/rdkafka_int.h +84 -46
  94. package/deps/librdkafka/src/rdkafka_metadata.c +221 -136
  95. package/deps/librdkafka/src/rdkafka_metadata.h +15 -11
  96. package/deps/librdkafka/src/rdkafka_metadata_cache.c +279 -73
  97. package/deps/librdkafka/src/rdkafka_mock.c +795 -19
  98. package/deps/librdkafka/src/rdkafka_mock.h +119 -0
  99. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1298 -132
  100. package/deps/librdkafka/src/rdkafka_mock_handlers.c +345 -49
  101. package/deps/librdkafka/src/rdkafka_mock_int.h +180 -61
  102. package/deps/librdkafka/src/rdkafka_msg.c +35 -19
  103. package/deps/librdkafka/src/rdkafka_msg.h +3 -3
  104. package/deps/librdkafka/src/rdkafka_msgset_writer.c +14 -10
  105. package/deps/librdkafka/src/rdkafka_offset.c +33 -5
  106. package/deps/librdkafka/src/rdkafka_op.c +1 -1
  107. package/deps/librdkafka/src/rdkafka_op.h +45 -21
  108. package/deps/librdkafka/src/rdkafka_partition.c +118 -23
  109. package/deps/librdkafka/src/rdkafka_partition.h +16 -7
  110. package/deps/librdkafka/src/rdkafka_proto.h +4 -1
  111. package/deps/librdkafka/src/rdkafka_protocol.h +1 -0
  112. package/deps/librdkafka/src/rdkafka_queue.c +125 -48
  113. package/deps/librdkafka/src/rdkafka_queue.h +19 -0
  114. package/deps/librdkafka/src/rdkafka_range_assignor.c +1 -1
  115. package/deps/librdkafka/src/rdkafka_request.c +336 -64
  116. package/deps/librdkafka/src/rdkafka_request.h +24 -1
  117. package/deps/librdkafka/src/rdkafka_sasl.c +5 -3
  118. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +14 -10
  119. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1166 -89
  120. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +13 -3
  121. package/deps/librdkafka/src/rdkafka_sasl_plain.c +3 -3
  122. package/deps/librdkafka/src/rdkafka_sasl_scram.c +4 -3
  123. package/deps/librdkafka/src/rdkafka_ssl.c +306 -81
  124. package/deps/librdkafka/src/rdkafka_ssl.h +22 -0
  125. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4 -0
  126. package/deps/librdkafka/src/rdkafka_telemetry.c +80 -23
  127. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +5 -1
  128. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +20 -20
  129. package/deps/librdkafka/src/rdkafka_topic.c +220 -137
  130. package/deps/librdkafka/src/rdkafka_topic.h +14 -8
  131. package/deps/librdkafka/src/rdkafka_transport.c +59 -47
  132. package/deps/librdkafka/src/rdkafka_transport.h +5 -0
  133. package/deps/librdkafka/src/rdkafka_txnmgr.c +6 -1
  134. package/deps/librdkafka/src/rdmap.c +6 -1
  135. package/deps/librdkafka/src/rdrand.c +11 -1
  136. package/deps/librdkafka/src/rdtime.h +48 -17
  137. package/deps/librdkafka/src/rdunittest.c +42 -25
  138. package/deps/librdkafka/src/rdunittest.h +2 -0
  139. package/deps/librdkafka/src/rdwin32.h +1 -1
  140. package/deps/librdkafka/src/regexp.c +47 -42
  141. package/deps/librdkafka/src/tinycthread_extra.c +45 -21
  142. package/deps/librdkafka/src/tinycthread_extra.h +7 -3
  143. package/deps/librdkafka/src-cpp/rdkafkacpp.h +28 -2
  144. package/deps/librdkafka/tests/0001-multiobj.c +4 -0
  145. package/deps/librdkafka/tests/0004-conf.c +103 -36
  146. package/deps/librdkafka/tests/0009-mock_cluster.c +1 -0
  147. package/deps/librdkafka/tests/0011-produce_batch.c +2 -1
  148. package/deps/librdkafka/tests/0016-client_swname.c +18 -3
  149. package/deps/librdkafka/tests/0017-compression.c +6 -8
  150. package/deps/librdkafka/tests/0018-cgrp_term.c +8 -3
  151. package/deps/librdkafka/tests/0021-rkt_destroy.c +1 -0
  152. package/deps/librdkafka/tests/0022-consume_batch.c +4 -1
  153. package/deps/librdkafka/tests/0026-consume_pause.c +12 -14
  154. package/deps/librdkafka/tests/0028-long_topicnames.c +1 -1
  155. package/deps/librdkafka/tests/0029-assign_offset.c +6 -8
  156. package/deps/librdkafka/tests/0030-offset_commit.c +2 -2
  157. package/deps/librdkafka/tests/0033-regex_subscribe.c +33 -17
  158. package/deps/librdkafka/tests/0034-offset_reset.c +25 -4
  159. package/deps/librdkafka/tests/0036-partial_fetch.c +1 -0
  160. package/deps/librdkafka/tests/0038-performance.c +1 -0
  161. package/deps/librdkafka/tests/0040-io_event.c +11 -5
  162. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +1 -0
  163. package/deps/librdkafka/tests/0044-partition_cnt.c +3 -2
  164. package/deps/librdkafka/tests/0045-subscribe_update.c +284 -20
  165. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +1 -0
  166. package/deps/librdkafka/tests/0048-partitioner.c +1 -1
  167. package/deps/librdkafka/tests/0050-subscribe_adds.c +1 -0
  168. package/deps/librdkafka/tests/0051-assign_adds.c +1 -0
  169. package/deps/librdkafka/tests/0052-msg_timestamps.c +22 -4
  170. package/deps/librdkafka/tests/0053-stats_cb.cpp +12 -20
  171. package/deps/librdkafka/tests/0055-producer_latency.c +176 -3
  172. package/deps/librdkafka/tests/0056-balanced_group_mt.c +6 -2
  173. package/deps/librdkafka/tests/0058-log.cpp +3 -3
  174. package/deps/librdkafka/tests/0059-bsearch.cpp +8 -4
  175. package/deps/librdkafka/tests/0061-consumer_lag.cpp +25 -5
  176. package/deps/librdkafka/tests/0067-empty_topic.cpp +3 -0
  177. package/deps/librdkafka/tests/0068-produce_timeout.c +21 -23
  178. package/deps/librdkafka/tests/0069-consumer_add_parts.c +3 -7
  179. package/deps/librdkafka/tests/0075-retry.c +38 -1
  180. package/deps/librdkafka/tests/0076-produce_retry.c +2 -0
  181. package/deps/librdkafka/tests/0077-compaction.c +8 -2
  182. package/deps/librdkafka/tests/0080-admin_ut.c +34 -4
  183. package/deps/librdkafka/tests/0081-admin.c +455 -155
  184. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +4 -0
  185. package/deps/librdkafka/tests/0083-cb_event.c +8 -3
  186. package/deps/librdkafka/tests/0084-destroy_flags.c +14 -18
  187. package/deps/librdkafka/tests/0085-headers.cpp +4 -0
  188. package/deps/librdkafka/tests/0086-purge.c +40 -7
  189. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +1 -1
  190. package/deps/librdkafka/tests/0089-max_poll_interval.c +12 -7
  191. package/deps/librdkafka/tests/0090-idempotence.c +1 -2
  192. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +5 -7
  193. package/deps/librdkafka/tests/0092-mixed_msgver.c +6 -0
  194. package/deps/librdkafka/tests/0093-holb.c +8 -5
  195. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +1 -0
  196. package/deps/librdkafka/tests/0097-ssl_verify.cpp +262 -70
  197. package/deps/librdkafka/tests/0098-consumer-txn.cpp +16 -16
  198. package/deps/librdkafka/tests/0099-commit_metadata.c +1 -1
  199. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +1 -1
  200. package/deps/librdkafka/tests/0102-static_group_rebalance.c +317 -16
  201. package/deps/librdkafka/tests/0103-transactions.c +7 -7
  202. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +1 -0
  203. package/deps/librdkafka/tests/0105-transactions_mock.c +18 -11
  204. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +35 -14
  205. package/deps/librdkafka/tests/0107-topic_recreate.c +2 -2
  206. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +86 -26
  207. package/deps/librdkafka/tests/0110-batch_size.cpp +1 -2
  208. package/deps/librdkafka/tests/0112-assign_unknown_part.c +3 -14
  209. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +248 -104
  210. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +3 -3
  211. package/deps/librdkafka/tests/0115-producer_auth.cpp +4 -1
  212. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +7 -5
  213. package/deps/librdkafka/tests/0117-mock_errors.c +15 -5
  214. package/deps/librdkafka/tests/0118-commit_rebalance.c +41 -8
  215. package/deps/librdkafka/tests/0119-consumer_auth.cpp +20 -1
  216. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +8 -3
  217. package/deps/librdkafka/tests/0125-immediate_flush.c +1 -1
  218. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +323 -8
  219. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +1 -0
  220. package/deps/librdkafka/tests/0132-strategy_ordering.c +12 -4
  221. package/deps/librdkafka/tests/0133-ssl_keys.c +28 -6
  222. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +24 -14
  223. package/deps/librdkafka/tests/0139-offset_validation_mock.c +510 -2
  224. package/deps/librdkafka/tests/0140-commit_metadata.cpp +1 -1
  225. package/deps/librdkafka/tests/0142-reauthentication.c +37 -17
  226. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +39 -40
  227. package/deps/librdkafka/tests/0146-metadata_mock.c +76 -15
  228. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
  229. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
  230. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  231. package/deps/librdkafka/tests/0150-telemetry_mock.c +9 -6
  232. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  233. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  234. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  235. package/deps/librdkafka/tests/CMakeLists.txt +6 -0
  236. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +34 -9
  237. package/deps/librdkafka/tests/autotest.sh +0 -0
  238. package/deps/librdkafka/tests/broker_version_tests.py +0 -0
  239. package/deps/librdkafka/tests/buildbox.sh +0 -0
  240. package/deps/librdkafka/tests/cleanup-checker-tests.sh +0 -0
  241. package/deps/librdkafka/tests/cluster_testing.py +0 -0
  242. package/deps/librdkafka/tests/delete-test-topics.sh +0 -0
  243. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  244. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  245. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  246. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  247. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +42 -101
  248. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  249. package/deps/librdkafka/tests/fixtures/ssl/client2.key +41 -29
  250. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +112 -37
  251. package/deps/librdkafka/tests/gen-ssl-certs.sh +0 -0
  252. package/deps/librdkafka/tests/interactive_broker_version.py +0 -0
  253. package/deps/librdkafka/tests/java/Makefile +2 -1
  254. package/deps/librdkafka/tests/java/run-class.sh +0 -0
  255. package/deps/librdkafka/tests/lz4_manual_test.sh +0 -0
  256. package/deps/librdkafka/tests/multi-broker-version-test.sh +0 -0
  257. package/deps/librdkafka/tests/parse-refcnt.sh +0 -0
  258. package/deps/librdkafka/tests/performance_plot.py +0 -0
  259. package/deps/librdkafka/tests/requirements.txt +1 -1
  260. package/deps/librdkafka/tests/run-all-tests.sh +79 -0
  261. package/deps/librdkafka/tests/run-consumer-tests.sh +0 -0
  262. package/deps/librdkafka/tests/run-producer-tests.sh +0 -0
  263. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  264. package/deps/librdkafka/tests/run-test.sh +0 -0
  265. package/deps/librdkafka/tests/sasl_test.py +0 -0
  266. package/deps/librdkafka/tests/test.c +478 -18
  267. package/deps/librdkafka/tests/test.h +62 -13
  268. package/deps/librdkafka/tests/testcpp.cpp +6 -1
  269. package/deps/librdkafka/tests/testcpp.h +30 -2
  270. package/deps/librdkafka/tests/testshared.h +16 -2
  271. package/deps/librdkafka/tests/tools/stats/graph.py +0 -0
  272. package/deps/librdkafka/tests/tools/stats/to_csv.py +1 -1
  273. package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
  274. package/deps/librdkafka/tests/until-fail.sh +0 -0
  275. package/deps/librdkafka/tests/xxxx-metadata.cpp +1 -1
  276. package/deps/librdkafka/vcpkg.json +1 -1
  277. package/deps/librdkafka/win32/setup-msys2.ps1 +24 -8
  278. package/deps/librdkafka/win32/setup-vcpkg.ps1 +28 -6
  279. package/deps/librdkafka/win32/tests/tests.vcxproj +6 -0
  280. package/deps/librdkafka/win32/wingetopt.h +5 -4
  281. package/errors.d.ts +27 -1
  282. package/lib/error.js +29 -3
  283. package/make_docs.sh +0 -0
  284. package/package.json +10 -11
  285. package/run_docker.sh +0 -0
  286. package/src/callbacks.cc +6 -9
  287. package/src/callbacks.h +1 -5
  288. package/test/kafka-consumer-worker.js +10 -7
  289. package/test/kafka-consumer.spec.js +32 -21
  290. package/deps/librdkafka/.semaphore/project.yml +0 -43
  291. package/deps/librdkafka/.semaphore/project_public.yml +0 -20
  292. package/deps/librdkafka/win32/install-openssl.ps1 +0 -33
@@ -404,7 +404,9 @@ static const struct rd_kafka_err_desc rd_kafka_err_descs[] = {
404
404
  _ERR_DESC(RD_KAFKA_RESP_ERR__BAD_MSG, "Local: Bad message format"),
405
405
  _ERR_DESC(RD_KAFKA_RESP_ERR__BAD_COMPRESSION,
406
406
  "Local: Invalid compressed data"),
407
- _ERR_DESC(RD_KAFKA_RESP_ERR__DESTROY, "Local: Broker handle destroyed"),
407
+ _ERR_DESC(RD_KAFKA_RESP_ERR__DESTROY,
408
+ "Local: Broker handle destroyed "
409
+ "for termination"),
408
410
  _ERR_DESC(
409
411
  RD_KAFKA_RESP_ERR__FAIL,
410
412
  "Local: Communication failure with broker"), // FIXME: too specific
@@ -488,7 +490,9 @@ static const struct rd_kafka_err_desc rd_kafka_err_descs[] = {
488
490
  "Local: Partition log truncation detected"),
489
491
  _ERR_DESC(RD_KAFKA_RESP_ERR__INVALID_DIFFERENT_RECORD,
490
492
  "Local: an invalid record in the same batch caused "
491
- "the failure of this message too."),
493
+ "the failure of this message too"),
494
+ _ERR_DESC(RD_KAFKA_RESP_ERR__DESTROY_BROKER,
495
+ "Local: Broker handle destroyed without termination"),
492
496
 
493
497
  _ERR_DESC(RD_KAFKA_RESP_ERR_UNKNOWN, "Unknown broker error"),
494
498
  _ERR_DESC(RD_KAFKA_RESP_ERR_NO_ERROR, "Success"),
@@ -714,6 +718,9 @@ static const struct rd_kafka_err_desc rd_kafka_err_descs[] = {
714
718
  _ERR_DESC(RD_KAFKA_RESP_ERR_TELEMETRY_TOO_LARGE,
715
719
  "Broker: Client sent a push telemetry request larger than the "
716
720
  "maximum size the broker will accept"),
721
+ _ERR_DESC(RD_KAFKA_RESP_ERR_REBOOTSTRAP_REQUIRED,
722
+ "Broker: Client metadata is stale, "
723
+ "client should rebootstrap to obtain new metadata"),
717
724
  _ERR_DESC(RD_KAFKA_RESP_ERR__END, NULL)};
718
725
 
719
726
 
@@ -925,7 +932,29 @@ rd_kafka_resp_err_t rd_kafka_test_fatal_error(rd_kafka_t *rk,
925
932
  return RD_KAFKA_RESP_ERR_NO_ERROR;
926
933
  }
927
934
 
928
-
935
+ /**
936
+ * @brief Called when a broker thread is decommissioned.
937
+ * on the main thread to join the corresponding thread
938
+ * and remove it from the wait lists.
939
+ *
940
+ * @locality main thread
941
+ */
942
+ void rd_kafka_decommissioned_broker_thread_join(rd_kafka_t *rk,
943
+ void *rkb_decommissioned) {
944
+ thrd_t *thrd;
945
+ int i;
946
+ RD_LIST_FOREACH(thrd, &rk->wait_decommissioned_thrds, i) {
947
+ void *rkb = rd_list_elem(&rk->wait_decommissioned_brokers, i);
948
+ if (rkb == rkb_decommissioned) {
949
+ rd_list_remove_elem(&rk->wait_decommissioned_thrds, i);
950
+ rd_list_remove_elem(&rk->wait_decommissioned_brokers,
951
+ i);
952
+ thrd_join(*thrd, NULL);
953
+ rd_free(thrd);
954
+ i--;
955
+ }
956
+ }
957
+ }
929
958
 
930
959
  /**
931
960
  * @brief Final destructor for rd_kafka_t, must only be called with refcnt 0.
@@ -1017,8 +1046,7 @@ void rd_kafka_destroy_final(rd_kafka_t *rk) {
1017
1046
  cnd_destroy(&rk->rk_init_cnd);
1018
1047
  mtx_destroy(&rk->rk_init_lock);
1019
1048
 
1020
- if (rk->rk_full_metadata)
1021
- rd_kafka_metadata_destroy(&rk->rk_full_metadata->metadata);
1049
+
1022
1050
  rd_kafkap_str_destroy(rk->rk_client_id);
1023
1051
  rd_kafkap_str_destroy(rk->rk_group_id);
1024
1052
  rd_kafkap_str_destroy(rk->rk_eos.transactional_id);
@@ -1168,8 +1196,8 @@ void rd_kafka_destroy_flags(rd_kafka_t *rk, int flags) {
1168
1196
  */
1169
1197
  static void rd_kafka_destroy_internal(rd_kafka_t *rk) {
1170
1198
  rd_kafka_topic_t *rkt, *rkt_tmp;
1171
- rd_kafka_broker_t *rkb, *rkb_tmp;
1172
- rd_list_t wait_thrds;
1199
+ rd_kafka_broker_t *rkb;
1200
+ rd_list_t wait_thrds, brokers_to_decommission;
1173
1201
  thrd_t *thrd;
1174
1202
  int i;
1175
1203
 
@@ -1212,32 +1240,24 @@ static void rd_kafka_destroy_internal(rd_kafka_t *rk) {
1212
1240
  }
1213
1241
 
1214
1242
  /* Decommission brokers.
1215
- * Broker thread holds a refcount and detects when broker refcounts
1216
- * reaches 1 and then decommissions itself. */
1217
- TAILQ_FOREACH_SAFE(rkb, &rk->rk_brokers, rkb_link, rkb_tmp) {
1218
- /* Add broker's thread to wait_thrds list for later joining */
1219
- thrd = rd_malloc(sizeof(*thrd));
1220
- *thrd = rkb->rkb_thread;
1221
- rd_list_add(&wait_thrds, thrd);
1222
- rd_kafka_wrunlock(rk);
1223
-
1224
- rd_kafka_dbg(rk, BROKER, "DESTROY", "Sending TERMINATE to %s",
1225
- rd_kafka_broker_name(rkb));
1226
- /* Send op to trigger queue/io wake-up.
1227
- * The op itself is (likely) ignored by the broker thread. */
1228
- rd_kafka_q_enq(rkb->rkb_ops,
1229
- rd_kafka_op_new(RD_KAFKA_OP_TERMINATE));
1230
-
1231
- #ifndef _WIN32
1232
- /* Interrupt IO threads to speed up termination. */
1233
- if (rk->rk_conf.term_sig)
1234
- pthread_kill(rkb->rkb_thread, rk->rk_conf.term_sig);
1235
- #endif
1236
-
1237
- rd_kafka_broker_destroy(rkb);
1243
+ * `rd_kafka_broker_decommission` releases and reacquires
1244
+ * the lock so there could be destroyed brokers in
1245
+ * `rk->rk_brokers` */
1246
+ rd_list_init(&brokers_to_decommission,
1247
+ rd_atomic32_get(&rk->rk_broker_cnt), NULL);
1248
+ TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
1249
+ /* Don't try to decommission already decommissioning brokers
1250
+ * otherwise they could be already destroyed when
1251
+ * `rd_kafka_broker_decommission` is called below. */
1252
+ if (rd_list_find(&rk->wait_decommissioned_brokers, rkb,
1253
+ rd_list_cmp_ptr) == NULL)
1254
+ rd_list_add(&brokers_to_decommission, rkb);
1255
+ }
1238
1256
 
1239
- rd_kafka_wrlock(rk);
1257
+ RD_LIST_FOREACH(rkb, &brokers_to_decommission, i) {
1258
+ rd_kafka_broker_decommission(rk, rkb, &wait_thrds);
1240
1259
  }
1260
+ rd_list_destroy(&brokers_to_decommission);
1241
1261
 
1242
1262
  if (rk->rk_clusterid) {
1243
1263
  rd_free(rk->rk_clusterid);
@@ -1279,22 +1299,23 @@ static void rd_kafka_destroy_internal(rd_kafka_t *rk) {
1279
1299
 
1280
1300
  /* Loose our special reference to the internal broker. */
1281
1301
  mtx_lock(&rk->rk_internal_rkb_lock);
1282
- if ((rkb = rk->rk_internal_rkb)) {
1302
+ if (rk->rk_internal_rkb) {
1283
1303
  rd_kafka_dbg(rk, GENERIC, "TERMINATE",
1284
1304
  "Decommissioning internal broker");
1285
1305
 
1286
- /* Send op to trigger queue wake-up. */
1287
- rd_kafka_q_enq(rkb->rkb_ops,
1306
+ thrd = rd_malloc(sizeof(*thrd));
1307
+ *thrd = rk->rk_internal_rkb->rkb_thread;
1308
+
1309
+ /* Send op to trigger queue wake-up.
1310
+ * WARNING: This is last time we can read
1311
+ * from rk_internal_rkb in this thread! */
1312
+ rd_kafka_q_enq(rk->rk_internal_rkb->rkb_ops,
1288
1313
  rd_kafka_op_new(RD_KAFKA_OP_TERMINATE));
1289
1314
 
1290
1315
  rk->rk_internal_rkb = NULL;
1291
- thrd = rd_malloc(sizeof(*thrd));
1292
- *thrd = rkb->rkb_thread;
1293
1316
  rd_list_add(&wait_thrds, thrd);
1294
1317
  }
1295
1318
  mtx_unlock(&rk->rk_internal_rkb_lock);
1296
- if (rkb)
1297
- rd_kafka_broker_destroy(rkb);
1298
1319
 
1299
1320
 
1300
1321
  rd_kafka_dbg(rk, GENERIC, "TERMINATE", "Join %d broker thread(s)",
@@ -1310,6 +1331,17 @@ static void rd_kafka_destroy_internal(rd_kafka_t *rk) {
1310
1331
 
1311
1332
  rd_list_destroy(&wait_thrds);
1312
1333
 
1334
+ /* Join previously decommissioned broker threads */
1335
+ RD_LIST_FOREACH(thrd, &rk->wait_decommissioned_thrds, i) {
1336
+ int res;
1337
+ if (thrd_join(*thrd, &res) != thrd_success)
1338
+ ;
1339
+ rd_free(thrd);
1340
+ }
1341
+ rd_list_destroy(&rk->additional_brokerlists);
1342
+ rd_list_destroy(&rk->wait_decommissioned_brokers);
1343
+ rd_list_destroy(&rk->wait_decommissioned_thrds);
1344
+
1313
1345
  /* Destroy mock cluster */
1314
1346
  if (rk->rk_mock.cluster)
1315
1347
  rd_kafka_mock_cluster_destroy(rk->rk_mock.cluster);
@@ -1434,9 +1466,7 @@ static RD_INLINE void rd_kafka_stats_emit_toppar(struct _stats_emit *st,
1434
1466
  rd_kafka_toppar_lock(rktp);
1435
1467
 
1436
1468
  if (rktp->rktp_broker) {
1437
- rd_kafka_broker_lock(rktp->rktp_broker);
1438
1469
  broker_id = rktp->rktp_broker->rkb_nodeid;
1439
- rd_kafka_broker_unlock(rktp->rktp_broker);
1440
1470
  }
1441
1471
 
1442
1472
  /* Grab a copy of the latest finalized offset stats */
@@ -1660,6 +1690,7 @@ static void rd_kafka_stats_emit_broker_reqs(struct _stats_emit *st,
1660
1690
  [RD_KAFKAP_AlterClientQuotas] = rd_true,
1661
1691
  [RD_KAFKAP_DescribeUserScramCredentials] = rd_true,
1662
1692
  [RD_KAFKAP_AlterUserScramCredentials] = rd_true,
1693
+ [RD_KAFKAP_ConsumerGroupDescribe] = rd_true,
1663
1694
  }};
1664
1695
  int i;
1665
1696
  int cnt = 0;
@@ -2029,6 +2060,85 @@ static void rd_kafka_1s_tmr_cb(rd_kafka_timers_t *rkts, void *arg) {
2029
2060
  rd_kafka_coord_cache_expire(&rk->rk_coord_cache);
2030
2061
  }
2031
2062
 
2063
+ /**
2064
+ * @brief Reset broker down reported flag for all brokers.
2065
+ * In case it was set to 1 it will be reset to 0 and
2066
+ * the broker down count will be decremented.
2067
+ *
2068
+ * @locks none
2069
+ * @locks_acquired rd_kafka_rdlock()
2070
+ * @locality any
2071
+ */
2072
+ void rd_kafka_reset_any_broker_down_reported(rd_kafka_t *rk) {
2073
+ rd_kafka_broker_t *rkb;
2074
+ rd_kafka_rdlock(rk);
2075
+ TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
2076
+ if (rd_atomic32_set(&rkb->rkb_down_reported, 0) == 1)
2077
+ rd_atomic32_sub(&rk->rk_broker_down_cnt, 1);
2078
+ }
2079
+ rd_kafka_rdunlock(rk);
2080
+ }
2081
+
2082
+ /**
2083
+ * @brief Re-bootstrap timer callback.
2084
+ *
2085
+ * @locality rdkafka main thread
2086
+ * @locks none
2087
+ */
2088
+ static void rd_kafka_rebootstrap_tmr_cb(rd_kafka_timers_t *rkts, void *arg) {
2089
+ int i;
2090
+ char *brokerlist;
2091
+ rd_kafka_t *rk = rkts->rkts_rk;
2092
+ rd_list_t additional_brokerlists;
2093
+
2094
+ rd_dassert(thrd_is_current(rk->rk_thread));
2095
+ if (rd_kafka_terminating(rk))
2096
+ /* Avoid re-bootstrapping while terminating */
2097
+ return;
2098
+
2099
+ rd_dassert(rk->rk_conf.metadata_recovery_strategy !=
2100
+ RD_KAFKA_METADATA_RECOVERY_STRATEGY_NONE);
2101
+ if (rk->rk_conf.metadata_recovery_strategy ==
2102
+ RD_KAFKA_METADATA_RECOVERY_STRATEGY_NONE)
2103
+ /* This function should not be called in this case.
2104
+ * this is just a fail-safe. */
2105
+ return;
2106
+
2107
+ rd_kafka_dbg(rk, ALL, "REBOOTSTRAP", "Starting re-bootstrap sequence");
2108
+
2109
+ rd_atomic32_set(&rk->rk_rebootstrap_in_progress, 1);
2110
+ rd_kafka_reset_any_broker_down_reported(rk);
2111
+
2112
+ if (rk->rk_conf.brokerlist) {
2113
+ rd_kafka_brokers_add0(
2114
+ rk,
2115
+ rk->rk_conf.brokerlist, rd_true
2116
+ /* resolve canonical bootstrap server
2117
+ * list names if requested*/);
2118
+ }
2119
+
2120
+ rd_kafka_rdlock(rk);
2121
+ if (rd_list_cnt(&rk->additional_brokerlists) == 0) {
2122
+ rd_kafka_rdunlock(rk);
2123
+ goto done;
2124
+ }
2125
+
2126
+ rd_list_init_copy(&additional_brokerlists, &rk->additional_brokerlists);
2127
+ rd_list_copy_to(&additional_brokerlists, &rk->additional_brokerlists,
2128
+ rd_list_string_copy, NULL);
2129
+ rd_kafka_rdunlock(rk);
2130
+
2131
+ RD_LIST_FOREACH(brokerlist, &additional_brokerlists, i) {
2132
+ rd_kafka_brokers_add0(rk, brokerlist,
2133
+ rd_false
2134
+ /* don't resolve canonical bootstrap server list
2135
+ * names even if requested */);
2136
+ }
2137
+ rd_list_destroy(&additional_brokerlists);
2138
+ done:
2139
+ rd_atomic32_set(&rk->rk_rebootstrap_in_progress, 0);
2140
+ }
2141
+
2032
2142
  static void rd_kafka_stats_emit_tmr_cb(rd_kafka_timers_t *rkts, void *arg) {
2033
2143
  rd_kafka_t *rk = rkts->rkts_rk;
2034
2144
  rd_kafka_stats_emit_all(rk);
@@ -2082,15 +2192,15 @@ static void rd_kafka_metadata_refresh_cb(rd_kafka_timers_t *rkts, void *arg) {
2082
2192
  * @locks none
2083
2193
  */
2084
2194
  static int rd_kafka_init_wait(rd_kafka_t *rk, int timeout_ms) {
2085
- struct timespec tspec;
2086
2195
  int ret;
2196
+ rd_ts_t abs_timeout;
2087
2197
 
2088
- rd_timeout_init_timespec(&tspec, timeout_ms);
2198
+ abs_timeout = rd_timeout_init(timeout_ms);
2089
2199
 
2090
2200
  mtx_lock(&rk->rk_init_lock);
2091
2201
  while (rk->rk_init_wait_cnt > 0 &&
2092
- cnd_timedwait_abs(&rk->rk_init_cnd, &rk->rk_init_lock, &tspec) ==
2093
- thrd_success)
2202
+ cnd_timedwait_abs(&rk->rk_init_cnd, &rk->rk_init_lock,
2203
+ abs_timeout) == thrd_success)
2094
2204
  ;
2095
2205
  ret = rk->rk_init_wait_cnt;
2096
2206
  mtx_unlock(&rk->rk_init_lock);
@@ -2103,10 +2213,8 @@ static int rd_kafka_init_wait(rd_kafka_t *rk, int timeout_ms) {
2103
2213
  * Main loop for Kafka handler thread.
2104
2214
  */
2105
2215
  static int rd_kafka_thread_main(void *arg) {
2106
- rd_kafka_t *rk = arg;
2107
- rd_kafka_timer_t tmr_1s = RD_ZERO_INIT;
2108
- rd_kafka_timer_t tmr_stats_emit = RD_ZERO_INIT;
2109
- rd_kafka_timer_t tmr_metadata_refresh = RD_ZERO_INIT;
2216
+ rd_kafka_t *rk = arg;
2217
+ rd_kafka_timer_t tmr_stats_emit = RD_ZERO_INIT;
2110
2218
 
2111
2219
  rd_kafka_set_thread_name("main");
2112
2220
  rd_kafka_set_thread_sysname("rdk:main");
@@ -2121,14 +2229,14 @@ static int rd_kafka_thread_main(void *arg) {
2121
2229
  rd_kafka_wrunlock(rk);
2122
2230
 
2123
2231
  /* 1 second timer for topic scan and connection checking. */
2124
- rd_kafka_timer_start(&rk->rk_timers, &tmr_1s, 1000000,
2232
+ rd_kafka_timer_start(&rk->rk_timers, &rk->one_s_tmr, 1000000,
2125
2233
  rd_kafka_1s_tmr_cb, NULL);
2126
2234
  if (rk->rk_conf.stats_interval_ms)
2127
2235
  rd_kafka_timer_start(&rk->rk_timers, &tmr_stats_emit,
2128
2236
  rk->rk_conf.stats_interval_ms * 1000ll,
2129
2237
  rd_kafka_stats_emit_tmr_cb, NULL);
2130
2238
  if (rk->rk_conf.metadata_refresh_interval_ms > 0)
2131
- rd_kafka_timer_start(&rk->rk_timers, &tmr_metadata_refresh,
2239
+ rd_kafka_timer_start(&rk->rk_timers, &rk->metadata_refresh_tmr,
2132
2240
  rk->rk_conf.metadata_refresh_interval_ms *
2133
2241
  1000ll,
2134
2242
  rd_kafka_metadata_refresh_cb, NULL);
@@ -2168,10 +2276,10 @@ static int rd_kafka_thread_main(void *arg) {
2168
2276
  rd_kafka_q_disable(rk->rk_ops);
2169
2277
  rd_kafka_q_purge(rk->rk_ops);
2170
2278
 
2171
- rd_kafka_timer_stop(&rk->rk_timers, &tmr_1s, 1);
2279
+ rd_kafka_timer_stop(&rk->rk_timers, &rk->one_s_tmr, 1);
2172
2280
  if (rk->rk_conf.stats_interval_ms)
2173
2281
  rd_kafka_timer_stop(&rk->rk_timers, &tmr_stats_emit, 1);
2174
- rd_kafka_timer_stop(&rk->rk_timers, &tmr_metadata_refresh, 1);
2282
+ rd_kafka_timer_stop(&rk->rk_timers, &rk->metadata_refresh_tmr, 1);
2175
2283
 
2176
2284
  /* Synchronise state */
2177
2285
  rd_kafka_wrlock(rk);
@@ -2205,7 +2313,6 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2205
2313
  rd_kafka_resp_err_t ret_err = RD_KAFKA_RESP_ERR_NO_ERROR;
2206
2314
  int ret_errno = 0;
2207
2315
  const char *conf_err;
2208
- char *group_remote_assignor_override = NULL;
2209
2316
  #ifndef _WIN32
2210
2317
  sigset_t newset, oldset;
2211
2318
  #endif
@@ -2290,6 +2397,11 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2290
2397
 
2291
2398
  rd_atomic64_init(&rk->rk_ts_last_poll, rk->rk_ts_created);
2292
2399
  rd_atomic32_init(&rk->rk_flushing, 0);
2400
+ rd_atomic32_init(&rk->rk_broker_cnt, 0);
2401
+ rd_atomic32_init(&rk->rk_logical_broker_cnt, 0);
2402
+ rd_atomic32_init(&rk->rk_broker_up_cnt, 0);
2403
+ rd_atomic32_init(&rk->rk_broker_down_cnt, 0);
2404
+ rd_atomic32_init(&rk->rk_rebootstrap_in_progress, 0);
2293
2405
 
2294
2406
  rk->rk_rep = rd_kafka_q_new(rk);
2295
2407
  rk->rk_ops = rd_kafka_q_new(rk);
@@ -2302,6 +2414,7 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2302
2414
  rk->rk_logq->rkq_opaque = rk;
2303
2415
  }
2304
2416
 
2417
+ rd_list_init(&rk->additional_brokerlists, 0, rd_free);
2305
2418
  TAILQ_INIT(&rk->rk_brokers);
2306
2419
  TAILQ_INIT(&rk->rk_topics);
2307
2420
  rd_kafka_timers_init(&rk->rk_timers, rk, rk->rk_ops);
@@ -2309,6 +2422,8 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2309
2422
  rd_kafka_coord_cache_init(&rk->rk_coord_cache,
2310
2423
  rk->rk_conf.metadata_max_age_ms);
2311
2424
  rd_kafka_coord_reqs_init(rk);
2425
+ rd_list_init(&rk->wait_decommissioned_thrds, 0, NULL);
2426
+ rd_list_init(&rk->wait_decommissioned_brokers, 0, NULL);
2312
2427
 
2313
2428
  if (rk->rk_conf.dr_cb || rk->rk_conf.dr_msg_cb)
2314
2429
  rk->rk_drmode = RD_KAFKA_DR_MODE_CB;
@@ -2341,11 +2456,30 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2341
2456
  #if WITH_OAUTHBEARER_OIDC
2342
2457
  if (rk->rk_conf.sasl.oauthbearer.method ==
2343
2458
  RD_KAFKA_SASL_OAUTHBEARER_METHOD_OIDC &&
2344
- !rk->rk_conf.sasl.oauthbearer.token_refresh_cb)
2345
- rd_kafka_conf_set_oauthbearer_token_refresh_cb(
2346
- &rk->rk_conf, rd_kafka_oidc_token_refresh_cb);
2459
+ !rk->rk_conf.sasl.oauthbearer.token_refresh_cb) {
2460
+ /* Use JWT bearer */
2461
+ rk->rk_conf.sasl.oauthbearer.builtin_token_refresh_cb = rd_true;
2462
+
2463
+ if (rk->rk_conf.sasl.oauthbearer.metadata_authentication.type ==
2464
+ RD_KAFKA_SASL_OAUTHBEARER_METADATA_AUTHENTICATION_TYPE_AZURE_IMDS) {
2465
+ rd_kafka_conf_set_oauthbearer_token_refresh_cb(
2466
+ &rk->rk_conf,
2467
+ rd_kafka_oidc_token_metadata_azure_imds_refresh_cb);
2468
+ } else if (
2469
+ rk->rk_conf.sasl.oauthbearer.grant_type ==
2470
+ RD_KAFKA_SASL_OAUTHBEARER_GRANT_TYPE_CLIENT_CREDENTIALS) {
2471
+ rd_kafka_conf_set_oauthbearer_token_refresh_cb(
2472
+ &rk->rk_conf,
2473
+ rd_kafka_oidc_token_client_credentials_refresh_cb);
2474
+ } else {
2475
+ rd_kafka_conf_set_oauthbearer_token_refresh_cb(
2476
+ &rk->rk_conf,
2477
+ rd_kafka_oidc_token_jwt_bearer_refresh_cb);
2478
+ }
2479
+ }
2347
2480
  #endif
2348
2481
 
2482
+
2349
2483
  rk->rk_controllerid = -1;
2350
2484
 
2351
2485
  /* Admin client defaults */
@@ -2400,64 +2534,6 @@ rd_kafka_t *rd_kafka_new(rd_kafka_type_t type,
2400
2534
  goto fail;
2401
2535
  }
2402
2536
 
2403
- if (!rk->rk_conf.group_remote_assignor) {
2404
- rd_kafka_assignor_t *cooperative_assignor;
2405
-
2406
- /* Detect if chosen assignor is cooperative
2407
- * FIXME: remove this compatibility altogether
2408
- * and apply the breaking changes that will be required
2409
- * in next major version. */
2410
-
2411
- cooperative_assignor =
2412
- rd_kafka_assignor_find(rk, "cooperative-sticky");
2413
- rk->rk_conf.partition_assignors_cooperative =
2414
- !rk->rk_conf.partition_assignors.rl_cnt ||
2415
- (cooperative_assignor &&
2416
- cooperative_assignor->rkas_enabled);
2417
-
2418
- if (rk->rk_conf.group_protocol ==
2419
- RD_KAFKA_GROUP_PROTOCOL_CONSUMER) {
2420
- /* Default remote assignor to the chosen local one. */
2421
- if (rk->rk_conf.partition_assignors_cooperative) {
2422
- group_remote_assignor_override =
2423
- rd_strdup("uniform");
2424
- rk->rk_conf.group_remote_assignor =
2425
- group_remote_assignor_override;
2426
- } else {
2427
- rd_kafka_assignor_t *range_assignor =
2428
- rd_kafka_assignor_find(rk, "range");
2429
- if (range_assignor &&
2430
- range_assignor->rkas_enabled) {
2431
- rd_kafka_log(
2432
- rk, LOG_WARNING, "ASSIGNOR",
2433
- "\"range\" assignor is sticky "
2434
- "with group protocol CONSUMER");
2435
- group_remote_assignor_override =
2436
- rd_strdup("range");
2437
- rk->rk_conf.group_remote_assignor =
2438
- group_remote_assignor_override;
2439
- } else {
2440
- rd_kafka_log(
2441
- rk, LOG_WARNING, "ASSIGNOR",
2442
- "roundrobin assignor isn't "
2443
- "available "
2444
- "with group protocol CONSUMER, "
2445
- "using the \"uniform\" one. "
2446
- "It's similar, "
2447
- "but it's also sticky");
2448
- group_remote_assignor_override =
2449
- rd_strdup("uniform");
2450
- rk->rk_conf.group_remote_assignor =
2451
- group_remote_assignor_override;
2452
- }
2453
- }
2454
- }
2455
- } else {
2456
- /* When users starts setting properties of the new protocol,
2457
- * they can only use incremental_assign/unassign. */
2458
- rk->rk_conf.partition_assignors_cooperative = rd_true;
2459
- }
2460
-
2461
2537
  /* Create Mock cluster */
2462
2538
  rd_atomic32_init(&rk->rk_mock.cluster_cnt, 0);
2463
2539
  if (rk->rk_conf.mock.broker_cnt > 0) {
@@ -2750,8 +2826,6 @@ fail:
2750
2826
  * that belong to rk_conf and thus needs to be cleaned up.
2751
2827
  * Legacy APIs, sigh.. */
2752
2828
  if (app_conf) {
2753
- if (group_remote_assignor_override)
2754
- rd_free(group_remote_assignor_override);
2755
2829
  rd_kafka_assignors_term(rk);
2756
2830
  rd_kafka_interceptors_destroy(&rk->rk_conf);
2757
2831
  memset(&rk->rk_conf, 0, sizeof(rk->rk_conf));
@@ -2765,7 +2839,65 @@ fail:
2765
2839
  return NULL;
2766
2840
  }
2767
2841
 
2842
+ /**
2843
+ * Schedules a rebootstrap of the cluster immediately.
2844
+ *
2845
+ * @locks none
2846
+ * @locks_acquired rd_kafka_timers_lock()
2847
+ * @locality any
2848
+ */
2849
+ void rd_kafka_rebootstrap(rd_kafka_t *rk) {
2850
+ if (rk->rk_conf.metadata_recovery_strategy ==
2851
+ RD_KAFKA_METADATA_RECOVERY_STRATEGY_NONE)
2852
+ return;
2768
2853
 
2854
+ if (rd_atomic32_set(&rk->rk_rebootstrap_in_progress, 1) == 0) {
2855
+ /* Only when not already in progress 0 -> 1.
2856
+ * After setting down a learned broker it could reconnect and
2857
+ * disconnect again before previous reboostrap completes,
2858
+ * causing a new re-bootstrap. */
2859
+ rd_kafka_timer_start_oneshot(
2860
+ &rk->rk_timers, &rk->rebootstrap_tmr, rd_true /*restart*/,
2861
+ 0, rd_kafka_rebootstrap_tmr_cb, NULL);
2862
+ }
2863
+ }
2864
+
2865
+ /**
2866
+ * Starts rebootstrap timer with the configured interval. Only if not
2867
+ * started or stopped.
2868
+ *
2869
+ * @locks none
2870
+ * @locks_acquired rd_kafka_timers_lock()
2871
+ * @locality any
2872
+ */
2873
+ void rd_kafka_rebootstrap_tmr_start_maybe(rd_kafka_t *rk) {
2874
+ if (rk->rk_conf.metadata_recovery_strategy ==
2875
+ RD_KAFKA_METADATA_RECOVERY_STRATEGY_NONE)
2876
+ return;
2877
+
2878
+ rd_kafka_timer_start_oneshot(
2879
+ &rk->rk_timers, &rk->rebootstrap_tmr, rd_false /*don't restart*/,
2880
+ rk->rk_conf.metadata_recovery_rebootstrap_trigger_ms * 1000LL,
2881
+ rd_kafka_rebootstrap_tmr_cb, NULL);
2882
+ }
2883
+
2884
+ /**
2885
+ * Stops rebootstrap timer, for example after a successful metadata response.
2886
+ *
2887
+ * @return 1 if the timer was started (before being stopped), else 0.
2888
+ *
2889
+ * @locks none
2890
+ * @locks_acquired rd_kafka_timers_lock()
2891
+ * @locality any
2892
+ */
2893
+ int rd_kafka_rebootstrap_tmr_stop(rd_kafka_t *rk) {
2894
+ if (rk->rk_conf.metadata_recovery_strategy ==
2895
+ RD_KAFKA_METADATA_RECOVERY_STRATEGY_NONE)
2896
+ return 0;
2897
+
2898
+ return rd_kafka_timer_stop(&rk->rk_timers, &rk->rebootstrap_tmr,
2899
+ rd_true /* lock */);
2900
+ }
2769
2901
 
2770
2902
  /**
2771
2903
  * Counts usage of the legacy/simple consumer (rd_kafka_consume_start() with
@@ -3178,12 +3310,12 @@ static rd_kafka_op_res_t rd_kafka_consume_callback0(
3178
3310
  struct consume_ctx ctx = {.consume_cb = consume_cb, .opaque = opaque};
3179
3311
  rd_kafka_op_res_t res;
3180
3312
 
3181
- rd_kafka_app_poll_start(rkq->rkq_rk, 0, timeout_ms);
3313
+ rd_kafka_app_poll_start(rkq->rkq_rk, rkq, 0, timeout_ms);
3182
3314
 
3183
3315
  res = rd_kafka_q_serve(rkq, timeout_ms, max_cnt, RD_KAFKA_Q_CB_RETURN,
3184
3316
  rd_kafka_consume_cb, &ctx);
3185
3317
 
3186
- rd_kafka_app_polled(rkq->rkq_rk);
3318
+ rd_kafka_app_polled(rkq->rkq_rk, rkq);
3187
3319
 
3188
3320
  return res;
3189
3321
  }
@@ -3249,7 +3381,7 @@ rd_kafka_consume0(rd_kafka_t *rk, rd_kafka_q_t *rkq, int timeout_ms) {
3249
3381
  rd_ts_t now = rd_clock();
3250
3382
  rd_ts_t abs_timeout = rd_timeout_init0(now, timeout_ms);
3251
3383
 
3252
- rd_kafka_app_poll_start(rk, now, timeout_ms);
3384
+ rd_kafka_app_poll_start(rk, rkq, now, timeout_ms);
3253
3385
 
3254
3386
  rd_kafka_yield_thread = 0;
3255
3387
  while ((
@@ -3266,7 +3398,7 @@ rd_kafka_consume0(rd_kafka_t *rk, rd_kafka_q_t *rkq, int timeout_ms) {
3266
3398
  /* Callback called rd_kafka_yield(), we must
3267
3399
  * stop dispatching the queue and return. */
3268
3400
  rd_kafka_set_last_error(RD_KAFKA_RESP_ERR__INTR, EINTR);
3269
- rd_kafka_app_polled(rk);
3401
+ rd_kafka_app_polled(rk, rkq);
3270
3402
  return NULL;
3271
3403
  }
3272
3404
 
@@ -3278,7 +3410,7 @@ rd_kafka_consume0(rd_kafka_t *rk, rd_kafka_q_t *rkq, int timeout_ms) {
3278
3410
  /* Timeout reached with no op returned. */
3279
3411
  rd_kafka_set_last_error(RD_KAFKA_RESP_ERR__TIMED_OUT,
3280
3412
  ETIMEDOUT);
3281
- rd_kafka_app_polled(rk);
3413
+ rd_kafka_app_polled(rk, rkq);
3282
3414
  return NULL;
3283
3415
  }
3284
3416
 
@@ -3293,7 +3425,7 @@ rd_kafka_consume0(rd_kafka_t *rk, rd_kafka_q_t *rkq, int timeout_ms) {
3293
3425
 
3294
3426
  rd_kafka_set_last_error(0, 0);
3295
3427
 
3296
- rd_kafka_app_polled(rk);
3428
+ rd_kafka_app_polled(rk, rkq);
3297
3429
 
3298
3430
  return rkmessage;
3299
3431
  }
@@ -3681,6 +3813,7 @@ rd_kafka_resp_err_t rd_kafka_query_watermark_offsets(rd_kafka_t *rk,
3681
3813
  struct rd_kafka_partition_leader *leader;
3682
3814
  rd_list_t leaders;
3683
3815
  rd_kafka_resp_err_t err;
3816
+ int tmout;
3684
3817
 
3685
3818
  partitions = rd_kafka_topic_partition_list_new(1);
3686
3819
  rktpar =
@@ -3727,9 +3860,13 @@ rd_kafka_resp_err_t rd_kafka_query_watermark_offsets(rd_kafka_t *rk,
3727
3860
 
3728
3861
  /* Wait for reply (or timeout) */
3729
3862
  while (state.err == RD_KAFKA_RESP_ERR__IN_PROGRESS) {
3730
- rd_kafka_q_serve(rkq, RD_POLL_INFINITE, 0,
3731
- RD_KAFKA_Q_CB_CALLBACK, rd_kafka_poll_cb,
3732
- NULL);
3863
+ tmout = rd_timeout_remains(ts_end);
3864
+ if (rd_timeout_expired(tmout)) {
3865
+ state.err = RD_KAFKA_RESP_ERR__TIMED_OUT;
3866
+ break;
3867
+ }
3868
+ rd_kafka_q_serve(rkq, tmout, 0, RD_KAFKA_Q_CB_CALLBACK,
3869
+ rd_kafka_poll_cb, NULL);
3733
3870
  }
3734
3871
 
3735
3872
  rd_kafka_q_destroy_owner(rkq);
@@ -3799,6 +3936,7 @@ static void rd_kafka_get_offsets_for_times_resp_cb(rd_kafka_t *rk,
3799
3936
  rd_kafka_buf_t *request,
3800
3937
  void *opaque) {
3801
3938
  struct _get_offsets_for_times *state;
3939
+ int actions = 0;
3802
3940
 
3803
3941
  if (err == RD_KAFKA_RESP_ERR__DESTROY) {
3804
3942
  /* 'state' has gone out of scope when offsets_for_times()
@@ -3809,10 +3947,22 @@ static void rd_kafka_get_offsets_for_times_resp_cb(rd_kafka_t *rk,
3809
3947
  state = opaque;
3810
3948
 
3811
3949
  err = rd_kafka_handle_ListOffsets(rk, rkb, err, rkbuf, request,
3812
- state->results, NULL);
3950
+ state->results, &actions);
3813
3951
  if (err == RD_KAFKA_RESP_ERR__IN_PROGRESS)
3814
3952
  return; /* Retrying */
3815
3953
 
3954
+ if (actions & RD_KAFKA_ERR_ACTION_REFRESH) {
3955
+ rd_kafka_topic_partition_t *rktpar;
3956
+ /* Remove its cache in case the topic isn't a known topic. */
3957
+ rd_kafka_wrlock(rk);
3958
+ RD_KAFKA_TPLIST_FOREACH(rktpar, state->results) {
3959
+ if (rktpar->err)
3960
+ rd_kafka_metadata_cache_delete_by_name(
3961
+ rk, rktpar->topic);
3962
+ }
3963
+ rd_kafka_wrunlock(rk);
3964
+ }
3965
+
3816
3966
  /* Retry if no broker connection is available yet. */
3817
3967
  if (err == RD_KAFKA_RESP_ERR__TRANSPORT && rkb &&
3818
3968
  rd_kafka_brokers_wait_state_change(
@@ -3927,10 +4077,10 @@ rd_kafka_op_res_t rd_kafka_poll_cb(rd_kafka_t *rk,
3927
4077
  cb_type == RD_KAFKA_Q_CB_FORCE_RETURN)
3928
4078
  return RD_KAFKA_OP_RES_PASS; /* Dont handle here */
3929
4079
  else {
3930
- rk->rk_ts_last_poll_end = rd_clock();
3931
- struct consume_ctx ctx = {.consume_cb =
3932
- rk->rk_conf.consume_cb,
3933
- .opaque = rk->rk_conf.opaque};
4080
+ rkq->rkq_ts_last_poll_end = rd_clock();
4081
+ struct consume_ctx ctx = {.consume_cb =
4082
+ rk->rk_conf.consume_cb,
4083
+ .opaque = rk->rk_conf.opaque};
3934
4084
 
3935
4085
  return rd_kafka_consume_cb(rk, rkq, rko, cb_type, &ctx);
3936
4086
  }
@@ -4080,6 +4230,9 @@ rd_kafka_op_res_t rd_kafka_poll_cb(rd_kafka_t *rk,
4080
4230
  case RD_KAFKA_OP_TERMINATE:
4081
4231
  /* nop: just a wake-up */
4082
4232
  res = RD_KAFKA_OP_RES_YIELD;
4233
+ if (rko->rko_u.terminated.cb) {
4234
+ rko->rko_u.terminated.cb(rk, rko->rko_u.terminated.rkb);
4235
+ }
4083
4236
  rd_kafka_op_destroy(rko);
4084
4237
  break;
4085
4238
 
@@ -4157,8 +4310,9 @@ rd_kafka_op_res_t rd_kafka_poll_cb(rd_kafka_t *rk,
4157
4310
  int rd_kafka_poll(rd_kafka_t *rk, int timeout_ms) {
4158
4311
  int r;
4159
4312
 
4160
- r = rd_kafka_q_serve(rk->rk_rep, timeout_ms, 0, RD_KAFKA_Q_CB_CALLBACK,
4161
- rd_kafka_poll_cb, NULL);
4313
+ r = rd_kafka_q_serve_maybe_consume(rk->rk_rep, timeout_ms, 0,
4314
+ RD_KAFKA_Q_CB_CALLBACK,
4315
+ rd_kafka_poll_cb, NULL);
4162
4316
  return r;
4163
4317
  }
4164
4318
 
@@ -4166,8 +4320,9 @@ int rd_kafka_poll(rd_kafka_t *rk, int timeout_ms) {
4166
4320
  rd_kafka_event_t *rd_kafka_queue_poll(rd_kafka_queue_t *rkqu, int timeout_ms) {
4167
4321
  rd_kafka_op_t *rko;
4168
4322
 
4169
- rko = rd_kafka_q_pop_serve(rkqu->rkqu_q, rd_timeout_us(timeout_ms), 0,
4170
- RD_KAFKA_Q_CB_EVENT, rd_kafka_poll_cb, NULL);
4323
+ rko = rd_kafka_q_pop_serve_maybe_consume(
4324
+ rkqu->rkqu_q, rd_timeout_us(timeout_ms), 0, RD_KAFKA_Q_CB_EVENT,
4325
+ rd_kafka_poll_cb, NULL);
4171
4326
 
4172
4327
 
4173
4328
  if (!rko)
@@ -4179,8 +4334,9 @@ rd_kafka_event_t *rd_kafka_queue_poll(rd_kafka_queue_t *rkqu, int timeout_ms) {
4179
4334
  int rd_kafka_queue_poll_callback(rd_kafka_queue_t *rkqu, int timeout_ms) {
4180
4335
  int r;
4181
4336
 
4182
- r = rd_kafka_q_serve(rkqu->rkqu_q, timeout_ms, 0,
4183
- RD_KAFKA_Q_CB_CALLBACK, rd_kafka_poll_cb, NULL);
4337
+ r = rd_kafka_q_serve_maybe_consume(rkqu->rkqu_q, timeout_ms, 0,
4338
+ RD_KAFKA_Q_CB_CALLBACK,
4339
+ rd_kafka_poll_cb, NULL);
4184
4340
  return r;
4185
4341
  }
4186
4342
 
@@ -4811,8 +4967,8 @@ static void rd_kafka_DescribeGroups_resp_cb(rd_kafka_t *rk,
4811
4967
  goto err;
4812
4968
  }
4813
4969
 
4970
+ gi->broker.id = rkb->rkb_nodeid;
4814
4971
  rd_kafka_broker_lock(rkb);
4815
- gi->broker.id = rkb->rkb_nodeid;
4816
4972
  gi->broker.host = rd_strdup(rkb->rkb_origname);
4817
4973
  gi->broker.port = rkb->rkb_port;
4818
4974
  rd_kafka_broker_unlock(rkb);
@@ -5011,6 +5167,9 @@ rd_kafka_list_groups(rd_kafka_t *rk,
5011
5167
  /* Query each broker for its list of groups */
5012
5168
  rd_kafka_rdlock(rk);
5013
5169
  TAILQ_FOREACH(rkb, &rk->rk_brokers, rkb_link) {
5170
+ if (rd_kafka_broker_or_instance_terminating(rkb))
5171
+ continue;
5172
+
5014
5173
  rd_kafka_error_t *error;
5015
5174
  rd_kafka_broker_lock(rkb);
5016
5175
  if (rkb->rkb_nodeid == -1 || RD_KAFKA_BROKER_IS_LOGICAL(rkb)) {
@@ -5122,13 +5281,8 @@ const char *rd_kafka_get_debug_contexts(void) {
5122
5281
 
5123
5282
 
5124
5283
  int rd_kafka_path_is_dir(const char *path) {
5125
- #ifdef _WIN32
5126
- struct _stat st;
5127
- return (_stat(path, &st) == 0 && st.st_mode & S_IFDIR);
5128
- #else
5129
- struct stat st;
5130
- return (stat(path, &st) == 0 && S_ISDIR(st.st_mode));
5131
- #endif
5284
+ rd_bool_t is_dir;
5285
+ return rd_file_stat(path, &is_dir) && is_dir;
5132
5286
  }
5133
5287
 
5134
5288
 
@@ -5280,7 +5434,7 @@ void rd_kafka_Uuid_destroy(rd_kafka_Uuid_t *uuid) {
5280
5434
  *
5281
5435
  * @remark Must be freed after use.
5282
5436
  */
5283
- const char *rd_kafka_Uuid_str(const rd_kafka_Uuid_t *uuid) {
5437
+ char *rd_kafka_Uuid_str(const rd_kafka_Uuid_t *uuid) {
5284
5438
  int i, j;
5285
5439
  unsigned char bytes[16];
5286
5440
  char *ret = rd_calloc(37, sizeof(*ret));