@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
@@ -1,3 +1,4 @@
1
+ <a name="introduction-to-librdkafka---the-apache-kafka-cc-client-library"></a>
1
2
  # Introduction to librdkafka - the Apache Kafka C/C++ client library
2
3
 
3
4
 
@@ -9,100 +10,123 @@ librdkafka also provides a native C++ interface.
9
10
  **Table of Contents**
10
11
 
11
12
  - [Introduction to librdkafka - the Apache Kafka C/C++ client library](#introduction-to-librdkafka---the-apache-kafka-cc-client-library)
12
- - [Performance](#performance)
13
- - [High throughput](#high-throughput)
14
- - [Low latency](#low-latency)
15
- - [Latency measurement](#latency-measurement)
16
- - [Compression](#compression)
17
- - [Message reliability](#message-reliability)
18
- - [Producer message delivery success](#producer-message-delivery-success)
19
- - [Producer message delivery failure](#producer-message-delivery-failure)
20
- - [Error: Timed out in transmission queue](#error-timed-out-in-transmission-queue)
21
- - [Error: Timed out in flight to/from broker](#error-timed-out-in-flight-tofrom-broker)
22
- - [Error: Temporary broker-side error](#error-temporary-broker-side-error)
23
- - [Error: Temporary errors due to stale metadata](#error-temporary-errors-due-to-stale-metadata)
24
- - [Error: Local time out](#error-local-time-out)
25
- - [Error: Permanent errors](#error-permanent-errors)
26
- - [Producer retries](#producer-retries)
27
- - [Reordering](#reordering)
28
- - [Idempotent Producer](#idempotent-producer)
29
- - [Guarantees](#guarantees)
30
- - [Ordering and message sequence numbers](#ordering-and-message-sequence-numbers)
31
- - [Partitioner considerations](#partitioner-considerations)
32
- - [Message timeout considerations](#message-timeout-considerations)
33
- - [Leader change](#leader-change)
34
- - [Error handling](#error-handling)
35
- - [RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER](#rdkafkaresperroutofordersequencenumber)
36
- - [RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER](#rdkafkaresperrduplicatesequencenumber)
37
- - [RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID](#rdkafkaresperrunknownproducerid)
38
- - [Standard errors](#standard-errors)
39
- - [Message persistence status](#message-persistence-status)
40
- - [Transactional Producer](#transactional-producer)
41
- - [Error handling](#error-handling-1)
42
- - [Old producer fencing](#old-producer-fencing)
43
- - [Configuration considerations](#configuration-considerations)
44
- - [Exactly Once Semantics (EOS) and transactions](#exactly-once-semantics-eos-and-transactions)
45
- - [Usage](#usage)
46
- - [Documentation](#documentation)
47
- - [Initialization](#initialization)
48
- - [Configuration](#configuration)
49
- - [Example](#example)
50
- - [Termination](#termination)
51
- - [High-level KafkaConsumer](#high-level-kafkaconsumer)
52
- - [Producer](#producer)
53
- - [Admin API client](#admin-api-client)
54
- - [Speeding up termination](#speeding-up-termination)
55
- - [Threads and callbacks](#threads-and-callbacks)
56
- - [Brokers](#brokers)
57
- - [SSL](#ssl)
58
- - [OAUTHBEARER with support for OIDC](#oauthbearer-with-support-for-oidc)
59
- - [Sparse connections](#sparse-connections)
60
- - [Random broker selection](#random-broker-selection)
61
- - [Persistent broker connections](#persistent-broker-connections)
62
- - [Connection close](#connection-close)
63
- - [Fetch From Follower](#fetch-from-follower)
64
- - [Logging](#logging)
65
- - [Debug contexts](#debug-contexts)
66
- - [Feature discovery](#feature-discovery)
67
- - [Producer API](#producer-api)
68
- - [Simple Consumer API (legacy)](#simple-consumer-api-legacy)
69
- - [Offset management](#offset-management)
70
- - [Auto offset commit](#auto-offset-commit)
71
- - [At-least-once processing](#at-least-once-processing)
72
- - [Auto offset reset](#auto-offset-reset)
73
- - [Consumer groups](#consumer-groups)
74
- - [Static consumer groups](#static-consumer-groups)
75
- - [Next generation of the consumer group protocol](#next-generation-of-the-consumer-group-protocol-kip-848)
76
- - [Topics](#topics)
77
- - [Unknown or unauthorized topics](#unknown-or-unauthorized-topics)
78
- - [Topic metadata propagation for newly created topics](#topic-metadata-propagation-for-newly-created-topics)
79
- - [Topic auto creation](#topic-auto-creation)
80
- - [Metadata](#metadata)
81
- - [< 0.9.3](#-093)
82
- - [> 0.9.3](#-093)
83
- - [Query reasons](#query-reasons)
84
- - [Caching strategy](#caching-strategy)
85
- - [Fatal errors](#fatal-errors)
86
- - [Fatal producer errors](#fatal-producer-errors)
87
- - [Fatal consumer errors](#fatal-consumer-errors)
88
- - [Compatibility](#compatibility)
89
- - [Broker version compatibility](#broker-version-compatibility)
90
- - [Broker version >= 0.10.0.0 (or trunk)](#broker-version--01000-or-trunk)
91
- - [Broker versions 0.9.0.x](#broker-versions-090x)
92
- - [Broker versions 0.8.x.y](#broker-versions-08xy)
93
- - [Detailed description](#detailed-description)
94
- - [Supported KIPs](#supported-kips)
95
- - [Supported protocol versions](#supported-protocol-versions)
13
+ - [Performance](#performance)
14
+ - [High throughput](#high-throughput)
15
+ - [Low latency](#low-latency)
16
+ - [Latency measurement](#latency-measurement)
17
+ - [Compression](#compression)
18
+ - [Message reliability](#message-reliability)
19
+ - [Producer message delivery success](#producer-message-delivery-success)
20
+ - [Producer message delivery failure](#producer-message-delivery-failure)
21
+ - [Error: Timed out in transmission queue](#error-timed-out-in-transmission-queue)
22
+ - [Error: Timed out in flight to/from broker](#error-timed-out-in-flight-tofrom-broker)
23
+ - [Error: Temporary broker-side error](#error-temporary-broker-side-error)
24
+ - [Error: Temporary errors due to stale metadata](#error-temporary-errors-due-to-stale-metadata)
25
+ - [Error: Local time out](#error-local-time-out)
26
+ - [Error: Permanent errors](#error-permanent-errors)
27
+ - [Producer retries](#producer-retries)
28
+ - [Reordering](#reordering)
29
+ - [Idempotent Producer](#idempotent-producer)
30
+ - [Guarantees](#guarantees)
31
+ - [Ordering and message sequence numbers](#ordering-and-message-sequence-numbers)
32
+ - [Partitioner considerations](#partitioner-considerations)
33
+ - [Message timeout considerations](#message-timeout-considerations)
34
+ - [Leader change](#leader-change)
35
+ - [Error handling](#error-handling)
36
+ - <a href="#rd-kafka-resp-err-out-of-order-sequence-number">RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER</a>
37
+ - <a href="#rd-kafka-resp-err-duplicate-sequence-number">RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER</a>
38
+ - <a href="#rd-kafka-resp-err-unknown-producer-id">RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID</a>
39
+ - [Standard errors](#standard-errors)
40
+ - [Message persistence status](#message-persistence-status)
41
+ - [Transactional Producer](#transactional-producer)
42
+ - [Error handling](#error-handling-1)
43
+ - [Old producer fencing](#old-producer-fencing)
44
+ - [Configuration considerations](#configuration-considerations)
45
+ - [Exactly Once Semantics (EOS) and transactions](#exactly-once-semantics-eos-and-transactions)
46
+ - [Usage](#usage)
47
+ - [Documentation](#documentation)
48
+ - [Initialization](#initialization)
49
+ - [Configuration](#configuration)
50
+ - [Example](#example)
51
+ - [Termination](#termination)
52
+ - [High-level KafkaConsumer](#high-level-kafkaconsumer)
53
+ - [Producer](#producer)
54
+ - [Admin API client](#admin-api-client)
55
+ - [Speeding up termination](#speeding-up-termination)
56
+ - [Threads and callbacks](#threads-and-callbacks)
57
+ - [Brokers](#brokers)
58
+ - [SSL](#ssl)
59
+ - [OAUTHBEARER with support for OIDC](#oauthbearer-with-support-for-oidc)
60
+ - [JWT bearer grant type (KIP-1139)](#jwt-bearer-grant-type-kip-1139)
61
+ - [Metadata based authentication](#metadata-based-authentication)
62
+ - [Azure IMDS](#azure-imds)
63
+ - [Sparse connections](#sparse-connections)
64
+ - [Random broker selection](#random-broker-selection)
65
+ - [Persistent broker connections](#persistent-broker-connections)
66
+ - [Connection close](#connection-close)
67
+ - [Fetch From Follower](#fetch-from-follower)
68
+ - [Logging](#logging)
69
+ - [Debug contexts](#debug-contexts)
70
+ - [Feature discovery](#feature-discovery)
71
+ - [Producer API](#producer-api)
72
+ - [Simple Consumer API (legacy)](#simple-consumer-api-legacy)
73
+ - [Offset management](#offset-management)
74
+ - [Auto offset commit](#auto-offset-commit)
75
+ - [At-least-once processing](#at-least-once-processing)
76
+ - [Auto offset reset](#auto-offset-reset)
77
+ - [Consumer groups](#consumer-groups)
78
+ - [Static consumer groups](#static-consumer-groups)
79
+ - [Next Generation Consumer Group Protocol (KIP-848)](#next-generation-consumer-group-protocol-kip-848)
80
+ - [Overview](#overview)
81
+ - [Available Features](#available-features)
82
+ - [Contract Changes](#contract-changes)
83
+ - [Client Configuration changes](#client-configuration-changes)
84
+ - [Rebalance Callback Changes](#rebalance-callback-changes)
85
+ - [Static Group Membership](#static-group-membership)
86
+ - [Session Timeout \& Fetching](#session-timeout--fetching)
87
+ - [Closing / Auto-Commit](#closing--auto-commit)
88
+ - [Error Handling Changes](#error-handling-changes)
89
+ - [Summary of Key Differences (Classic vs Next-Gen)](#summary-of-key-differences-classic-vs-next-gen)
90
+ - [Minimal Example Config](#minimal-example-config)
91
+ - [Classic Protocol](#classic-protocol)
92
+ - [Next-Gen Protocol / KIP-848](#next-gen-protocol--kip-848)
93
+ - [Rebalance Callback Migration](#rebalance-callback-migration)
94
+ - [Range Assignor (Classic)](#range-assignor-classic)
95
+ - [Incremental Assignor (Including Range in Consumer / KIP-848, Any Protocol)](#incremental-assignor-including-range-in-consumer--kip-848-any-protocol)
96
+ - [Upgrade and Downgrade](#upgrade-and-downgrade)
97
+ - [Migration Checklist (Next-Gen Protocol / KIP-848)](#migration-checklist-next-gen-protocol--kip-848)
98
+ - [Note on Batch consume APIs](#note-on-batch-consume-apis)
99
+ - [Topics](#topics)
100
+ - [Unknown or unauthorized topics](#unknown-or-unauthorized-topics)
101
+ - [Topic metadata propagation for newly created topics](#topic-metadata-propagation-for-newly-created-topics)
102
+ - [Topic auto creation](#topic-auto-creation)
103
+ - [Metadata](#metadata)
104
+ - [\< 0.9.3](#lt093)
105
+ - [\> 0.9.3](#gt093-1)
106
+ - [Query reasons](#query-reasons)
107
+ - [Caching strategy](#caching-strategy)
108
+ - [Fatal errors](#fatal-errors)
109
+ - [Fatal producer errors](#fatal-producer-errors)
110
+ - [Fatal consumer errors](#fatal-consumer-errors)
111
+ - [Compatibility](#compatibility)
112
+ - [Broker version compatibility](#broker-version-compatibility)
113
+ - [Broker version \>= 0.10.0.0 (or trunk)](#broker-version--01000-or-trunk)
114
+ - [Broker versions 0.9.0.x](#broker-versions-090x)
115
+ - [Broker versions 0.8.x.y](#broker-versions-08xy)
116
+ - [Detailed description](#detailed-description)
117
+ - [Supported KIPs](#supported-kips)
118
+ - [Supported protocol versions](#supported-protocol-versions)
96
119
  - [Recommendations for language binding developers](#recommendations-for-language-binding-developers)
97
- - [Expose the configuration interface pass-thru](#expose-the-configuration-interface-pass-thru)
98
- - [Error constants](#error-constants)
99
- - [Reporting client software name and version to broker](#reporting-client-software-name-and-version-to-broker)
100
- - [Documentation reuse](#documentation-reuse)
101
- - [Community support](#community-support)
120
+ - [Expose the configuration interface pass-thru](#expose-the-configuration-interface-pass-thru)
121
+ - [Error constants](#error-constants)
122
+ - [Reporting client software name and version to broker](#reporting-client-software-name-and-version-to-broker)
123
+ - [Documentation reuse](#documentation-reuse)
124
+ - [Community support](#community-support)
102
125
 
103
126
  <!-- markdown-toc end -->
104
127
 
105
128
 
129
+ <a name="performance"></a>
106
130
  ## Performance
107
131
 
108
132
  librdkafka is a multi-threaded library designed for use on modern hardware and
@@ -128,6 +152,7 @@ per-message load on the broker. A good general purpose setting is 5ms.
128
152
  For applications seeking maximum throughput, the recommended value is >= 50ms.
129
153
 
130
154
 
155
+ <a name="high-throughput"></a>
131
156
  ### High throughput
132
157
 
133
158
  The key to high throughput is message batching - waiting for a certain amount
@@ -176,6 +201,7 @@ These setting are set globally (`rd_kafka_conf_t`) but applies on a
176
201
  per topic+partition basis.
177
202
 
178
203
 
204
+ <a name="low-latency"></a>
179
205
  ### Low latency
180
206
 
181
207
  When low latency messaging is required the `linger.ms` should be
@@ -188,6 +214,7 @@ increasing network, memory and CPU usage for producers, brokers and consumers.
188
214
  See [How to decrease message latency](https://github.com/confluentinc/librdkafka/wiki/How-to-decrease-message-latency) for more info.
189
215
 
190
216
 
217
+ <a name="latency-measurement"></a>
191
218
  #### Latency measurement
192
219
 
193
220
  End-to-end latency is preferably measured by synchronizing clocks on producers
@@ -202,42 +229,42 @@ To break down the end-to-end latencies and find where latencies are adding up
202
229
  there are a number of metrics available through librdkafka statistics
203
230
  on the producer:
204
231
 
205
- * `brokers[].int_latency` is the time, per message, between produce()
206
- and the message being written to a MessageSet and ProduceRequest.
207
- High `int_latency` indicates CPU core contention: check CPU load and,
208
- involuntary context switches (`/proc/<..>/status`).
209
- Consider using a machine/instance with more CPU cores.
210
- This metric is only relevant on the producer.
211
-
212
- * `brokers[].outbuf_latency` is the time, per protocol request
213
- (such as ProduceRequest), between the request being enqueued (which happens
214
- right after int_latency) and the time the request is written to the
215
- TCP socket connected to the broker.
216
- High `outbuf_latency` indicates CPU core contention or network congestion:
217
- check CPU load and socket SendQ (`netstat -anp | grep :9092`).
218
-
219
- * `brokers[].rtt` is the time, per protocol request, between the request being
220
- written to the TCP socket and the time the response is received from
221
- the broker.
222
- High `rtt` indicates broker load or network congestion:
223
- check broker metrics, local socket SendQ, network performance, etc.
224
-
225
- * `brokers[].throttle` is the time, per throttled protocol request, the
226
- broker throttled/delayed handling of a request due to usage quotas.
227
- The throttle time will also be reflected in `rtt`.
228
-
229
- * `topics[].batchsize` is the size of individual Producer MessageSet batches.
230
- See below.
231
-
232
- * `topics[].batchcnt` is the number of messages in individual Producer
233
- MessageSet batches. Due to Kafka protocol overhead a batch with few messages
234
- will have a higher relative processing and size overhead than a batch
235
- with many messages.
236
- Use the `linger.ms` client configuration property to set the maximum
237
- amount of time allowed for accumulating a single batch, the larger the
238
- value the larger the batches will grow, thus increasing efficiency.
239
- When producing messages at a high rate it is recommended to increase
240
- linger.ms, which will improve throughput and in some cases also latency.
232
+ * `brokers[].int_latency` is the time, per message, between produce()
233
+ and the message being written to a MessageSet and ProduceRequest.
234
+ High `int_latency` indicates CPU core contention: check CPU load and,
235
+ involuntary context switches (`/proc/<..>/status`).
236
+ Consider using a machine/instance with more CPU cores.
237
+ This metric is only relevant on the producer.
238
+
239
+ * `brokers[].outbuf_latency` is the time, per protocol request
240
+ (such as ProduceRequest), between the request being enqueued (which happens
241
+ right after int_latency) and the time the request is written to the
242
+ TCP socket connected to the broker.
243
+ High `outbuf_latency` indicates CPU core contention or network congestion:
244
+ check CPU load and socket SendQ (`netstat -anp | grep :9092`).
245
+
246
+ * `brokers[].rtt` is the time, per protocol request, between the request being
247
+ written to the TCP socket and the time the response is received from
248
+ the broker.
249
+ High `rtt` indicates broker load or network congestion:
250
+ check broker metrics, local socket SendQ, network performance, etc.
251
+
252
+ * `brokers[].throttle` is the time, per throttled protocol request, the
253
+ broker throttled/delayed handling of a request due to usage quotas.
254
+ The throttle time will also be reflected in `rtt`.
255
+
256
+ * `topics[].batchsize` is the size of individual Producer MessageSet batches.
257
+ See below.
258
+
259
+ * `topics[].batchcnt` is the number of messages in individual Producer
260
+ MessageSet batches. Due to Kafka protocol overhead a batch with few messages
261
+ will have a higher relative processing and size overhead than a batch
262
+ with many messages.
263
+ Use the `linger.ms` client configuration property to set the maximum
264
+ amount of time allowed for accumulating a single batch, the larger the
265
+ value the larger the batches will grow, thus increasing efficiency.
266
+ When producing messages at a high rate it is recommended to increase
267
+ linger.ms, which will improve throughput and in some cases also latency.
241
268
 
242
269
 
243
270
  See [STATISTICS.md](STATISTICS.md) for the full definition of metrics.
@@ -245,6 +272,7 @@ A JSON schema for the statistics is available in
245
272
  [statistics-schema.json](src/statistics-schema.json).
246
273
 
247
274
 
275
+ <a name="compression"></a>
248
276
  ### Compression
249
277
 
250
278
  Producer message compression is enabled through the `compression.codec`
@@ -258,6 +286,7 @@ The local batch queue size is controlled through the `batch.num.messages`,
258
286
 
259
287
 
260
288
 
289
+ <a name="message-reliability"></a>
261
290
  ## Message reliability
262
291
 
263
292
  Message reliability is an important factor of librdkafka - an application
@@ -270,10 +299,10 @@ for message commit acknowledgements from brokers (any value but 0, see
270
299
  for specifics) then librdkafka will hold on to the message until
271
300
  all expected acks have been received, gracefully handling the following events:
272
301
 
273
- * Broker connection failure
274
- * Topic leader change
275
- * Produce errors signaled by the broker
276
- * Network problems
302
+ * Broker connection failure
303
+ * Topic leader change
304
+ * Produce errors signaled by the broker
305
+ * Network problems
277
306
 
278
307
  We recommend `request.required.acks` to be set to `all` to make sure
279
308
  produced messages are acknowledged by all in-sync replica brokers.
@@ -287,15 +316,16 @@ The delivery report callback is used by librdkafka to signal the status of
287
316
  a message back to the application, it will be called once for each message
288
317
  to report the status of message delivery:
289
318
 
290
- * If `error_code` is non-zero the message delivery failed and the error_code
291
- indicates the nature of the failure (`rd_kafka_resp_err_t` enum).
292
- * If `error_code` is zero the message has been successfully delivered.
319
+ * If `error_code` is non-zero the message delivery failed and the error_code
320
+ indicates the nature of the failure (`rd_kafka_resp_err_t` enum).
321
+ * If `error_code` is zero the message has been successfully delivered.
293
322
 
294
323
  See Producer API chapter for more details on delivery report callback usage.
295
324
 
296
325
  The delivery report callback is optional but highly recommended.
297
326
 
298
327
 
328
+ <a name="producer-message-delivery-success"></a>
299
329
  ### Producer message delivery success
300
330
 
301
331
  When a ProduceRequest is successfully handled by the broker and a
@@ -305,6 +335,7 @@ queue (if a delivery report callback has been set) and will be passed to
305
335
  the application on the next invocation rd_kafka_poll().
306
336
 
307
337
 
338
+ <a name="producer-message-delivery-failure"></a>
308
339
  ### Producer message delivery failure
309
340
 
310
341
  The following sub-chapters explains how different produce errors
@@ -324,6 +355,7 @@ using the `retries`, `retry.backoff.ms` and `retry.backoff.max.ms`
324
355
  configuration properties.
325
356
 
326
357
 
358
+ <a name="error-timed-out-in-transmission-queue"></a>
327
359
  #### Error: Timed out in transmission queue
328
360
 
329
361
  Internal error ERR__TIMED_OUT_QUEUE.
@@ -339,6 +371,7 @@ since the message was never actually transmitted.
339
371
  A retry by librdkafka at this point will not cause duplicate messages.
340
372
 
341
373
 
374
+ <a name="error-timed-out-in-flight-tofrom-broker"></a>
342
375
  #### Error: Timed out in flight to/from broker
343
376
 
344
377
  Internal error ERR__TIMED_OUT, ERR__TRANSPORT.
@@ -355,6 +388,7 @@ This is a retryable error.
355
388
  A retry by librdkafka at this point may cause duplicate messages.
356
389
 
357
390
 
391
+ <a name="error-temporary-broker-side-error"></a>
358
392
  #### Error: Temporary broker-side error
359
393
 
360
394
  Broker errors ERR_REQUEST_TIMED_OUT, ERR_NOT_ENOUGH_REPLICAS,
@@ -364,6 +398,7 @@ These errors are considered temporary and librdkafka is will retry them
364
398
  if permitted by configuration.
365
399
 
366
400
 
401
+ <a name="error-temporary-errors-due-to-stale-metadata"></a>
367
402
  #### Error: Temporary errors due to stale metadata
368
403
 
369
404
  Broker errors ERR_LEADER_NOT_AVAILABLE, ERR_NOT_LEADER_FOR_PARTITION.
@@ -374,6 +409,7 @@ request is automatically sent to find a new leader for the partition.
374
409
  A retry by librdkafka at this point will not cause duplicate messages.
375
410
 
376
411
 
412
+ <a name="error-local-time-out"></a>
377
413
  #### Error: Local time out
378
414
 
379
415
  Internal error ERR__MSG_TIMED_OUT.
@@ -387,6 +423,7 @@ Since the `message.timeout.ms` has passed there will be no more retries
387
423
  by librdkafka.
388
424
 
389
425
 
426
+ <a name="error-permanent-errors"></a>
390
427
  #### Error: Permanent errors
391
428
 
392
429
  Any other error is considered a permanent error and the message
@@ -397,19 +434,20 @@ The full list of permanent errors depend on the broker version and
397
434
  will likely grow in the future.
398
435
 
399
436
  Typical permanent broker errors are:
400
- * ERR_CORRUPT_MESSAGE
401
- * ERR_MSG_SIZE_TOO_LARGE - adjust client's or broker's `message.max.bytes`.
402
- * ERR_UNKNOWN_TOPIC_OR_PART - topic or partition does not exist,
403
- automatic topic creation is disabled on the
404
- broker or the application is specifying a
405
- partition that does not exist.
406
- * ERR_RECORD_LIST_TOO_LARGE
407
- * ERR_INVALID_REQUIRED_ACKS
408
- * ERR_TOPIC_AUTHORIZATION_FAILED
409
- * ERR_UNSUPPORTED_FOR_MESSAGE_FORMAT
410
- * ERR_CLUSTER_AUTHORIZATION_FAILED
411
-
412
-
437
+ * ERR_CORRUPT_MESSAGE
438
+ * ERR_MSG_SIZE_TOO_LARGE - adjust client's or broker's `message.max.bytes`.
439
+ * ERR_UNKNOWN_TOPIC_OR_PART - topic or partition does not exist,
440
+ automatic topic creation is disabled on the
441
+ broker or the application is specifying a
442
+ partition that does not exist.
443
+ * ERR_RECORD_LIST_TOO_LARGE
444
+ * ERR_INVALID_REQUIRED_ACKS
445
+ * ERR_TOPIC_AUTHORIZATION_FAILED
446
+ * ERR_UNSUPPORTED_FOR_MESSAGE_FORMAT
447
+ * ERR_CLUSTER_AUTHORIZATION_FAILED
448
+
449
+
450
+ <a name="producer-retries"></a>
413
451
  ### Producer retries
414
452
 
415
453
  The ProduceRequest itself is not retried, instead the messages
@@ -421,6 +459,7 @@ A backoff time (`retry.backoff.ms`) is set on the retried messages which
421
459
  effectively blocks retry attempts until the backoff time has expired.
422
460
 
423
461
 
462
+ <a name="reordering"></a>
424
463
  ### Reordering
425
464
 
426
465
  As for all retries, if `max.in.flight` > 1 and `retries` > 0, retried messages
@@ -432,6 +471,7 @@ Using the Idempotent Producer prevents reordering even with `max.in.flight` > 1,
432
471
  see [Idempotent Producer](#idempotent-producer) below for more information.
433
472
 
434
473
 
474
+ <a name="idempotent-producer"></a>
435
475
  ### Idempotent Producer
436
476
 
437
477
  librdkafka supports the idempotent producer which provides strict ordering and
@@ -446,33 +486,35 @@ for any of the automatically adjusted properties, e.g., it is an error to
446
486
  explicitly set `acks=1` when `enable.idempotence=true` is set.
447
487
 
448
488
 
489
+ <a name="guarantees"></a>
449
490
  #### Guarantees
450
491
 
451
492
  There are three types of guarantees that the idempotent producer can satisfy:
452
493
 
453
- * Exactly-once - a message is only written to the log once.
454
- Does NOT cover the exactly-once consumer case.
455
- * Ordering - a series of messages are written to the log in the
456
- order they were produced.
457
- * Gap-less - **EXPERIMENTAL** a series of messages are written once and
458
- in order without risk of skipping messages. The sequence
459
- of messages may be cut short and fail before all
460
- messages are written, but may not fail individual
461
- messages in the series.
462
- This guarantee is disabled by default, but may be enabled
463
- by setting `enable.gapless.guarantee` if individual message
464
- failure is a concern.
465
- Messages that fail due to exceeded timeout (`message.timeout.ms`),
466
- are permitted by the gap-less guarantee and may cause
467
- gaps in the message series without raising a fatal error.
468
- See **Message timeout considerations** below for more info.
469
- **WARNING**: This is an experimental property subject to
470
- change or removal.
494
+ * Exactly-once - a message is only written to the log once.
495
+ Does NOT cover the exactly-once consumer case.
496
+ * Ordering - a series of messages are written to the log in the
497
+ order they were produced.
498
+ * Gap-less - **EXPERIMENTAL** a series of messages are written once and
499
+ in order without risk of skipping messages. The sequence
500
+ of messages may be cut short and fail before all
501
+ messages are written, but may not fail individual
502
+ messages in the series.
503
+ This guarantee is disabled by default, but may be enabled
504
+ by setting `enable.gapless.guarantee` if individual message
505
+ failure is a concern.
506
+ Messages that fail due to exceeded timeout (`message.timeout.ms`),
507
+ are permitted by the gap-less guarantee and may cause
508
+ gaps in the message series without raising a fatal error.
509
+ See **Message timeout considerations** below for more info.
510
+ **WARNING**: This is an experimental property subject to
511
+ change or removal.
471
512
 
472
513
  All three guarantees are in effect when idempotence is enabled, only
473
514
  gap-less may be disabled individually.
474
515
 
475
516
 
517
+ <a name="ordering-and-message-sequence-numbers"></a>
476
518
  #### Ordering and message sequence numbers
477
519
 
478
520
  librdkafka maintains the original produce() ordering per-partition for all
@@ -493,28 +535,29 @@ With Idempotent Producer enabled there is no risk of reordering despite
493
535
  `max.in.flight` > 1 (capped at 5).
494
536
 
495
537
  **Note**: "MsgId" in log messages refer to the librdkafka msgid, while "seq"
496
- refers to the protocol message sequence, "baseseq" is the seq of
497
- the first message in a batch.
498
- MsgId starts at 1, while message seqs start at 0.
538
+ refers to the protocol message sequence, "baseseq" is the seq of
539
+ the first message in a batch.
540
+ MsgId starts at 1, while message seqs start at 0.
499
541
 
500
542
 
501
543
  The producer statistics also maintain two metrics for tracking the next
502
544
  expected response sequence:
503
545
 
504
- * `next_ack_seq` - the next sequence to expect an acknowledgement for, which
505
- is the last successfully produced MessageSet's last
506
- sequence + 1.
507
- * `next_err_seq` - the next sequence to expect an error for, which is typically
508
- the same as `next_ack_seq` until an error occurs, in which
509
- case the `next_ack_seq` can't be incremented (since no
510
- messages were acked on error). `next_err_seq` is used to
511
- properly handle sub-sequent errors due to a failing
512
- first request.
546
+ * `next_ack_seq` - the next sequence to expect an acknowledgement for, which
547
+ is the last successfully produced MessageSet's last
548
+ sequence + 1.
549
+ * `next_err_seq` - the next sequence to expect an error for, which is typically
550
+ the same as `next_ack_seq` until an error occurs, in which
551
+ case the `next_ack_seq` can't be incremented (since no
552
+ messages were acked on error). `next_err_seq` is used to
553
+ properly handle sub-sequent errors due to a failing
554
+ first request.
513
555
 
514
556
  **Note**: Both are exposed in partition statistics.
515
557
 
516
558
 
517
559
 
560
+ <a name="partitioner-considerations"></a>
518
561
  #### Partitioner considerations
519
562
 
520
563
  Strict ordering is guaranteed on a **per partition** basis.
@@ -526,17 +569,18 @@ a topic's partition count is known, which would insert these messages
526
569
  after the partition-explicit messages regardless of produce order.
527
570
 
528
571
 
572
+ <a name="message-timeout-considerations"></a>
529
573
  #### Message timeout considerations
530
574
 
531
575
  If messages time out (due to `message.timeout.ms`) while in the producer queue
532
576
  there will be gaps in the series of produced messages.
533
577
 
534
578
  E.g., Messages 1,2,3,4,5 are produced by the application.
535
- While messages 2,3,4 are transmitted to the broker the connection to
536
- the broker goes down.
537
- While the broker is down the message timeout expires for message 2 and 3.
538
- As the connection comes back up messages 4, 5 are transmitted to the
539
- broker, resulting in a final written message sequence of 1, 4, 5.
579
+ While messages 2,3,4 are transmitted to the broker the connection to
580
+ the broker goes down.
581
+ While the broker is down the message timeout expires for message 2 and 3.
582
+ As the connection comes back up messages 4, 5 are transmitted to the
583
+ broker, resulting in a final written message sequence of 1, 4, 5.
540
584
 
541
585
  The producer gracefully handles this case by draining the in-flight requests
542
586
  for a given partition when one or more of its queued (not transmitted)
@@ -573,6 +617,7 @@ large `message.timeout.ms` to minimize the risk of timeouts.
573
617
  **Note**: `delivery.timeout.ms` is an alias for `message.timeout.ms`.
574
618
 
575
619
 
620
+ <a name="leader-change"></a>
576
621
  #### Leader change
577
622
 
578
623
  There are corner cases where an Idempotent Producer has outstanding
@@ -590,6 +635,7 @@ If the connection to the previous broker goes down the outstanding requests
590
635
  are failed immediately.
591
636
 
592
637
 
638
+ <a name="error-handling"></a>
593
639
  #### Error handling
594
640
 
595
641
  Background:
@@ -605,7 +651,7 @@ provide stricter and less complex error handling.
605
651
  The follow sections describe librdkafka's handling of the
606
652
  Idempotent Producer specific errors that may be returned by the broker.
607
653
 
608
-
654
+ <a name="rd-kafka-resp-err-out-of-order-sequence-number"></a>
609
655
  ##### RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER
610
656
 
611
657
  This error is returned by the broker when the sequence number in the
@@ -633,7 +679,7 @@ Fail the batch, reset the pid, and then continue producing
633
679
  in the message series.
634
680
 
635
681
 
636
-
682
+ <a name="rd-kafka-resp-err-duplicate-sequence-number"></a>
637
683
  ##### RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER
638
684
 
639
685
  Returned by broker when the request's base sequence number is
@@ -651,7 +697,7 @@ timestamp or offset set.
651
697
  **Java Producer behaviour:**
652
698
  Treats the message as successfully delivered.
653
699
 
654
-
700
+ <a name="rd-kafka-resp-err-unknown-producer-id"></a>
655
701
  ##### RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID
656
702
 
657
703
  Returned by broker when the PID+Epoch is unknown, which may occur when
@@ -685,6 +731,7 @@ Retries the send in some cases (but KIP-360 will change this).
685
731
  Not a fatal error in any case.
686
732
 
687
733
 
734
+ <a name="standard-errors"></a>
688
735
  ##### Standard errors
689
736
 
690
737
  All the standard Produce errors are handled in the usual way,
@@ -702,56 +749,60 @@ the gap-less guarantee (if `enable.gapless.guarantee` is set) by failing all
702
749
  queued messages.
703
750
 
704
751
 
752
+ <a name="message-persistence-status"></a>
705
753
  ##### Message persistence status
706
754
 
707
755
  To help the application decide what to do in these error cases, a new
708
756
  per-message API is introduced, `rd_kafka_message_status()`,
709
757
  which returns one of the following values:
710
758
 
711
- * `RD_KAFKA_MSG_STATUS_NOT_PERSISTED` - the message has never
712
- been transmitted to the broker, or failed with an error indicating
713
- it was not written to the log.
714
- Application retry will risk ordering, but not duplication.
715
- * `RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED` - the message was transmitted
716
- to the broker, but no acknowledgement was received.
717
- Application retry will risk ordering and duplication.
718
- * `RD_KAFKA_MSG_STATUS_PERSISTED` - the message was written to the log by
719
- the broker and fully acknowledged.
720
- No reason for application to retry.
759
+ * `RD_KAFKA_MSG_STATUS_NOT_PERSISTED` - the message has never
760
+ been transmitted to the broker, or failed with an error indicating
761
+ it was not written to the log.
762
+ Application retry will risk ordering, but not duplication.
763
+ * `RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED` - the message was transmitted
764
+ to the broker, but no acknowledgement was received.
765
+ Application retry will risk ordering and duplication.
766
+ * `RD_KAFKA_MSG_STATUS_PERSISTED` - the message was written to the log by
767
+ the broker and fully acknowledged.
768
+ No reason for application to retry.
721
769
 
722
770
  This method should be called by the application on delivery report error.
723
771
 
724
772
 
773
+ <a name="transactional-producer"></a>
725
774
  ### Transactional Producer
726
775
 
727
776
 
777
+ <a name="error-handling-1"></a>
728
778
  #### Error handling
729
779
 
730
780
  Using the transactional producer simplifies error handling compared to the
731
781
  standard or idempotent producer, a transactional application will only need
732
782
  to care about these different types of errors:
733
783
 
734
- * Retriable errors - the operation failed due to temporary problems,
735
- such as network timeouts, the operation may be safely retried.
736
- Use `rd_kafka_error_is_retriable()` to distinguish this case.
737
- * Abortable errors - if any of the transactional APIs return a non-fatal
738
- error code the current transaction has failed and the application
739
- must call `rd_kafka_abort_transaction()`, rewind its input to the
740
- point before the current transaction started, and attempt a new transaction
741
- by calling `rd_kafka_begin_transaction()`, etc.
742
- Use `rd_kafka_error_txn_requires_abort()` to distinguish this case.
743
- * Fatal errors - the application must cease operations and destroy the
744
- producer instance.
745
- Use `rd_kafka_error_is_fatal()` to distinguish this case.
746
- * For all other errors returned from the transactional API: the current
747
- recommendation is to treat any error that has neither retriable, abortable,
748
- or fatal set, as a fatal error.
784
+ * Retriable errors - the operation failed due to temporary problems,
785
+ such as network timeouts, the operation may be safely retried.
786
+ Use `rd_kafka_error_is_retriable()` to distinguish this case.
787
+ * Abortable errors - if any of the transactional APIs return a non-fatal
788
+ error code the current transaction has failed and the application
789
+ must call `rd_kafka_abort_transaction()`, rewind its input to the
790
+ point before the current transaction started, and attempt a new transaction
791
+ by calling `rd_kafka_begin_transaction()`, etc.
792
+ Use `rd_kafka_error_txn_requires_abort()` to distinguish this case.
793
+ * Fatal errors - the application must cease operations and destroy the
794
+ producer instance.
795
+ Use `rd_kafka_error_is_fatal()` to distinguish this case.
796
+ * For all other errors returned from the transactional API: the current
797
+ recommendation is to treat any error that has neither retriable, abortable,
798
+ or fatal set, as a fatal error.
749
799
 
750
800
  While the application should log the actual fatal or abortable errors, there
751
801
  is no need for the application to handle the underlying errors specifically.
752
802
 
753
803
 
754
804
 
805
+ <a name="old-producer-fencing"></a>
755
806
  #### Old producer fencing
756
807
 
757
808
  If a new transactional producer instance is started with the same
@@ -761,6 +812,7 @@ raising a fatal error with the error code set to
761
812
  `RD_KAFKA_RESP_ERR__FENCED`.
762
813
 
763
814
 
815
+ <a name="configuration-considerations"></a>
764
816
  #### Configuration considerations
765
817
 
766
818
  To make sure messages time out (in case of connectivity problems, etc) within
@@ -773,6 +825,7 @@ automatically.
773
825
 
774
826
 
775
827
 
828
+ <a name="exactly-once-semantics-eos-and-transactions"></a>
776
829
  ### Exactly Once Semantics (EOS) and transactions
777
830
 
778
831
  librdkafka supports Exactly One Semantics (EOS) as defined in [KIP-98](https://cwiki.apache.org/confluence/display/KAFKA/KIP-98+-+Exactly+Once+Delivery+and+Transactional+Messaging).
@@ -789,14 +842,17 @@ the number of input partitions.
789
842
  See KIP-447 for more information.
790
843
 
791
844
 
845
+ <a name="usage"></a>
792
846
  ## Usage
793
847
 
848
+ <a name="documentation"></a>
794
849
  ### Documentation
795
850
 
796
851
  The librdkafka API is documented in the [`rdkafka.h`](src/rdkafka.h)
797
852
  header file, the configuration properties are documented in
798
853
  [`CONFIGURATION.md`](CONFIGURATION.md)
799
854
 
855
+ <a name="initialization"></a>
800
856
  ### Initialization
801
857
 
802
858
  The application needs to instantiate a top-level object `rd_kafka_t` which is
@@ -815,13 +871,14 @@ Not using the API will cause librdkafka to use its default values which are
815
871
  documented in [`CONFIGURATION.md`](CONFIGURATION.md).
816
872
 
817
873
  **Note**: An application may create multiple `rd_kafka_t` objects and
818
- they share no state.
874
+ they share no state.
819
875
 
820
876
  **Note**: An `rd_kafka_topic_t` object may only be used with the `rd_kafka_t`
821
- object it was created from.
877
+ object it was created from.
822
878
 
823
879
 
824
880
 
881
+ <a name="configuration"></a>
825
882
  ### Configuration
826
883
 
827
884
  To ease integration with the official Apache Kafka software and lower
@@ -832,10 +889,11 @@ Configuration is applied prior to object creation using the
832
889
  `rd_kafka_conf_set()` and `rd_kafka_topic_conf_set()` APIs.
833
890
 
834
891
  **Note**: The `rd_kafka.._conf_t` objects are not reusable after they have been
835
- passed to `rd_kafka.._new()`.
836
- The application does not need to free any config resources after a
837
- `rd_kafka.._new()` call.
892
+ passed to `rd_kafka.._new()`.
893
+ The application does not need to free any config resources after a
894
+ `rd_kafka.._new()` call.
838
895
 
896
+ <a name="example"></a>
839
897
  #### Example
840
898
 
841
899
  ```c
@@ -873,6 +931,7 @@ are detected. It will also emit log warnings for deprecated and problematic
873
931
  configuration properties.
874
932
 
875
933
 
934
+ <a name="termination"></a>
876
935
  ### Termination
877
936
 
878
937
  librdkafka is asynchronous in its nature and performs most operation in its
@@ -894,23 +953,24 @@ destroyed/deleted prior to destroying or closing the handle.
894
953
 
895
954
  For C, make sure the following objects are destroyed prior to calling
896
955
  `rd_kafka_consumer_close()` and `rd_kafka_destroy()`:
897
- * `rd_kafka_message_t`
898
- * `rd_kafka_topic_t`
899
- * `rd_kafka_topic_partition_t`
900
- * `rd_kafka_topic_partition_list_t`
901
- * `rd_kafka_event_t`
902
- * `rd_kafka_queue_t`
956
+ * `rd_kafka_message_t`
957
+ * `rd_kafka_topic_t`
958
+ * `rd_kafka_topic_partition_t`
959
+ * `rd_kafka_topic_partition_list_t`
960
+ * `rd_kafka_event_t`
961
+ * `rd_kafka_queue_t`
903
962
 
904
963
  For C++ make sure the following objects are deleted prior to
905
964
  calling `KafkaConsumer::close()` and delete on the Consumer, KafkaConsumer or
906
965
  Producer handle:
907
- * `Message`
908
- * `Topic`
909
- * `TopicPartition`
910
- * `Event`
911
- * `Queue`
966
+ * `Message`
967
+ * `Topic`
968
+ * `TopicPartition`
969
+ * `Event`
970
+ * `Queue`
912
971
 
913
972
 
973
+ <a name="high-level-kafkaconsumer"></a>
914
974
  #### High-level KafkaConsumer
915
975
 
916
976
  Proper termination sequence for the high-level KafkaConsumer is:
@@ -927,13 +987,14 @@ Proper termination sequence for the high-level KafkaConsumer is:
927
987
  **NOTE**: Any topic objects created must be destroyed prior to rd_kafka_destroy()
928
988
 
929
989
  Effects of not doing the above, for:
930
- 1. Final offsets are not committed and the consumer will not actively leave
931
- the group, it will be kicked out of the group after the `session.timeout.ms`
932
- expires. It is okay to omit the `rd_kafka_consumer_close()` call in case
933
- the application does not want to wait for the blocking close call.
934
- 2. librdkafka will continue to operate on the handle. Actual memory leaks.
990
+ 1. Final offsets are not committed and the consumer will not actively leave
991
+ the group, it will be kicked out of the group after the `session.timeout.ms`
992
+ expires. It is okay to omit the `rd_kafka_consumer_close()` call in case
993
+ the application does not want to wait for the blocking close call.
994
+ 2. librdkafka will continue to operate on the handle. Actual memory leaks.
935
995
 
936
996
 
997
+ <a name="producer"></a>
937
998
  #### Producer
938
999
 
939
1000
  The proper termination sequence for Producers is:
@@ -948,10 +1009,11 @@ The proper termination sequence for Producers is:
948
1009
  ```
949
1010
 
950
1011
  Effects of not doing the above, for:
951
- 1. Messages in-queue or in-flight will be dropped.
952
- 2. librdkafka will continue to operate on the handle. Actual memory leaks.
1012
+ 1. Messages in-queue or in-flight will be dropped.
1013
+ 2. librdkafka will continue to operate on the handle. Actual memory leaks.
953
1014
 
954
1015
 
1016
+ <a name="admin-api-client"></a>
955
1017
  #### Admin API client
956
1018
 
957
1019
  Unlike the Java Admin client, the Admin APIs in librdkafka are available
@@ -969,6 +1031,7 @@ topic metadata lookups to unexpectedly have the broker create topics.
969
1031
 
970
1032
 
971
1033
 
1034
+ <a name="speeding-up-termination"></a>
972
1035
  #### Speeding up termination
973
1036
  To speed up the termination of librdkafka an application can set a
974
1037
  termination signal that will be used internally by librdkafka to quickly
@@ -982,6 +1045,7 @@ Make sure you block this signal in your application.
982
1045
  ```
983
1046
 
984
1047
 
1048
+ <a name="threads-and-callbacks"></a>
985
1049
  ### Threads and callbacks
986
1050
 
987
1051
  librdkafka uses multiple threads internally to fully utilize modern hardware.
@@ -992,32 +1056,32 @@ A poll-based API is used to provide signaling back to the application,
992
1056
  the application should call rd_kafka_poll() at regular intervals.
993
1057
  The poll API will call the following configured callbacks (optional):
994
1058
 
995
- * `dr_msg_cb` - Message delivery report callback - signals that a message has
996
- been delivered or failed delivery, allowing the application to take action
997
- and to release any application resources used in the message.
998
- * `error_cb` - Error callback - signals an error. These errors are usually of
999
- an informational nature, i.e., failure to connect to a broker, and the
1000
- application usually does not need to take any action.
1001
- The type of error is passed as a rd_kafka_resp_err_t enum value,
1002
- including both remote broker errors as well as local failures.
1003
- An application typically does not have to perform any action when
1004
- an error is raised through the error callback, the client will
1005
- automatically try to recover from all errors, given that the
1006
- client and cluster is correctly configured.
1007
- In some specific cases a fatal error may occur which will render
1008
- the client more or less inoperable for further use:
1009
- if the error code in the error callback is set to
1010
- `RD_KAFKA_RESP_ERR__FATAL` the application should retrieve the
1011
- underlying fatal error and reason using the `rd_kafka_fatal_error()` call,
1012
- and then begin terminating the instance.
1013
- The Event API's EVENT_ERROR has a `rd_kafka_event_error_is_fatal()`
1014
- function, and the C++ EventCb has a `fatal()` method, to help the
1015
- application determine if an error is fatal or not.
1016
- * `stats_cb` - Statistics callback - triggered if `statistics.interval.ms`
1017
- is configured to a non-zero value, emitting metrics and internal state
1018
- in JSON format, see [STATISTICS.md].
1019
- * `throttle_cb` - Throttle callback - triggered whenever a broker has
1020
- throttled (delayed) a request.
1059
+ * `dr_msg_cb` - Message delivery report callback - signals that a message has
1060
+ been delivered or failed delivery, allowing the application to take action
1061
+ and to release any application resources used in the message.
1062
+ * `error_cb` - Error callback - signals an error. These errors are usually of
1063
+ an informational nature, i.e., failure to connect to a broker, and the
1064
+ application usually does not need to take any action.
1065
+ The type of error is passed as a rd_kafka_resp_err_t enum value,
1066
+ including both remote broker errors as well as local failures.
1067
+ An application typically does not have to perform any action when
1068
+ an error is raised through the error callback, the client will
1069
+ automatically try to recover from all errors, given that the
1070
+ client and cluster is correctly configured.
1071
+ In some specific cases a fatal error may occur which will render
1072
+ the client more or less inoperable for further use:
1073
+ if the error code in the error callback is set to
1074
+ `RD_KAFKA_RESP_ERR__FATAL` the application should retrieve the
1075
+ underlying fatal error and reason using the `rd_kafka_fatal_error()` call,
1076
+ and then begin terminating the instance.
1077
+ The Event API's EVENT_ERROR has a `rd_kafka_event_error_is_fatal()`
1078
+ function, and the C++ EventCb has a `fatal()` method, to help the
1079
+ application determine if an error is fatal or not.
1080
+ * `stats_cb` - Statistics callback - triggered if `statistics.interval.ms`
1081
+ is configured to a non-zero value, emitting metrics and internal state
1082
+ in JSON format, see [STATISTICS.md].
1083
+ * `throttle_cb` - Throttle callback - triggered whenever a broker has
1084
+ throttled (delayed) a request.
1021
1085
 
1022
1086
  These callbacks will also be triggered by `rd_kafka_flush()`,
1023
1087
  `rd_kafka_consumer_poll()`, and any other functions that serve queues.
@@ -1026,20 +1090,21 @@ These callbacks will also be triggered by `rd_kafka_flush()`,
1026
1090
  Optional callbacks not triggered by poll, these may be called spontaneously
1027
1091
  from any thread at any time:
1028
1092
 
1029
- * `log_cb` - Logging callback - allows the application to output log messages
1030
- generated by librdkafka.
1031
- * `partitioner_cb` - Partitioner callback - application provided message partitioner.
1032
- The partitioner may be called in any thread at any time, it may be
1033
- called multiple times for the same key.
1034
- Partitioner function contraints:
1035
- - MUST NOT call any rd_kafka_*() functions
1036
- - MUST NOT block or execute for prolonged periods of time.
1037
- - MUST return a value between 0 and partition_cnt-1, or the
1038
- special RD_KAFKA_PARTITION_UA value if partitioning
1039
- could not be performed.
1093
+ * `log_cb` - Logging callback - allows the application to output log messages
1094
+ generated by librdkafka.
1095
+ * `partitioner_cb` - Partitioner callback - application provided message partitioner.
1096
+ The partitioner may be called in any thread at any time, it may be
1097
+ called multiple times for the same key.
1098
+ Partitioner function contraints:
1099
+ - MUST NOT call any rd_kafka_*() functions
1100
+ - MUST NOT block or execute for prolonged periods of time.
1101
+ - MUST return a value between 0 and partition_cnt-1, or the
1102
+ special RD_KAFKA_PARTITION_UA value if partitioning
1103
+ could not be performed.
1040
1104
 
1041
1105
 
1042
1106
 
1107
+ <a name="brokers"></a>
1043
1108
  ### Brokers
1044
1109
 
1045
1110
  On initialization, librdkafka only needs a partial list of
@@ -1058,6 +1123,7 @@ A DNS record containing all broker address can thus be used to provide a
1058
1123
  reliable bootstrap broker.
1059
1124
 
1060
1125
 
1126
+ <a name="ssl"></a>
1061
1127
  #### SSL
1062
1128
 
1063
1129
  If the client is to connect to a broker's SSL endpoints/listeners the client
@@ -1069,15 +1135,15 @@ the connection is closed (and retried). This is to protect the client
1069
1135
  from connecting to rogue brokers.
1070
1136
 
1071
1137
  The CA root certificate defaults are system specific:
1072
- * On Linux, Mac OSX, and other Unix-like system the OpenSSL default
1073
- CA path will be used, also called the OPENSSLDIR, which is typically
1074
- `/etc/ssl/certs` (on Linux, typcially in the `ca-certificates` package) and
1075
- `/usr/local/etc/openssl` on Mac OSX (Homebrew).
1076
- * On Windows the Root certificate store is used, unless
1077
- `ssl.ca.certificate.stores` is configured in which case certificates are
1078
- read from the specified stores.
1079
- * If OpenSSL is linked statically, librdkafka will set the default CA
1080
- location to the first of a series of probed paths (see below).
1138
+ * On Linux, Mac OSX, and other Unix-like system the OpenSSL default
1139
+ CA path will be used, also called the OPENSSLDIR, which is typically
1140
+ `/etc/ssl/certs` (on Linux, typcially in the `ca-certificates` package) and
1141
+ `/usr/local/etc/openssl` on Mac OSX (Homebrew).
1142
+ * On Windows the Root certificate store is used, unless
1143
+ `ssl.ca.certificate.stores` is configured in which case certificates are
1144
+ read from the specified stores.
1145
+ * If OpenSSL is linked statically, librdkafka will set the default CA
1146
+ location to the first of a series of probed paths (see below).
1081
1147
 
1082
1148
  If the system-provided default CA root certificates are not sufficient to
1083
1149
  verify the broker's certificate, such as when a self-signed certificate
@@ -1118,15 +1184,16 @@ of certificate stores can be read by setting the `ssl.ca.certificate.stores`
1118
1184
  configuration property to a comma-separated list of certificate store names.
1119
1185
  The predefined system store names are:
1120
1186
 
1121
- * `MY` - User certificates
1122
- * `Root` - System CA certificates (default)
1123
- * `CA` - Intermediate CA certificates
1124
- * `Trust` - Trusted publishers
1187
+ * `MY` - User certificates
1188
+ * `Root` - System CA certificates (default)
1189
+ * `CA` - Intermediate CA certificates
1190
+ * `Trust` - Trusted publishers
1125
1191
 
1126
1192
  For example, to read both intermediate and root CAs, set
1127
1193
  `ssl.ca.certificate.stores=CA,Root`.
1128
1194
 
1129
1195
 
1196
+ <a name="oauthbearer-with-support-for-oidc"></a>
1130
1197
  #### OAUTHBEARER with support for OIDC
1131
1198
 
1132
1199
  OAUTHBEARER with OIDC provides a method for the client to authenticate to the
@@ -1135,24 +1202,98 @@ and passing the retrieved token to brokers during connection setup.
1135
1202
 
1136
1203
  To use this authentication method the client needs to be configured as follows:
1137
1204
 
1138
- * `security.protocol` - set to `SASL_SSL` or `SASL_PLAINTEXT`.
1139
- * `sasl.mechanism` - set to `OAUTHBEARER`.
1140
- * `sasl.oauthbearer.method` - set to `OIDC`.
1141
- * `sasl.oauthbearer.token.endpoint.url` - OAUTH issuer token
1142
- endpoint HTTP(S) URI used to retrieve the token.
1143
- * `sasl.oauthbearer.client.id` - public identifier for the application.
1144
- It must be unique across all clients that the authorization server handles.
1145
- * `sasl.oauthbearer.client.secret` - secret known only to the
1146
- application and the authorization server.
1147
- This should be a sufficiently random string that is not guessable.
1148
- * `sasl.oauthbearer.scope` - clients use this to specify the scope of the
1149
- access request to the broker.
1150
- * `sasl.oauthbearer.extensions` - (optional) additional information to be
1151
- provided to the broker. A comma-separated list of key=value pairs.
1152
- For example:
1153
- `supportFeatureX=true,organizationId=sales-emea`
1154
-
1155
-
1205
+ * `security.protocol` - set to `SASL_SSL` or `SASL_PLAINTEXT`.
1206
+ * `sasl.mechanism` - set to `OAUTHBEARER`.
1207
+ * `sasl.oauthbearer.method` - set to `OIDC`.
1208
+ * `sasl.oauthbearer.token.endpoint.url` - OAUTH issuer token
1209
+ endpoint HTTP(S) URI used to retrieve the token.
1210
+ * `sasl.oauthbearer.client.id` - public identifier for the application.
1211
+ It must be unique across all clients that the authorization server handles.
1212
+ * `sasl.oauthbearer.client.secret` - secret known only to the
1213
+ application and the authorization server.
1214
+ This should be a sufficiently random string that is not guessable.
1215
+ * `sasl.oauthbearer.scope` - clients use this to specify the scope of the
1216
+ access request to the broker.
1217
+ * `sasl.oauthbearer.extensions` - (optional) additional information to be
1218
+ provided to the broker. A comma-separated list of key=value pairs.
1219
+ For example:
1220
+ `supportFeatureX=true,organizationId=sales-emea`
1221
+ * `https.ca.location` - (optional) to customize the CA certificates
1222
+ location.
1223
+
1224
+ * `https.ca.pem` - (optional) to provide the CA certificates as a PEM string.
1225
+
1226
+ <a name="jwt-bearer-grant-type-kip-1139">
1227
+ ##### JWT bearer grant type (KIP-1139)
1228
+
1229
+ This KIP adds support for the `client_credentials, urn:ietf:params:oauth:grant-type:jwt-bearer`
1230
+ grant type, with a series of properties to be used for creating a JWT assertion
1231
+ sent to the token endpoint. The authenticated principal corresponds to the
1232
+ `sub` claim returned by token endpoint, `sasl.oauthbearer.client.id` and
1233
+ `sasl.oauthbearer.client.secret` aren't used. Required JWT claims must be set
1234
+ either through the template or with the `claim` properties.
1235
+
1236
+ * `sasl.oauthbearer.grant.type` - changes the default grant type, set it to
1237
+ `urn:ietf:params:oauth:grant-type:jwt-bearer`.
1238
+ * `sasl.oauthbearer.assertion.algorithm` - JWT algorithm defaults to `RS256`.
1239
+ * `sasl.oauthbearer.assertion.private.key.file` - a private key file for signing
1240
+ the token.
1241
+ * `sasl.oauthbearer.assertion.private.key.passphrase` - (optional) passphrase for the key if encrypted.
1242
+ * `sasl.oauthbearer.assertion.private.key.pem` - alternatively to the key file
1243
+ it's possible to pass the private key as a string.
1244
+ * `sasl.oauthbearer.assertion.file` - (optional) assertion file: with this property all other
1245
+ assertion related fields are ignored and the assertion is read from this file
1246
+ that should be periodically updated.
1247
+ * `sasl.oauthbearer.assertion.jwt.template.file` - (optional) template file: a template containing
1248
+ a default `header` and `payload` that can be overwritten by the `claim` properties.
1249
+ * `sasl.oauthbearer.assertion.claim.aud`,
1250
+ `sasl.oauthbearer.assertion.claim.exp.seconds`,
1251
+ `sasl.oauthbearer.assertion.claim.iss`,
1252
+ `sasl.oauthbearer.assertion.claim.jti.include`,
1253
+ `sasl.oauthbearer.assertion.claim.sub` - (optional) the `claim` properties:
1254
+ it's possible to dynamically customize the JWT claims with these or to
1255
+ skip the template file and use only these properties.
1256
+
1257
+ <a name="metadata-based-authentication"></a>
1258
+ ##### Metadata based authentication
1259
+
1260
+ Some cloud providers added the ability to authenticate clients based on
1261
+ OAUTHBEARER/OIDC tokens returned from endpoints that can only be called from
1262
+ a given instance. Such endpoints are served on a specific IP address (169.254.169.254)
1263
+ that is a link-local metadata endpoint.
1264
+
1265
+
1266
+ While there is no standard for that still, librdkafka has support for
1267
+ some metadata based OAUTHBEARER authentication types.
1268
+
1269
+
1270
+ Currently these authentication types are supported:
1271
+
1272
+ <a name="azure-imds">
1273
+ ###### Azure IMDS
1274
+
1275
+ To use this method you set:
1276
+
1277
+ * `sasl.oauthbearer.metadata.authentication.type=azure_imds` this makes it so
1278
+ that ` sasl.oauthbearer.client.id` and `sasl.oauthbearer.client.secret`
1279
+ aren't required.
1280
+ * `sasl.oauthbearer.config` is a general purpose configuration property
1281
+ In this case it accepts comma-separated `key=value` pairs.
1282
+ The `query` key is required in case `sasl.oauthbearer.token.endpoint.url` isn't
1283
+ specified and its value is the GET query string to append
1284
+ to the token endpoint URL. Such query string contains params required by
1285
+ Azure IMDS such as `client_id` (the UAMI), `resource` for determining the
1286
+ target audience and `api-version` for the API version to be used by the endpoint
1287
+ * `sasl.oauthbearer.token.endpoint.url` (optional) is set automatically.
1288
+ when choosing `sasl.oauthbearer.metadata.authentication.type=azure_imds` but can
1289
+ be customized.
1290
+
1291
+
1292
+ _Example:_ `sasl.oauthbearer.metadata.authentication.type=azure_imds` and
1293
+ `sasl.oauthbearer.config=params=api-version=2025-04-07&resource=api://<App registration client id>&client_id=<UAMI client id>`
1294
+
1295
+
1296
+ <a name="sparse-connections"></a>
1156
1297
  #### Sparse connections
1157
1298
 
1158
1299
  The client will only connect to brokers it needs to communicate with, and
@@ -1160,12 +1301,13 @@ only when necessary.
1160
1301
 
1161
1302
  Examples of needed broker connections are:
1162
1303
 
1163
- * leaders for partitions being consumed from
1164
- * leaders for partitions being produced to
1165
- * consumer group coordinator broker
1166
- * cluster controller for Admin API operations
1304
+ * leaders for partitions being consumed from
1305
+ * leaders for partitions being produced to
1306
+ * consumer group coordinator broker
1307
+ * cluster controller for Admin API operations
1167
1308
 
1168
1309
 
1310
+ <a name="random-broker-selection"></a>
1169
1311
  ##### Random broker selection
1170
1312
 
1171
1313
  When there is no broker connection and a connection to any broker
@@ -1179,11 +1321,11 @@ If there is already an available broker connection to any broker it is used,
1179
1321
  rather than connecting to a new one.
1180
1322
 
1181
1323
  The random broker selection and connection scheduling is triggered when:
1182
- * bootstrap servers are configured (`rd_kafka_new()`)
1183
- * brokers are manually added (`rd_kafka_brokers_add()`).
1184
- * a consumer group coordinator needs to be found.
1185
- * acquiring a ProducerID for the Idempotent Producer.
1186
- * cluster or topic metadata is being refreshed.
1324
+ * bootstrap servers are configured (`rd_kafka_new()`)
1325
+ * brokers are manually added (`rd_kafka_brokers_add()`).
1326
+ * a consumer group coordinator needs to be found.
1327
+ * acquiring a ProducerID for the Idempotent Producer.
1328
+ * cluster or topic metadata is being refreshed.
1187
1329
 
1188
1330
  A single connection attempt will be performed, and the broker will
1189
1331
  return to an idle INIT state on failure to connect.
@@ -1192,21 +1334,23 @@ The random broker selection is rate-limited to:
1192
1334
  10 < `reconnect.backoff.ms`/2 < 1000 milliseconds.
1193
1335
 
1194
1336
  **Note**: The broker connection will be maintained until it is closed
1195
- by the broker (idle connection reaper).
1337
+ by the broker (idle connection reaper).
1196
1338
 
1339
+ <a name="persistent-broker-connections"></a>
1197
1340
  ##### Persistent broker connections
1198
1341
 
1199
1342
  While the random broker selection is useful for one-off queries, there
1200
1343
  is need for the client to maintain persistent connections to certain brokers:
1201
- * Consumer: the group coordinator.
1202
- * Consumer: partition leader for topics being fetched from.
1203
- * Producer: partition leader for topics being produced to.
1344
+ * Consumer: the group coordinator.
1345
+ * Consumer: partition leader for topics being fetched from.
1346
+ * Producer: partition leader for topics being produced to.
1204
1347
 
1205
1348
  These dependencies are discovered and maintained automatically, marking
1206
1349
  matching brokers as persistent, which will make the client maintain connections
1207
1350
  to these brokers at all times, reconnecting as necessary.
1208
1351
 
1209
1352
 
1353
+ <a name="connection-close"></a>
1210
1354
  #### Connection close
1211
1355
 
1212
1356
  A broker connection may be closed by the broker, intermediary network gear,
@@ -1234,6 +1378,7 @@ the logging level will be LOG_WARNING (4), else LOG_INFO (6).
1234
1378
  but it is recommended to instead rely on the above heuristics.
1235
1379
 
1236
1380
 
1381
+ <a name="fetch-from-follower"></a>
1237
1382
  #### Fetch From Follower
1238
1383
 
1239
1384
  librdkafka supports consuming messages from follower replicas
@@ -1244,51 +1389,54 @@ consumers to replicas is determined by the configured `replica.selector.class`
1244
1389
  on the broker.
1245
1390
 
1246
1391
 
1392
+ <a name="logging"></a>
1247
1393
  ### Logging
1248
1394
 
1395
+ <a name="debug-contexts"></a>
1249
1396
  #### Debug contexts
1250
1397
 
1251
1398
  Extensive debugging of librdkafka can be enabled by setting the
1252
1399
  `debug` configuration property to a CSV string of debug contexts:
1253
1400
 
1254
- Debug context | Type | Description
1255
- --------------|----------|----------------------
1256
- generic | * | General client instance level debugging. Includes initialization and termination debugging.
1257
- broker | * | Broker and connection state debugging.
1258
- topic | * | Topic and partition state debugging. Includes leader changes.
1259
- metadata | * | Cluster and topic metadata retrieval debugging.
1260
- feature | * | Kafka protocol feature support as negotiated with the broker.
1261
- queue | producer | Message queue debugging.
1262
- msg | * | Message debugging. Includes information about batching, compression, sizes, etc.
1263
- protocol | * | Kafka protocol request/response debugging. Includes latency (rtt) printouts.
1264
- cgrp | consumer | Low-level consumer group state debugging.
1265
- security | * | Security and authentication debugging.
1266
- fetch | consumer | Consumer message fetch debugging. Includes decision when and why messages are fetched.
1267
- interceptor | * | Interceptor interface debugging.
1268
- plugin | * | Plugin loading debugging.
1269
- consumer | consumer | High-level consumer debugging.
1270
- admin | admin | Admin API debugging.
1271
- eos | producer | Idempotent Producer debugging.
1272
- mock | * | Mock cluster functionality debugging.
1273
- assignor | consumer | Detailed consumer group partition assignor debugging.
1274
- conf | * | Display set configuration properties on startup.
1275
- all | * | All of the above.
1401
+ | Debug context | Type | Description |
1402
+ | ------------- | -------- | ------------------------------------------------------------------------------------------- |
1403
+ | generic | * | General client instance level debugging. Includes initialization and termination debugging. |
1404
+ | broker | * | Broker and connection state debugging. |
1405
+ | topic | * | Topic and partition state debugging. Includes leader changes. |
1406
+ | metadata | * | Cluster and topic metadata retrieval debugging. |
1407
+ | feature | * | Kafka protocol feature support as negotiated with the broker. |
1408
+ | queue | producer | Message queue debugging. |
1409
+ | msg | * | Message debugging. Includes information about batching, compression, sizes, etc. |
1410
+ | protocol | * | Kafka protocol request/response debugging. Includes latency (rtt) printouts. |
1411
+ | cgrp | consumer | Low-level consumer group state debugging. |
1412
+ | security | * | Security and authentication debugging. |
1413
+ | fetch | consumer | Consumer message fetch debugging. Includes decision when and why messages are fetched. |
1414
+ | interceptor | * | Interceptor interface debugging. |
1415
+ | plugin | * | Plugin loading debugging. |
1416
+ | consumer | consumer | High-level consumer debugging. |
1417
+ | admin | admin | Admin API debugging. |
1418
+ | eos | producer | Idempotent Producer debugging. |
1419
+ | mock | * | Mock cluster functionality debugging. |
1420
+ | assignor | consumer | Detailed consumer group partition assignor debugging. |
1421
+ | conf | * | Display set configuration properties on startup. |
1422
+ | all | * | All of the above. |
1276
1423
 
1277
1424
 
1278
1425
  Suggested debugging settings for troubleshooting:
1279
1426
 
1280
- Problem space | Type | Debug setting
1281
- -----------------------|----------|-------------------
1282
- Producer not delivering messages to broker | producer | `broker,topic,msg`
1283
- Consumer not fetching messages | consumer | Start with `consumer`, or use `cgrp,fetch` for detailed information.
1284
- Consumer starts reading at unexpected offset | consumer | `consumer` or `cgrp,fetch`
1285
- Authentication or connectivity issues | * | `broker,auth`
1286
- Protocol handling or latency | * | `broker,protocol`
1287
- Topic leader and state | * | `topic,metadata`
1427
+ | Problem space | Type | Debug setting |
1428
+ | -------------------------------------------- | -------- | -------------------------------------------------------------------- |
1429
+ | Producer not delivering messages to broker | producer | `broker,topic,msg` |
1430
+ | Consumer not fetching messages | consumer | Start with `consumer`, or use `cgrp,fetch` for detailed information. |
1431
+ | Consumer starts reading at unexpected offset | consumer | `consumer` or `cgrp,fetch` |
1432
+ | Authentication or connectivity issues | * | `broker,auth` |
1433
+ | Protocol handling or latency | * | `broker,protocol` |
1434
+ | Topic leader and state | * | `topic,metadata` |
1288
1435
 
1289
1436
 
1290
1437
 
1291
1438
 
1439
+ <a name="feature-discovery"></a>
1292
1440
  ### Feature discovery
1293
1441
 
1294
1442
  Apache Kafka broker version 0.10.0 added support for the ApiVersionRequest API
@@ -1305,6 +1453,7 @@ and is controlled by the `broker.version.fallback` configuration property.
1305
1453
 
1306
1454
 
1307
1455
 
1456
+ <a name="producer-api"></a>
1308
1457
  ### Producer API
1309
1458
 
1310
1459
  After setting up the `rd_kafka_t` object with type `RD_KAFKA_PRODUCER` and one
@@ -1313,36 +1462,36 @@ to be produced and sent to brokers.
1313
1462
 
1314
1463
  The `rd_kafka_produce()` function takes the following arguments:
1315
1464
 
1316
- * `rkt` - the topic to produce to, previously created with
1317
- `rd_kafka_topic_new()`
1318
- * `partition` - partition to produce to. If this is set to
1319
- `RD_KAFKA_PARTITION_UA` (UnAssigned) then the configured partitioner
1320
- function will be used to select a target partition.
1321
- * `msgflags` - 0, or one of:
1322
- * `RD_KAFKA_MSG_F_COPY` - librdkafka will immediately make a copy of
1323
- the payload. Use this when the payload is in non-persistent
1324
- memory, such as the stack.
1325
- * `RD_KAFKA_MSG_F_FREE` - let librdkafka free the payload using
1326
- `free(3)` when it is done with it.
1327
-
1328
- These two flags are mutually exclusive and neither need to be set in
1329
- which case the payload is neither copied nor freed by librdkafka.
1330
-
1331
- If `RD_KAFKA_MSG_F_COPY` flag is not set no data copying will be
1332
- performed and librdkafka will hold on the payload pointer until
1333
- the message has been delivered or fails.
1334
- The delivery report callback will be called when librdkafka is done
1335
- with the message to let the application regain ownership of the
1336
- payload memory.
1337
- The application must not free the payload in the delivery report
1338
- callback if `RD_KAFKA_MSG_F_FREE is set`.
1339
- * `payload`,`len` - the message payload
1340
- * `key`,`keylen` - an optional message key which can be used for partitioning.
1341
- It will be passed to the topic partitioner callback, if any, and
1342
- will be attached to the message when sending to the broker.
1343
- * `msg_opaque` - an optional application-provided per-message opaque pointer
1344
- that will be provided in the message delivery callback to let
1345
- the application reference a specific message.
1465
+ * `rkt` - the topic to produce to, previously created with
1466
+ `rd_kafka_topic_new()`
1467
+ * `partition` - partition to produce to. If this is set to
1468
+ `RD_KAFKA_PARTITION_UA` (UnAssigned) then the configured partitioner
1469
+ function will be used to select a target partition.
1470
+ * `msgflags` - 0, or one of:
1471
+ * `RD_KAFKA_MSG_F_COPY` - librdkafka will immediately make a copy of
1472
+ the payload. Use this when the payload is in non-persistent
1473
+ memory, such as the stack.
1474
+ * `RD_KAFKA_MSG_F_FREE` - let librdkafka free the payload using
1475
+ `free(3)` when it is done with it.
1476
+
1477
+ These two flags are mutually exclusive and neither need to be set in
1478
+ which case the payload is neither copied nor freed by librdkafka.
1479
+
1480
+ If `RD_KAFKA_MSG_F_COPY` flag is not set no data copying will be
1481
+ performed and librdkafka will hold on the payload pointer until
1482
+ the message has been delivered or fails.
1483
+ The delivery report callback will be called when librdkafka is done
1484
+ with the message to let the application regain ownership of the
1485
+ payload memory.
1486
+ The application must not free the payload in the delivery report
1487
+ callback if `RD_KAFKA_MSG_F_FREE is set`.
1488
+ * `payload`,`len` - the message payload
1489
+ * `key`,`keylen` - an optional message key which can be used for partitioning.
1490
+ It will be passed to the topic partitioner callback, if any, and
1491
+ will be attached to the message when sending to the broker.
1492
+ * `msg_opaque` - an optional application-provided per-message opaque pointer
1493
+ that will be provided in the message delivery callback to let
1494
+ the application reference a specific message.
1346
1495
 
1347
1496
 
1348
1497
  `rd_kafka_produce()` is a non-blocking API, it will enqueue the message
@@ -1362,6 +1511,7 @@ message fields, such as timestamp and headers.
1362
1511
  **Note**: See `examples/rdkafka_performance.c` for a producer implementation.
1363
1512
 
1364
1513
 
1514
+ <a name="simple-consumer-api-legacy"></a>
1365
1515
  ### Simple Consumer API (legacy)
1366
1516
 
1367
1517
  NOTE: For the high-level KafkaConsumer interface see rd_kafka_subscribe (rdkafka.h) or KafkaConsumer (rdkafkacpp.h)
@@ -1373,16 +1523,16 @@ for a given partition by calling `rd_kafka_consume_start()`.
1373
1523
 
1374
1524
  `rd_kafka_consume_start()` arguments:
1375
1525
 
1376
- * `rkt` - the topic to start consuming from, previously created with
1377
- `rd_kafka_topic_new()`.
1378
- * `partition` - partition to consume from.
1379
- * `offset` - message offset to start consuming from. This may either be an
1380
- absolute message offset or one of the three special offsets:
1381
- `RD_KAFKA_OFFSET_BEGINNING` to start consuming from the beginning
1382
- of the partition's queue (oldest message), or
1383
- `RD_KAFKA_OFFSET_END` to start consuming at the next message to be
1384
- produced to the partition, or
1385
- `RD_KAFKA_OFFSET_STORED` to use the offset store.
1526
+ * `rkt` - the topic to start consuming from, previously created with
1527
+ `rd_kafka_topic_new()`.
1528
+ * `partition` - partition to consume from.
1529
+ * `offset` - message offset to start consuming from. This may either be an
1530
+ absolute message offset or one of the three special offsets:
1531
+ `RD_KAFKA_OFFSET_BEGINNING` to start consuming from the beginning
1532
+ of the partition's queue (oldest message), or
1533
+ `RD_KAFKA_OFFSET_END` to start consuming at the next message to be
1534
+ produced to the partition, or
1535
+ `RD_KAFKA_OFFSET_STORED` to use the offset store.
1386
1536
 
1387
1537
  After a topic+partition consumer has been started librdkafka will attempt
1388
1538
  to keep `queued.min.messages` messages in the local queue by repeatedly
@@ -1393,10 +1543,10 @@ request.
1393
1543
  This local message queue is then served to the application through three
1394
1544
  different consume APIs:
1395
1545
 
1396
- * `rd_kafka_consume()` - consumes a single message
1397
- * `rd_kafka_consume_batch()` - consumes one or more messages
1398
- * `rd_kafka_consume_callback()` - consumes all messages in the local
1399
- queue and calls a callback function for each one.
1546
+ * `rd_kafka_consume()` - consumes a single message
1547
+ * `rd_kafka_consume_batch()` - consumes one or more messages
1548
+ * `rd_kafka_consume_callback()` - consumes all messages in the local
1549
+ queue and calls a callback function for each one.
1400
1550
 
1401
1551
  These three APIs are listed above the ascending order of performance,
1402
1552
  `rd_kafka_consume()` being the slowest and `rd_kafka_consume_callback()` being
@@ -1408,15 +1558,15 @@ is represented by the `rd_kafka_message_t` type.
1408
1558
 
1409
1559
  `rd_kafka_message_t` members:
1410
1560
 
1411
- * `err` - Error signaling back to the application. If this field is non-zero
1412
- the `payload` field should be considered an error message and
1413
- `err` is an error code (`rd_kafka_resp_err_t`).
1414
- If `err` is zero then the message is a proper fetched message
1415
- and `payload` et.al contains message payload data.
1416
- * `rkt`,`partition` - Topic and partition for this message or error.
1417
- * `payload`,`len` - Message payload data or error message (err!=0).
1418
- * `key`,`key_len` - Optional message key as specified by the producer
1419
- * `offset` - Message offset
1561
+ * `err` - Error signaling back to the application. If this field is non-zero
1562
+ the `payload` field should be considered an error message and
1563
+ `err` is an error code (`rd_kafka_resp_err_t`).
1564
+ If `err` is zero then the message is a proper fetched message
1565
+ and `payload` et.al contains message payload data.
1566
+ * `rkt`,`partition` - Topic and partition for this message or error.
1567
+ * `payload`,`len` - Message payload data or error message (err!=0).
1568
+ * `key`,`key_len` - Optional message key as specified by the producer
1569
+ * `offset` - Message offset
1420
1570
 
1421
1571
  Both the `payload` and `key` memory, as well as the message as a whole, is
1422
1572
  owned by librdkafka and must not be used after an `rd_kafka_message_destroy()`
@@ -1434,6 +1584,7 @@ purge any messages currently in the local queue.
1434
1584
  **Note**: See `examples/rdkafka_performance.c` for a consumer implementation.
1435
1585
 
1436
1586
 
1587
+ <a name="offset-management"></a>
1437
1588
  #### Offset management
1438
1589
 
1439
1590
  Broker based offset management is available for broker version >= 0.9.0
@@ -1444,16 +1595,17 @@ Offset management is also available through a deprecated local offset file,
1444
1595
  where the offset is periodically written to a local file for each
1445
1596
  topic+partition according to the following topic configuration properties:
1446
1597
 
1447
- * `enable.auto.commit`
1448
- * `auto.commit.interval.ms`
1449
- * `offset.store.path`
1450
- * `offset.store.sync.interval.ms`
1598
+ * `enable.auto.commit`
1599
+ * `auto.commit.interval.ms`
1600
+ * `offset.store.path`
1601
+ * `offset.store.sync.interval.ms`
1451
1602
 
1452
1603
  The legacy `auto.commit.enable` topic configuration property is only to be used
1453
1604
  with the legacy low-level consumer.
1454
1605
  Use `enable.auto.commit` with the modern KafkaConsumer.
1455
1606
 
1456
1607
 
1608
+ <a name="auto-offset-commit"></a>
1457
1609
  ##### Auto offset commit
1458
1610
 
1459
1611
  The consumer will automatically commit offsets every `auto.commit.interval.ms`
@@ -1464,6 +1616,7 @@ this offset store is updated by `consumer_poll()` (et.al) to
1464
1616
  store the offset of the last message passed to the application
1465
1617
  (per topic+partition).
1466
1618
 
1619
+ <a name="at-least-once-processing"></a>
1467
1620
  ##### At-least-once processing
1468
1621
  Since auto commits are performed in a background thread this may result in
1469
1622
  the offset for the latest message being committed before the application has
@@ -1483,10 +1636,11 @@ The latest stored offset will be automatically committed every
1483
1636
  `auto.commit.interval.ms`.
1484
1637
 
1485
1638
  **Note**: Only greater offsets are committed, e.g., if the latest committed
1486
- offset was 10 and the application performs an offsets_store()
1487
- with offset 9, that offset will not be committed.
1639
+ offset was 10 and the application performs an offsets_store()
1640
+ with offset 9, that offset will not be committed.
1488
1641
 
1489
1642
 
1643
+ <a name="auto-offset-reset"></a>
1490
1644
  ##### Auto offset reset
1491
1645
 
1492
1646
  The consumer will by default try to acquire the last committed offsets for
@@ -1495,14 +1649,15 @@ If there is no committed offset available, or the consumer is unable to
1495
1649
  fetch the committed offsets, the policy of `auto.offset.reset` will kick in.
1496
1650
  This configuration property may be set to one the following values:
1497
1651
 
1498
- * `earliest` - start consuming the earliest message of the partition.
1499
- * `latest` - start consuming the next message to be produced to the partition.
1500
- * `error` - don't start consuming but isntead raise a consumer error
1501
- with error-code `RD_KAFKA_RESP_ERR__AUTO_OFFSET_RESET` for
1502
- the topic+partition. This allows the application to decide what
1503
- to do in case there is no committed start offset.
1652
+ * `earliest` - start consuming the earliest message of the partition.
1653
+ * `latest` - start consuming the next message to be produced to the partition.
1654
+ * `error` - don't start consuming but isntead raise a consumer error
1655
+ with error-code `RD_KAFKA_RESP_ERR__AUTO_OFFSET_RESET` for
1656
+ the topic+partition. This allows the application to decide what
1657
+ to do in case there is no committed start offset.
1504
1658
 
1505
1659
 
1660
+ <a name="consumer-groups"></a>
1506
1661
  ### Consumer groups
1507
1662
 
1508
1663
  Broker based consumer groups (requires Apache Kafka broker >=0.9) are supported,
@@ -1515,6 +1670,7 @@ group coordinator, and partition leader(s).
1515
1670
  ![Consumer group state diagram](src/librdkafka_cgrp_synch.png)
1516
1671
 
1517
1672
 
1673
+ <a name="static-consumer-groups"></a>
1518
1674
  #### Static consumer groups
1519
1675
 
1520
1676
  By default Kafka consumers are rebalanced each time a new consumer joins
@@ -1540,99 +1696,218 @@ the original fatal error code and reason.
1540
1696
 
1541
1697
  To read more about static group membership, see [KIP-345](https://cwiki.apache.org/confluence/display/KAFKA/KIP-345%3A+Introduce+static+membership+protocol+to+reduce+consumer+rebalances).
1542
1698
 
1699
+ <a name="next-generation-consumer-group-protocol-kip-848"></a>
1700
+ ### Next Generation Consumer Group Protocol ([KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol))
1543
1701
 
1544
- ### Next generation of the consumer group protocol: [KIP 848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol)
1702
+ Starting with **librdkafka v2.12.0** (GA release), the next generation consumer group rebalance protocol defined in **[KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol)** is **production-ready**.
1545
1703
 
1546
- Starting from librdkafka 2.4.0 the next generation consumer group rebalance protocol
1547
- defined in KIP 848 is introduced.
1704
+ **Note:** The new consumer group protocol defined in [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol) is not enabled by default. There are few contract change associated with the new protocol and might cause breaking changes. `group.protocol` configuration property dictates whether to use the new `consumer` protocol or older `classic` protocol. It defaults to `classic` if not provided.
1548
1705
 
1549
- **Warning**
1550
- It's still in **Early Access** which means it's _not production-ready_,
1551
- given it's still under validation and lacking some needed features.
1552
- Features and their contract might change in future.
1706
+ <a name="overview"></a>
1707
+ #### Overview
1708
+ - **What changed:**
1709
+ The **Group Leader role** (consumer member) is removed. Assignments are calculated by the **Group Coordinator (broker)** and distributed via **heartbeats**.
1553
1710
 
1554
- With this protocol the role of the Group Leader (a member) is removed and
1555
- the assignment is calculated by the Group Coordinator (a broker) and sent
1556
- to each member through heartbeats.
1711
+ - **Requirements:**
1712
+ - Broker version: **v4.0.0+**
1713
+ - librdkafka version: **v2.12.0+**: GA (production-ready)
1557
1714
 
1558
- To test it, a Kafka cluster must be set up, in KRaft mode, and the new group
1559
- protocol enabled with the `group.coordinator.rebalance.protocols` property.
1560
- Broker version must be Apache Kafka 3.7.0 or newer. See Apache Kafka
1561
- [Release Notes](https://cwiki.apache.org/confluence/display/KAFKA/The+Next+Generation+of+the+Consumer+Rebalance+Protocol+%28KIP-848%29+-+Early+Access+Release+Notes).
1715
+ - **Enablement (client-side):**
1716
+ - `group.protocol=consumer`
1717
+ - `group.remote.assignor=<assignor>` (optional; broker-controlled if `NULL`; default broker assignor is **`uniform`**)
1562
1718
 
1563
- Client side, it can be enabled by setting the new property `group.protocol=consumer`.
1564
- A second property named `group.remote.assignor` is added to choose desired
1565
- remote assignor.
1719
+ <a name="available-features"></a>
1720
+ #### Available Features
1566
1721
 
1567
- **Available features**
1722
+ All [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol) features are supported including:
1568
1723
 
1569
- - Subscription to one or more topics
1570
- - Rebalance callbacks (see contract changes)
1724
+ - Subscription to one or more topics, including **regular expression (regex) subscriptions**
1725
+ - Rebalance callbacks (**incremental only**)
1571
1726
  - Static group membership
1572
- - Configure remote assignor
1573
- - Max poll interval is enforced
1574
- - Offline upgrade from an empty consumer group with committed offsets
1575
-
1576
- **Future features**
1577
-
1578
- - Regular expression support when subscribing
1579
- - AdminClient changes as described in the KIP
1580
-
1581
- **Contract changes**
1582
-
1583
- Along with the new feature there are some needed contract changes,
1584
- so the protocol will be enabled by default only with a librdkafka major release.
1585
-
1586
- - Deprecated client configurations with the new protocol:
1587
- - `partition.assignment.strategy` replaced by `group.remote.assignor`
1588
- - `session.timeout.ms` replaced by broker configuration `group.consumer.session.timeout.ms`
1589
- - `heartbeat.interval.ms`, replaced by broker configuration `group.consumer.heartbeat.interval.ms`
1590
- - `group.protocol.type` which is not used in the new protocol
1591
-
1592
- - Protocol rebalance is fully incremental, so the only allowed functions to
1593
- use in a rebalance callback will be `rd_kafka_incremental_assign` and
1594
- `rd_kafka_incremental_unassign`. Currently you can still use existing code
1595
- and the expected function to call is determined based on the chosen
1596
- `partition.assignment.strategy` but this will be removed in next
1597
- release.
1598
-
1599
- When setting the `group.remote.assignor` property, it's already
1600
- required to use the incremental assign and unassign functions.
1601
- All assignors are sticky with new protocol, including the _range_ one, that wasn't.
1602
-
1603
- - With a static group membership, if two members are using the same
1604
- `group.instance.id`, the one that joins the consumer group later will be
1605
- fenced, with the fatal `UNRELEASED_INSTANCE_ID` error. Before, it was the existing
1606
- member to be fenced. This was changed to avoid two members contending the
1607
- same id. It also means that any instance that crashes won't be automatically
1608
- replaced by a new instance until session times out and it's especially required
1609
- to check that consumers are being closed properly on shutdown. Ensuring that
1610
- no two instances with same `group.instance.id` are running at any time
1611
- is also important.
1612
-
1613
- - Session timeout is remote only and, if the Coordinator isn't reachable
1614
- by a member, this will continue to fetch messages, even if it won't be able to
1615
- commit them. Otherwise, the member will be fenced as soon as it receives an
1616
- heartbeat response from the Coordinator.
1617
- With `classic` protocol, instead, member stops fetching when session timeout
1618
- expires on the client.
1619
-
1620
- For the same reason, when closing or unsubscribing with auto-commit set,
1621
- the member will try to commit until a specific timeout has passed.
1622
- Currently the timeout is the same as the `classic` protocol and it corresponds
1623
- to the `session.timeout.ms`, but it will change before the feature
1624
- reaches a stable state.
1625
-
1626
- - An `UNKNOWN_TOPIC_OR_PART` error isn't received anymore when a consumer is
1627
- subscribing to a topic that doesn't exist in local cache, as the consumer
1628
- is still subscribing to the topic and it could be created just after that.
1629
-
1630
- - A consumer won't do a preliminary Metadata call that returns a
1631
- `TOPIC_AUTHORIZATION_FAILED`, as it's happening with group protocol `classic`.
1632
- Topic partitions will still be assigned to the member
1633
- by the Coordinator only if it's authorized to consume from the topic.
1727
+ - Configurable remote assignor
1728
+ - Enforced max poll interval
1729
+ - Upgrade from `classic` protocol or downgrade from `consumer` protocol
1730
+ - AdminClient changes as per KIP
1731
+
1732
+ <a name="contract-changes"></a>
1733
+ #### Contract Changes
1734
+
1735
+ <a name="client-configuration-changes"></a>
1736
+ ##### Client Configuration changes
1737
+
1738
+ | Classic Protocol (Deprecated Configs in KIP-848) | KIP-848 / Next-Gen Replacement |
1739
+ | ------------------------------------------------ | ----------------------------------------------------- |
1740
+ | `partition.assignment.strategy` | `group.remote.assignor` |
1741
+ | `session.timeout.ms` | Broker config: `group.consumer.session.timeout.ms` |
1742
+ | `heartbeat.interval.ms` | Broker config: `group.consumer.heartbeat.interval.ms` |
1743
+ | `group.protocol.type` | Not used in the new protocol |
1744
+
1745
+ **Note:** The properties listed under “Classic Protocol (Deprecated Configs in KIP-848)” are **no longer used** when using the KIP-848 consumer protocol.
1746
+
1747
+ <a name="rebalance-callback-changes"></a>
1748
+ ##### Rebalance Callback Changes
1749
+
1750
+ - Protocol is **fully incremental**.
1751
+ - **Inside the rebalance callback**, you **must use**:
1752
+ - `rd_kafka_incremental_assign(rk, partitions)` to assign partitions
1753
+ - `rd_kafka_incremental_unassign(rk, partitions)` to revoke partitions
1754
+ - **Do not** use `rd_kafka_assign()` or other assignment APIs in KIP-848.
1755
+ - **Important:** The `partitions` parameter passed to `rd_kafka_incremental_assign` or `rd_kafka_incremental_unassign` contains only an **incremental list of partitions**—those being added or revoked—rather than the full partition list returned by `rd_kafka_assign(rk, partitions)` in the **range assignor of the classic protocol**, which was the default.
1756
+ - All assignors are **sticky**, including `range` (which wasn’t sticky before).
1757
+
1758
+ <a name="static-group-membership"></a>
1759
+ ##### Static Group Membership
1760
+
1761
+ - Duplicate `group.instance.id` handling:
1762
+ - **Newly joining member** is fenced with **UNRELEASED_INSTANCE_ID (fatal)**.
1763
+ - (Classic protocol fenced the **existing** member instead.)
1764
+ - Implications:
1765
+ - Ensure only **one active instance per `group.instance.id`**.
1766
+ - Consumers must shut down cleanly to avoid blocking replacements until session timeout expires.
1767
+
1768
+ <a name="session-timeout--fetching"></a>
1769
+ ##### Session Timeout & Fetching
1770
+
1771
+ - **Session timeout is broker-controlled**:
1772
+ - If the Coordinator is unreachable, a consumer **continues fetching messages** but cannot commit offsets.
1773
+ - Consumer is fenced once a heartbeat response is received from the Coordinator.
1774
+ - In the classic protocol, the client stopped fetching when session timeout expired.
1775
+
1776
+ <a name="closing--auto-commit"></a>
1777
+ ##### Closing / Auto-Commit
1778
+
1779
+ - On `close()` or unsubscribe with auto-commit enabled:
1780
+ - Member retries committing offsets until a timeout expires.
1781
+ - Currently uses the **default remote session timeout**.
1782
+ - Future **KIP-1092** will allow custom commit timeouts.
1783
+
1784
+ <a name="error-handling-changes"></a>
1785
+ ##### Error Handling Changes
1786
+
1787
+ - `UNKNOWN_TOPIC_OR_PART` (**subscription case**):
1788
+ - No longer returned if a topic is missing in the **local cache** when subscribing; the subscription proceeds.
1789
+ - `TOPIC_AUTHORIZATION_FAILED`:
1790
+ - Reported once per heartbeat or subscription change, even if only one topic is unauthorized.
1791
+
1792
+ <a name="summary-of-key-differences-classic-vs-next-gen"></a>
1793
+ ##### Summary of Key Differences (Classic vs Next-Gen)
1794
+
1795
+ - **Assignment:** Classic protocol calculated by **Group Leader (consumer)**; KIP-848 calculated by **Group Coordinator (broker)**
1796
+ - **Assignors:** Classic range assignor was **not sticky**; KIP-848 assignors are **sticky**, including range
1797
+ - **Deprecated configs:** Classic client configs are replaced by `group.remote.assignor` and broker-controlled session/heartbeat configs
1798
+ - **Static membership fencing:** KIP-848 fences **new member** on duplicate `group.instance.id`
1799
+ - **Session timeout:** Classic enforced on client; KIP-848 enforced on broker
1800
+ - **Auto-commit on close:** Classic stops at client session timeout; KIP-848 retries until remote timeout
1801
+ - **Unknown topics:** KIP-848 does not return error on subscription if topic missing
1802
+ - **Upgrade/Downgrade:** KIP-848 supports upgrade/downgrade from/to `classic` and `consumer` protocols
1803
+
1804
+ <a name="minimal-example-config"></a>
1805
+ #### Minimal Example Config
1806
+
1807
+ <a name="classic-protocol"></a>
1808
+ ##### Classic Protocol
1809
+ ```properties
1810
+ # Optional; default is 'classic'
1811
+ group.protocol=classic
1812
+
1813
+ partition.assignment.strategy=<range,roundrobin,sticky>
1814
+ session.timeout.ms=45000
1815
+ heartbeat.interval.ms=15000
1816
+ ```
1817
+
1818
+ <a name="next-gen-protocol--kip-848"></a>
1819
+ ##### Next-Gen Protocol / KIP-848
1820
+ ```properties
1821
+ group.protocol=consumer
1822
+
1823
+ # Optional: select a remote assignor
1824
+ # Valid options currently: 'uniform' or 'range'
1825
+ # group.remote.assignor=<uniform,range>
1826
+ # If unset(NULL), broker chooses the assignor (default: 'uniform')
1827
+
1828
+ # Session & heartbeat now controlled by broker:
1829
+ # group.consumer.session.timeout.ms
1830
+ # group.consumer.heartbeat.interval.ms
1831
+ ```
1832
+
1833
+ <a name="rebalance-callback-migration"></a>
1834
+ #### Rebalance Callback Migration
1835
+
1836
+ <a name="range-assignor-classic"></a>
1837
+ ##### Range Assignor (Classic)
1838
+ ```c
1839
+ /* Rebalance callback for range assignor (classic) */
1840
+ static void rebalance_cb (rd_kafka_t *rk,
1841
+ rd_kafka_resp_err_t err,
1842
+ rd_kafka_topic_partition_list_t *partitions,
1843
+ void *opaque) {
1844
+ switch (err) {
1845
+ case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
1846
+ rd_kafka_assign(rk, partitions); /* full partition list */
1847
+ break;
1848
+
1849
+ case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
1850
+ rd_kafka_assign(rk, NULL); /* revoke all partitions */
1851
+ break;
1852
+
1853
+ default:
1854
+ fprintf(stderr, "Rebalance error: %s\n", rd_kafka_err2str(err));
1855
+ break;
1856
+ }
1857
+ }
1858
+ ```
1859
+
1860
+ <a name="incremental-assignor-including-range-in-consumer--kip-848-any-protocol"></a>
1861
+ ##### Incremental Assignor (Including Range in Consumer / KIP-848, Any Protocol)
1862
+
1863
+ ```c
1864
+ /* Rebalance callback for incremental assignor */
1865
+ static void rebalance_cb (rd_kafka_t *rk,
1866
+ rd_kafka_resp_err_t err,
1867
+ rd_kafka_topic_partition_list_t *partitions,
1868
+ void *opaque) {
1869
+ switch (err) {
1870
+ case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
1871
+ rd_kafka_incremental_assign(rk, partitions); /* incremental partitions only */
1872
+ break;
1873
+
1874
+ case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
1875
+ rd_kafka_incremental_unassign(rk, partitions);
1876
+ break;
1877
+
1878
+ default:
1879
+ fprintf(stderr, "Rebalance error: %s\n", rd_kafka_err2str(err));
1880
+ break;
1881
+ }
1882
+ }
1883
+ ```
1884
+ **Note:**
1885
+ - The `partitions` list contains **only partitions being added or revoked**, not the full partition list as in the classic `rd_kafka_assign()`.
1634
1886
 
1887
+ <a name="upgrade-and-downgrade"></a>
1888
+ #### Upgrade and Downgrade
1635
1889
 
1890
+ - A group made up entirely of `classic` consumers runs under the classic protocol.
1891
+ - The group is **upgraded to the consumer protocol** as soon as at least one `consumer` protocol member joins.
1892
+ - The group is **downgraded back to the classic protocol** if the last `consumer` protocol member leaves while `classic` members remain.
1893
+ - Both **rolling upgrade** (classic → consumer) and **rolling downgrade** (consumer → classic) are supported.
1894
+
1895
+
1896
+ <a name="migration-checklist-next-gen-protocol--kip-848"></a>
1897
+ #### Migration Checklist (Next-Gen Protocol / [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol))
1898
+
1899
+ 1. Upgrade to **librdkafka ≥ v2.12.0** (GA release)
1900
+ 2. Run against **Kafka brokers ≥ v4.0.0**
1901
+ 3. Set `group.protocol=consumer`
1902
+ 4. Optionally set `group.remote.assignor`; leave `NULL` for broker-controlled (default: `uniform`), valid options: `uniform` or `range`
1903
+ 5. Replace deprecated configs with new ones
1904
+ 6. Update rebalance callbacks to **incremental APIs only**
1905
+ 7. Review static membership handling (`group.instance.id`)
1906
+ 8. Ensure proper shutdown to avoid fencing issues
1907
+ 9. Adjust error handling for unknown topics and authorization failures
1908
+
1909
+
1910
+ <a name="note-on-batch-consume-apis"></a>
1636
1911
  ### Note on Batch consume APIs
1637
1912
 
1638
1913
  Using multiple instances of `rd_kafka_consume_batch()` and/or `rd_kafka_consume_batch_queue()`
@@ -1653,8 +1928,10 @@ set `rebalance_cb` configuration property (refer [examples/rdkafka_complex_consu
1653
1928
  for the help with the usage) for the consumer.
1654
1929
 
1655
1930
 
1931
+ <a name="topics"></a>
1656
1932
  ### Topics
1657
1933
 
1934
+ <a name="unknown-or-unauthorized-topics"></a>
1658
1935
  #### Unknown or unauthorized topics
1659
1936
 
1660
1937
  If a consumer application subscribes to non-existent or unauthorized topics
@@ -1679,6 +1956,7 @@ occurs, for instance adjusting its subscription or assignment to exclude the
1679
1956
  unauthorized topic.
1680
1957
 
1681
1958
 
1959
+ <a name="topic-metadata-propagation-for-newly-created-topics"></a>
1682
1960
  #### Topic metadata propagation for newly created topics
1683
1961
 
1684
1962
  Due to the asynchronous nature of topic creation in Apache Kafka it may
@@ -1702,12 +1980,15 @@ Should the topic propagation time expire without the topic being seen the
1702
1980
  produced messages will fail with `RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC`.
1703
1981
 
1704
1982
  **Note**: The propagation time will not take affect if a topic is known to
1705
- the client and then deleted, in this case the topic will immediately
1706
- be marked as non-existent and remain non-existent until a topic
1707
- metadata refresh sees the topic again (after the topic has been
1708
- re-created).
1983
+ the client and then deleted, in this case the topic will immediately
1984
+ be marked as non-existent and remain non-existent until a topic
1985
+ metadata refresh sees the topic again (after the topic has been
1986
+ re-created).
1987
+
1988
+ **Note**: `RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC*` during a `subscribe()` call occurs **only with the classic protocol**. With the next-gen `consumer` protocol (KIP-848), subscription proceeds even if the topic is not yet in the local cache (e.g., it may be created later).
1709
1989
 
1710
1990
 
1991
+ <a name="topic-auto-creation"></a>
1711
1992
  #### Topic auto creation
1712
1993
 
1713
1994
  Topic auto creation is supported by librdkafka, if a non-existent topic is
@@ -1733,41 +2014,46 @@ be configured on the broker.
1733
2014
 
1734
2015
 
1735
2016
 
2017
+ <a name="metadata"></a>
1736
2018
  ### Metadata
1737
2019
 
2020
+ <a name="lt093"></a>
1738
2021
  #### < 0.9.3
1739
2022
  Previous to the 0.9.3 release librdkafka's metadata handling
1740
2023
  was chatty and excessive, which usually isn't a problem in small
1741
2024
  to medium-sized clusters, but in large clusters with a large amount
1742
2025
  of librdkafka clients the metadata requests could hog broker CPU and bandwidth.
1743
2026
 
2027
+ <a name="gt093-1"></a>
1744
2028
  #### > 0.9.3
1745
2029
 
1746
2030
  The remaining Metadata sections describe the current behaviour.
1747
2031
 
1748
2032
  **Note:** "Known topics" in the following section means topics for
1749
- locally created `rd_kafka_topic_t` objects.
2033
+ locally created `rd_kafka_topic_t` objects.
1750
2034
 
1751
2035
 
2036
+ <a name="query-reasons"></a>
1752
2037
  #### Query reasons
1753
2038
 
1754
2039
  There are four reasons to query metadata:
1755
2040
 
1756
- * brokers - update/populate cluster broker list, so the client can
1757
- find and connect to any new brokers added.
2041
+ * brokers - update/populate cluster broker list, so the client can
2042
+ find and connect to any new brokers added.
1758
2043
 
1759
- * specific topic - find leader or partition count for specific topic
2044
+ * specific topic - find leader or partition count for specific topic
1760
2045
 
1761
- * known topics - same, but for all locally known topics.
2046
+ * known topics - same, but for all locally known topics.
1762
2047
 
1763
- * all topics - get topic names for consumer group wildcard subscription
1764
- matching
2048
+ * all topics - get topic names for consumer group wildcard subscription
2049
+ matching
1765
2050
 
1766
2051
  The above list is sorted so that the sub-sequent entries contain the
1767
2052
  information above, e.g., 'known topics' contains enough information to
1768
2053
  also satisfy 'specific topic' and 'brokers'.
1769
2054
 
1770
2055
 
2056
+ <a name="caching-strategy"></a>
1771
2057
  #### Caching strategy
1772
2058
 
1773
2059
  The prevalent cache timeout is `metadata.max.age.ms`, any cached entry
@@ -1775,35 +2061,37 @@ will remain authoritative for this long or until a relevant broker error
1775
2061
  is returned.
1776
2062
 
1777
2063
 
1778
- * brokers - eternally cached, the broker list is additative.
2064
+ * brokers - eternally cached, the broker list is additative.
1779
2065
 
1780
- * topics - cached for `metadata.max.age.ms`
2066
+ * topics - cached for `metadata.max.age.ms`
1781
2067
 
1782
2068
 
1783
2069
 
2070
+ <a name="fatal-errors"></a>
1784
2071
  ### Fatal errors
1785
2072
 
1786
2073
  If an unrecoverable error occurs, a fatal error is triggered in one
1787
2074
  or more of the follow ways depending on what APIs the application is utilizing:
1788
2075
 
1789
- * C: the `error_cb` is triggered with error code `RD_KAFKA_RESP_ERR__FATAL`,
1790
- the application should call `rd_kafka_fatal_error()` to retrieve the
1791
- underlying fatal error code and error string.
1792
- * C: an `RD_KAFKA_EVENT_ERROR` event is triggered and
1793
- `rd_kafka_event_error_is_fatal()` returns true: the fatal error code
1794
- and string are available through `rd_kafka_event_error()`, and `.._string()`.
1795
- * C and C++: any API call may return `RD_KAFKA_RESP_ERR__FATAL`, use
1796
- `rd_kafka_fatal_error()` to retrieve the underlying fatal error code
1797
- and error string.
1798
- * C++: an `EVENT_ERROR` event is triggered and `event.fatal()` returns true:
1799
- the fatal error code and string are available through `event.err()` and
1800
- `event.str()`.
2076
+ * C: the `error_cb` is triggered with error code `RD_KAFKA_RESP_ERR__FATAL`,
2077
+ the application should call `rd_kafka_fatal_error()` to retrieve the
2078
+ underlying fatal error code and error string.
2079
+ * C: an `RD_KAFKA_EVENT_ERROR` event is triggered and
2080
+ `rd_kafka_event_error_is_fatal()` returns true: the fatal error code
2081
+ and string are available through `rd_kafka_event_error()`, and `.._string()`.
2082
+ * C and C++: any API call may return `RD_KAFKA_RESP_ERR__FATAL`, use
2083
+ `rd_kafka_fatal_error()` to retrieve the underlying fatal error code
2084
+ and error string.
2085
+ * C++: an `EVENT_ERROR` event is triggered and `event.fatal()` returns true:
2086
+ the fatal error code and string are available through `event.err()` and
2087
+ `event.str()`.
1801
2088
 
1802
2089
 
1803
2090
  An application may call `rd_kafka_fatal_error()` at any time to check if
1804
2091
  a fatal error has been raised.
1805
2092
 
1806
2093
 
2094
+ <a name="fatal-producer-errors"></a>
1807
2095
  #### Fatal producer errors
1808
2096
 
1809
2097
  The idempotent producer guarantees of ordering and no duplicates also
@@ -1813,9 +2101,9 @@ can't be satisfied.
1813
2101
  If a fatal error has been raised, sub-sequent use of the following API calls
1814
2102
  will fail:
1815
2103
 
1816
- * `rd_kafka_produce()`
1817
- * `rd_kafka_producev()`
1818
- * `rd_kafka_produce_batch()`
2104
+ * `rd_kafka_produce()`
2105
+ * `rd_kafka_producev()`
2106
+ * `rd_kafka_produce_batch()`
1819
2107
 
1820
2108
  The underlying fatal error code will be returned, depending on the error
1821
2109
  reporting scheme for each of those APIs.
@@ -1831,6 +2119,7 @@ The purged messages in queue will fail with error code set to
1831
2119
  `RD_KAFKA_RESP_ERR__PURGE_QUEUE`.
1832
2120
 
1833
2121
 
2122
+ <a name="fatal-consumer-errors"></a>
1834
2123
  #### Fatal consumer errors
1835
2124
 
1836
2125
  A consumer configured for static group membership (`group.instance.id`) may
@@ -1838,13 +2127,13 @@ raise a fatal error if a new consumer instance is started with the same
1838
2127
  instance id, causing the existing consumer to be fenced by the new consumer.
1839
2128
 
1840
2129
  This fatal error is propagated on the fenced existing consumer in multiple ways:
1841
- * `error_cb` (if configured) is triggered.
1842
- * `rd_kafka_consumer_poll()` (et.al) will return a message object
1843
- with the `err` field set to `RD_KAFKA_ERR__FATAL`.
1844
- * any sub-sequent calls to state-changing consumer calls will
1845
- return `RD_KAFKA_ERR___FATAL`.
1846
- This includes `rd_kafka_subscribe()`, `rd_kafka_assign()`,
1847
- `rd_kafka_consumer_close()`, `rd_kafka_commit*()`, etc.
2130
+ * `error_cb` (if configured) is triggered.
2131
+ * `rd_kafka_consumer_poll()` (et.al) will return a message object
2132
+ with the `err` field set to `RD_KAFKA_ERR__FATAL`.
2133
+ * any sub-sequent calls to state-changing consumer calls will
2134
+ return `RD_KAFKA_ERR___FATAL`.
2135
+ This includes `rd_kafka_subscribe()`, `rd_kafka_assign()`,
2136
+ `rd_kafka_consumer_close()`, `rd_kafka_commit*()`, etc.
1848
2137
 
1849
2138
  The consumer will automatically stop consuming when a fatal error has occurred
1850
2139
  and no further subscription, assignment, consumption or offset committing
@@ -1853,8 +2142,10 @@ consumer instance and terminate the application since it has been replaced
1853
2142
  by a newer instance.
1854
2143
 
1855
2144
 
2145
+ <a name="compatibility"></a>
1856
2146
  ## Compatibility
1857
2147
 
2148
+ <a name="broker-version-compatibility"></a>
1858
2149
  ### Broker version compatibility
1859
2150
 
1860
2151
  librdkafka supports all released Apache Kafka broker versions since 0.8.0.0.0,
@@ -1862,13 +2153,14 @@ but not all features may be available on all broker versions since some
1862
2153
  features rely on newer broker functionality.
1863
2154
 
1864
2155
  **Current defaults:**
1865
- * `api.version.request=true`
1866
- * `broker.version.fallback=0.10.0`
1867
- * `api.version.fallback.ms=0` (never revert to `broker.version.fallback`)
2156
+ * `api.version.request=true`
2157
+ * `broker.version.fallback=0.10.0`
2158
+ * `api.version.fallback.ms=0` (never revert to `broker.version.fallback`)
1868
2159
 
1869
2160
  Depending on what broker version you are using, please configure your
1870
2161
  librdkafka based client as follows:
1871
2162
 
2163
+ <a name="broker-version--01000-or-trunk"></a>
1872
2164
  #### Broker version >= 0.10.0.0 (or trunk)
1873
2165
 
1874
2166
  For librdkafka >= v1.0.0 there is no need to set any api.version-related
@@ -1882,6 +2174,7 @@ api.version.fallback.ms=0
1882
2174
  ```
1883
2175
 
1884
2176
 
2177
+ <a name="broker-versions-090x"></a>
1885
2178
  #### Broker versions 0.9.0.x
1886
2179
 
1887
2180
  ```
@@ -1889,6 +2182,7 @@ api.version.request=false
1889
2182
  broker.version.fallback=0.9.0.x (the exact 0.9.0.. version you are using)
1890
2183
  ```
1891
2184
 
2185
+ <a name="broker-versions-08xy"></a>
1892
2186
  #### Broker versions 0.8.x.y
1893
2187
 
1894
2188
  ```
@@ -1896,6 +2190,7 @@ api.version.request=false
1896
2190
  broker.version.fallback=0.8.x.y (your exact 0.8... broker version)
1897
2191
  ```
1898
2192
 
2193
+ <a name="detailed-description"></a>
1899
2194
  #### Detailed description
1900
2195
 
1901
2196
  Apache Kafka version 0.10.0.0 added support for
@@ -1906,27 +2201,27 @@ But for older broker versions there is no way for the client to reliably know
1906
2201
  what protocol features the broker supports.
1907
2202
 
1908
2203
  To alleviate this situation librdkafka has three configuration properties:
1909
- * `api.version.request=true|false` - enables the API version request,
1910
- this requires a >= 0.10.0.0 broker and will cause a disconnect on
1911
- brokers 0.8.x - this disconnect is recognized by librdkafka and on the next
1912
- connection attempt (which is immediate) it will disable the API version
1913
- request and use `broker.version.fallback` as a basis of available features.
1914
- **NOTE**: Due to a bug in broker version 0.9.0.0 & 0.9.0.1 the broker will
1915
- not close the connection when receiving the API version request, instead
1916
- the request will time out in librdkafka after 10 seconds and it will fall
1917
- back to `broker.version.fallback` on the next immediate connection attempt.
1918
- * `broker.version.fallback=X.Y.Z.N` - if the API version request fails
1919
- (if `api.version.request=true`) or API version requests are disabled
1920
- (`api.version.request=false`) then this tells librdkafka what version the
1921
- broker is running and adapts its feature set accordingly.
1922
- * `api.version.fallback.ms=MS` - In the case where `api.version.request=true`
1923
- and the API version request fails, this property dictates for how long
1924
- librdkafka will use `broker.version.fallback` instead of
1925
- `api.version.request=true`. After `MS` has passed the API version request
1926
- will be sent on any new connections made for the broker in question.
1927
- This allows upgrading the Kafka broker to a new version with extended
1928
- feature set without needing to restart or reconfigure the client
1929
- (given that `api.version.request=true`).
2204
+ * `api.version.request=true|false` - enables the API version request,
2205
+ this requires a >= 0.10.0.0 broker and will cause a disconnect on
2206
+ brokers 0.8.x - this disconnect is recognized by librdkafka and on the next
2207
+ connection attempt (which is immediate) it will disable the API version
2208
+ request and use `broker.version.fallback` as a basis of available features.
2209
+ **NOTE**: Due to a bug in broker version 0.9.0.0 & 0.9.0.1 the broker will
2210
+ not close the connection when receiving the API version request, instead
2211
+ the request will time out in librdkafka after 10 seconds and it will fall
2212
+ back to `broker.version.fallback` on the next immediate connection attempt.
2213
+ * `broker.version.fallback=X.Y.Z.N` - if the API version request fails
2214
+ (if `api.version.request=true`) or API version requests are disabled
2215
+ (`api.version.request=false`) then this tells librdkafka what version the
2216
+ broker is running and adapts its feature set accordingly.
2217
+ * `api.version.fallback.ms=MS` - In the case where `api.version.request=true`
2218
+ and the API version request fails, this property dictates for how long
2219
+ librdkafka will use `broker.version.fallback` instead of
2220
+ `api.version.request=true`. After `MS` has passed the API version request
2221
+ will be sent on any new connections made for the broker in question.
2222
+ This allows upgrading the Kafka broker to a new version with extended
2223
+ feature set without needing to restart or reconfigure the client
2224
+ (given that `api.version.request=true`).
1930
2225
 
1931
2226
  *Note: These properties applies per broker.*
1932
2227
 
@@ -1936,13 +2231,14 @@ broker version 0.9.0.0 & 0.9.0.1, but was changed to `true` in
1936
2231
  librdkafka v0.11.0.
1937
2232
 
1938
2233
 
2234
+ <a name="supported-kips"></a>
1939
2235
  ### Supported KIPs
1940
2236
 
1941
2237
  The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Improvement+Proposals) supported by librdkafka.
1942
2238
 
1943
2239
 
1944
2240
  | KIP | Kafka release | Status |
1945
- |--------------------------------------------------------------------------|-----------------------------|-----------------------------------------------------------------------------------------------|
2241
+ | ------------------------------------------------------------------------ | --------------------------- | --------------------------------------------------------------------------------------------- |
1946
2242
  | KIP-1 - Stop accepting request.required.acks > 1 | 0.9.0.0 | Not enforced on client (due to backwards compat with brokers <0.8.3) |
1947
2243
  | KIP-4 - Metadata protocol changes | 0.9.0.0, 0.10.0.0, 0.10.1.0 | Supported |
1948
2244
  | KIP-8 - Producer flush() | 0.9.0.0 | Supported |
@@ -2055,67 +2351,75 @@ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/conf
2055
2351
  | KIP-735 - Increase default consumer session timeout | 3.0.0 | Supported |
2056
2352
  | KIP-768 - SASL/OAUTHBEARER OIDC support | 3.0 | Supported |
2057
2353
  | KIP-881 - Rack-aware Partition Assignment for Kafka Consumers | 3.5.0 | Supported |
2058
- | KIP-848 - The Next Generation of the Consumer Rebalance Protocol | 3.7.0 (EA) | Early Access |
2354
+ | KIP-848 - The Next Generation of the Consumer Rebalance Protocol | 4.0.0 | Supported |
2355
+ | KIP-899 - Allow producer and consumer clients to rebootstrap | 3.8.0 | Supported |
2059
2356
  | KIP-951 - Leader discovery optimisations for the client | 3.7.0 | Supported |
2357
+ | KIP-1082 - Require Client-Generated IDs over the ConsumerGroupHeartbeat | 4.0.0 | Supported |
2358
+ | KIP-1102 - Enable clients to rebootstrap based on timeout or error code | 4.0.0 | Supported |
2359
+ | KIP-1139 - Add support for OAuth jwt-bearer grant type | 4.1.0 (WIP) | Supported |
2060
2360
 
2061
2361
 
2062
2362
 
2063
2363
 
2364
+ <a name="supported-protocol-versions"></a>
2064
2365
  ### Supported protocol versions
2065
2366
 
2066
- "Kafka max" is the maximum ApiVersion supported in Apache Kafka 3.7.0, while
2367
+ "Kafka max" is the maximum ApiVersion supported in Apache Kafka 4.0.0, while
2067
2368
  "librdkafka max" is the maximum ApiVersion supported in the latest
2068
2369
  release of librdkafka.
2069
2370
 
2070
2371
 
2071
- | ApiKey | Request name | Kafka max | librdkafka max |
2072
- | ------- | ----------------------------- | ---------- | -------------- |
2073
- | 0 | Produce | 10 | 10 |
2074
- | 1 | Fetch | 16 | 16 |
2075
- | 2 | ListOffsets | 8 | 7 |
2076
- | 3 | Metadata | 12 | 12 |
2077
- | 8 | OffsetCommit | 9 | 9 |
2078
- | 9 | OffsetFetch | 9 | 9 |
2079
- | 10 | FindCoordinator | 4 | 2 |
2080
- | 11 | JoinGroup | 9 | 5 |
2081
- | 12 | Heartbeat | 4 | 3 |
2082
- | 13 | LeaveGroup | 5 | 1 |
2083
- | 14 | SyncGroup | 5 | 3 |
2084
- | 15 | DescribeGroups | 5 | 4 |
2085
- | 16 | ListGroups | 4 | 4 |
2086
- | 17 | SaslHandshake | 1 | 1 |
2087
- | 18 | ApiVersions | 3 | 3 |
2088
- | 19 | CreateTopics | 7 | 4 |
2089
- | 20 | DeleteTopics | 6 | 1 |
2090
- | 21 | DeleteRecords | 2 | 1 |
2091
- | 22 | InitProducerId | 4 | 4 |
2092
- | 23 | OffsetForLeaderEpoch | 4 | 2 |
2093
- | 24 | AddPartitionsToTxn | 4 | 0 |
2094
- | 25 | AddOffsetsToTxn | 3 | 0 |
2095
- | 26 | EndTxn | 3 | 1 |
2096
- | 28 | TxnOffsetCommit | 3 | 3 |
2097
- | 29 | DescribeAcls | 3 | 1 |
2098
- | 30 | CreateAcls | 3 | 1 |
2099
- | 31 | DeleteAcls | 3 | 1 |
2100
- | 32 | DescribeConfigs | 4 | 1 |
2101
- | 33 | AlterConfigs | 2 | 2 |
2102
- | 36 | SaslAuthenticate | 2 | 1 |
2103
- | 37 | CreatePartitions | 3 | 0 |
2104
- | 42 | DeleteGroups | 2 | 1 |
2105
- | 43 | ElectLeaders | 2 | 2 |
2106
- | 44 | IncrementalAlterConfigs | 1 | 1 |
2107
- | 47 | OffsetDelete | 0 | 0 |
2108
- | 50 | DescribeUserScramCredentials | 0 | 0 |
2109
- | 51 | AlterUserScramCredentials | 0 | 0 |
2110
- | 68 | ConsumerGroupHeartbeat | 0 | 0 |
2111
- | 71 | GetTelemetrySubscriptions | 0 | 0 |
2112
- | 72 | PushTelemetry | 0 | 0 |
2113
-
2372
+ | ApiKey | Request name | Kafka max | librdkafka max |
2373
+ | ------ | ---------------------------- | --------- | -------------- |
2374
+ | 0 | Produce | 12 | 10 |
2375
+ | 1 | Fetch | 17 | 16 |
2376
+ | 2 | ListOffsets | 10 | 7 |
2377
+ | 3 | Metadata | 13 | 13 |
2378
+ | 8 | OffsetCommit | 9 | 9 |
2379
+ | 9 | OffsetFetch | 9 | 9 |
2380
+ | 10 | FindCoordinator | 6 | 2 |
2381
+ | 11 | JoinGroup | 9 | 5 |
2382
+ | 12 | Heartbeat | 4 | 3 |
2383
+ | 13 | LeaveGroup | 5 | 1 |
2384
+ | 14 | SyncGroup | 5 | 3 |
2385
+ | 15 | DescribeGroups | 6 | 4 |
2386
+ | 16 | ListGroups | 5 | 4 |
2387
+ | 17 | SaslHandshake | 1 | 1 |
2388
+ | 18 | ApiVersions | 4 | 3 |
2389
+ | 19 | CreateTopics | 7 | 4 |
2390
+ | 20 | DeleteTopics | 6 | 1 |
2391
+ | 21 | DeleteRecords | 2 | 1 |
2392
+ | 22 | InitProducerId | 5 | 4 |
2393
+ | 23 | OffsetForLeaderEpoch | 4 | 2 |
2394
+ | 24 | AddPartitionsToTxn | 5 | 0 |
2395
+ | 25 | AddOffsetsToTxn | 4 | 0 |
2396
+ | 26 | EndTxn | 5 | 1 |
2397
+ | 28 | TxnOffsetCommit | 5 | 3 |
2398
+ | 29 | DescribeAcls | 3 | 1 |
2399
+ | 30 | CreateAcls | 3 | 1 |
2400
+ | 31 | DeleteAcls | 3 | 1 |
2401
+ | 32 | DescribeConfigs | 4 | 1 |
2402
+ | 33 | AlterConfigs | 2 | 2 |
2403
+ | 36 | SaslAuthenticate | 2 | 1 |
2404
+ | 37 | CreatePartitions | 3 | 0 |
2405
+ | 42 | DeleteGroups | 2 | 1 |
2406
+ | 43 | ElectLeaders | 2 | 2 |
2407
+ | 44 | IncrementalAlterConfigs | 1 | 1 |
2408
+ | 47 | OffsetDelete | 0 | 0 |
2409
+ | 50 | DescribeUserScramCredentials | 0 | 0 |
2410
+ | 51 | AlterUserScramCredentials | 0 | 0 |
2411
+ | 68 | ConsumerGroupHeartbeat | 1 | 1 |
2412
+ | 69 | ConsumerGroupDescribe | 1 | 0 |
2413
+ | 71 | GetTelemetrySubscriptions | 0 | 0 |
2414
+ | 72 | PushTelemetry | 0 | 0 |
2415
+
2416
+ <a name="recommendations-for-language-binding-developers"></a>
2114
2417
  # Recommendations for language binding developers
2115
2418
 
2116
2419
  These recommendations are targeted for developers that wrap librdkafka
2117
2420
  with their high-level languages, such as confluent-kafka-go or node-rdkafka.
2118
2421
 
2422
+ <a name="expose-the-configuration-interface-pass-thru"></a>
2119
2423
  ## Expose the configuration interface pass-thru
2120
2424
 
2121
2425
  librdkafka's string-based key=value configuration property interface controls
@@ -2130,6 +2434,7 @@ in a pass-through fashion without any pre-checking done by your binding code it
2130
2434
  means that a simple upgrade of the underlying librdkafka library (but not your
2131
2435
  bindings) will provide new features to the user.
2132
2436
 
2437
+ <a name="error-constants"></a>
2133
2438
  ## Error constants
2134
2439
 
2135
2440
  The error constants, both the official (value >= 0) errors as well as the
@@ -2138,6 +2443,7 @@ To avoid hard-coding them to expose to your users, librdkafka provides an API
2138
2443
  to extract the full list programmatically during runtime or for
2139
2444
  code generation, see `rd_kafka_get_err_descs()`.
2140
2445
 
2446
+ <a name="reporting-client-software-name-and-version-to-broker"></a>
2141
2447
  ## Reporting client software name and version to broker
2142
2448
 
2143
2449
  [KIP-511](https://cwiki.apache.org/confluence/display/KAFKA/KIP-511%3A+Collect+and+Expose+Client%27s+Name+and+Version+in+the+Brokers) introduces a means for a
@@ -2151,23 +2457,25 @@ librdkafka will send its name (`librdkafka`) and version (e.g., `v1.3.0`)
2151
2457
  upon connect to a supporting broker.
2152
2458
  To help distinguish high-level client bindings on top of librdkafka, a client
2153
2459
  binding should configure the following two properties:
2154
- * `client.software.name` - set to the binding name, e.g,
2155
- `confluent-kafka-go` or `node-rdkafka`.
2156
- * `client.software.version` - the version of the binding and the version
2157
- of librdkafka, e.g., `v1.3.0-librdkafka-v1.3.0` or
2158
- `1.2.0-librdkafka-v1.3.0`.
2159
- It is **highly recommended** to include the librdkafka version in this
2160
- version string.
2460
+ * `client.software.name` - set to the binding name, e.g,
2461
+ `confluent-kafka-go` or `node-rdkafka`.
2462
+ * `client.software.version` - the version of the binding and the version
2463
+ of librdkafka, e.g., `v1.3.0-librdkafka-v1.3.0` or
2464
+ `1.2.0-librdkafka-v1.3.0`.
2465
+ It is **highly recommended** to include the librdkafka version in this
2466
+ version string.
2161
2467
 
2162
2468
  These configuration properties are hidden (from CONFIGURATION.md et.al.) as
2163
2469
  they should typically not be modified by the user.
2164
2470
 
2471
+ <a name="documentation-reuse"></a>
2165
2472
  ## Documentation reuse
2166
2473
 
2167
2474
  You are free to reuse the librdkafka API and CONFIGURATION documentation in
2168
2475
  your project, but please do return any documentation improvements back to
2169
2476
  librdkafka (file a github pull request).
2170
2477
 
2478
+ <a name="community-support"></a>
2171
2479
  ## Community support
2172
2480
 
2173
2481
  Community support is offered through GitHub Issues and Discussions.