1 /* 2 * librdkafka - Apache Kafka C library 3 * 4 * Copyright (c) 2012-2013 Magnus Edenhill 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file rdkafka.h 31 * @brief Apache Kafka C/C++ consumer and producer client library. 32 * 33 * rdkafka.h contains the public API for librdkafka. 34 * The API is documented in this file as comments prefixing the function, type, 35 * enum, define, etc. 36 * 37 * @sa For the C++ interface see rdkafkacpp.h 38 * 39 * @tableofcontents 40 */ 41 42 43 /* @cond NO_DOC */ 44 module deimos.rdkafka; 45 46 import core.stdc.stdio; 47 import core.stdc.ctype; 48 import core.stdc.inttypes; 49 //import core.stdc.sys.types; 50 import core.sys.posix.sys.types; 51 //#include <inttypes.h> 52 //#include <sys/types.h> 53 version(Windows){ 54 import core.sys.windows.basetsd; 55 } 56 57 extern(C) nothrow @nogc: 58 59 60 /*#ifdef _MSC_VER 61 #include <basetsd.h> 62 typedef SSIZE_T ssize_t; 63 #define RD_UNUSED 64 #define RD_DEPRECATED 65 #undef 66 #ifdef LIBRDKAFKA_EXPORTS 67 #define __declspec(dllexport) 68 #else 69 #define __declspec(dllimport) 70 #endif 71 72 #else 73 #define RD_UNUSED __attribute__((unused)) 74 #define 75 #define RD_DEPRECATED __attribute__((deprecated)) 76 #endif*/ 77 78 /* @endcond */ 79 80 81 /** 82 * @brief Returns the librdkafka version as integer. 83 * 84 * @returns Version integer. 85 * 86 * @sa See RD_KAFKA_VERSION for how to parse the integer format. 87 * @sa Use rd_kafka_version_str() to retreive the version as a string. 88 */ 89 90 int rd_kafka_version(); 91 92 /** 93 * @brief Returns the librdkafka version as string. 94 * 95 * @returns Version string 96 */ 97 98 const(char) * rd_kafka_version_str (); 99 100 /**@}*/ 101 102 103 /** 104 * @name Constants, errors, types 105 * @{ 106 * 107 * 108 */ 109 110 111 /** 112 * @enum rd_kafka_type_t 113 * 114 * @brief rd_kafka_t handle type. 115 * 116 * @sa rd_kafka_new() 117 */ 118 enum rd_kafka_type_t { 119 RD_KAFKA_PRODUCER, /**< Producer client */ 120 RD_KAFKA_CONSUMER /**< Consumer client */ 121 } 122 //alias rd_kafka_type_t; 123 124 125 /** 126 * @enum Timestamp types 127 * 128 * @sa rd_kafka_message_timestamp() 129 */ 130 enum rd_kafka_timestamp_type_t { 131 RD_KAFKA_TIMESTAMP_NOT_AVAILABLE, /**< Timestamp not available */ 132 RD_KAFKA_TIMESTAMP_CREATE_TIME, /**< Message creation time */ 133 RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME /**< Log append time */ 134 } 135 136 137 /** 138 * @brief Retrieve supported debug contexts for use with the \c \"debug\" 139 * configuration property. (runtime) 140 * 141 * @returns Comma-separated list of available debugging contexts. 142 */ 143 144 const(char) *rd_kafka_get_debug_contexts(); 145 146 /** 147 * @brief Supported debug contexts. (compile time) 148 * 149 * @deprecated This compile time value may be outdated at runtime due to 150 * linking another version of the library. 151 * Use rd_kafka_get_debug_contexts() instead. 152 */ 153 deprecated("please Use rd_kafka_get_debug_contexts() instead."){ 154 enum RD_KAFKA_DEBUG_CONTEXTS = "all,generic,broker,topic,metadata,queue,msg,protocol,cgrp,security,fetch,feature"; 155 } 156 157 158 /* @cond NO_DOC */ 159 /* Private types to provide ABI compatibility */ 160 161 struct rd_kafka_s{} 162 struct rd_kafka_topic_s{} 163 struct rd_kafka_conf_s{} 164 struct rd_kafka_topic_conf_s{} 165 struct rd_kafka_queue_s{} 166 167 alias rd_kafka_t = rd_kafka_s; 168 alias rd_kafka_topic_t = rd_kafka_topic_s; 169 alias rd_kafka_conf_t = rd_kafka_conf_s; 170 alias rd_kafka_topic_conf_t = rd_kafka_topic_conf_s; 171 alias rd_kafka_queue_t = rd_kafka_queue_s; 172 /* 173 typedef struct rd_kafka_s rd_kafka_t; 174 typedef struct rd_kafka_topic_s rd_kafka_topic_t; 175 typedef struct rd_kafka_conf_s rd_kafka_conf_t; 176 typedef struct rd_kafka_topic_conf_s rd_kafka_topic_conf_t; 177 typedef struct rd_kafka_queue_s rd_kafka_queue_t;*/ 178 /* @endcond */ 179 180 181 /** 182 * @enum rd_kafka_resp_err_t 183 * @brief Error codes. 184 * 185 * The negative error codes delimited by two underscores 186 * (\c RD_KAFKA_RESP_ERR__..) denotes errors internal to librdkafka and are 187 * displayed as \c \"Local: \<error string..\>\", while the error codes 188 * delimited by a single underscore (\c RD_KAFKA_RESP_ERR_..) denote broker 189 * errors and are displayed as \c \"Broker: \<error string..\>\". 190 * 191 * @sa Use rd_kafka_err2str() to translate an error code a human readable string 192 */ 193 enum rd_kafka_resp_err_t { 194 /* Internal errors to rdkafka: */ 195 /** Begin internal error codes */ 196 RD_KAFKA_RESP_ERR__BEGIN = -200, 197 /** Received message is incorrect */ 198 RD_KAFKA_RESP_ERR__BAD_MSG = -199, 199 /** Bad/unknown compression */ 200 RD_KAFKA_RESP_ERR__BAD_COMPRESSION = -198, 201 /** Broker is going away */ 202 RD_KAFKA_RESP_ERR__DESTROY = -197, 203 /** Generic failure */ 204 RD_KAFKA_RESP_ERR__FAIL = -196, 205 /** Broker transport failure */ 206 RD_KAFKA_RESP_ERR__TRANSPORT = -195, 207 /** Critical system resource */ 208 RD_KAFKA_RESP_ERR__CRIT_SYS_RESOURCE = -194, 209 /** Failed to resolve broker */ 210 RD_KAFKA_RESP_ERR__RESOLVE = -193, 211 /** Produced message timed out*/ 212 RD_KAFKA_RESP_ERR__MSG_TIMED_OUT = -192, 213 /** Reached the end of the topic+partition queue on 214 * the broker. Not really an error. */ 215 RD_KAFKA_RESP_ERR__PARTITION_EOF = -191, 216 /** Permanent: Partition does not exist in cluster. */ 217 RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION = -190, 218 /** File or filesystem error */ 219 RD_KAFKA_RESP_ERR__FS = -189, 220 /** Permanent: Topic does not exist in cluster. */ 221 RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC = -188, 222 /** All broker connections are down. */ 223 RD_KAFKA_RESP_ERR__ALL_BROKERS_DOWN = -187, 224 /** Invalid argument, or invalid configuration */ 225 RD_KAFKA_RESP_ERR__INVALID_ARG = -186, 226 /** Operation timed out */ 227 RD_KAFKA_RESP_ERR__TIMED_OUT = -185, 228 /** Queue is full */ 229 RD_KAFKA_RESP_ERR__QUEUE_FULL = -184, 230 /** ISR count < required.acks */ 231 RD_KAFKA_RESP_ERR__ISR_INSUFF = -183, 232 /** Broker node update */ 233 RD_KAFKA_RESP_ERR__NODE_UPDATE = -182, 234 /** SSL error */ 235 RD_KAFKA_RESP_ERR__SSL = -181, 236 /** Waiting for coordinator to become available. */ 237 RD_KAFKA_RESP_ERR__WAIT_COORD = -180, 238 /** Unknown client group */ 239 RD_KAFKA_RESP_ERR__UNKNOWN_GROUP = -179, 240 /** Operation in progress */ 241 RD_KAFKA_RESP_ERR__IN_PROGRESS = -178, 242 /** Previous operation in progress, wait for it to finish. */ 243 RD_KAFKA_RESP_ERR__PREV_IN_PROGRESS = -177, 244 /** This operation would interfere with an existing subscription */ 245 RD_KAFKA_RESP_ERR__EXISTING_SUBSCRIPTION = -176, 246 /** Assigned partitions (rebalance_cb) */ 247 RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS = -175, 248 /** Revoked partitions (rebalance_cb) */ 249 RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS = -174, 250 /** Conflicting use */ 251 RD_KAFKA_RESP_ERR__CONFLICT = -173, 252 /** Wrong state */ 253 RD_KAFKA_RESP_ERR__STATE = -172, 254 /** Unknown protocol */ 255 RD_KAFKA_RESP_ERR__UNKNOWN_PROTOCOL = -171, 256 /** Not implemented */ 257 RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED = -170, 258 /** Authentication failure*/ 259 RD_KAFKA_RESP_ERR__AUTHENTICATION = -169, 260 /** No stored offset */ 261 RD_KAFKA_RESP_ERR__NO_OFFSET = -168, 262 /** Outdated */ 263 RD_KAFKA_RESP_ERR__OUTDATED = -167, 264 /** Timed out in queue */ 265 RD_KAFKA_RESP_ERR__TIMED_OUT_QUEUE = -166, 266 267 /** End internal error codes */ 268 RD_KAFKA_RESP_ERR__END = -100, 269 270 /* Kafka broker errors: */ 271 /** Unknown broker error */ 272 RD_KAFKA_RESP_ERR_UNKNOWN = -1, 273 /** Success */ 274 RD_KAFKA_RESP_ERR_NO_ERROR = 0, 275 /** Offset out of range */ 276 RD_KAFKA_RESP_ERR_OFFSET_OUT_OF_RANGE = 1, 277 /** Invalid message */ 278 RD_KAFKA_RESP_ERR_INVALID_MSG = 2, 279 /** Unknown topic or partition */ 280 RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART = 3, 281 /** Invalid message size */ 282 RD_KAFKA_RESP_ERR_INVALID_MSG_SIZE = 4, 283 /** Leader not available */ 284 RD_KAFKA_RESP_ERR_LEADER_NOT_AVAILABLE = 5, 285 /** Not leader for partition */ 286 RD_KAFKA_RESP_ERR_NOT_LEADER_FOR_PARTITION = 6, 287 /** Request timed out */ 288 RD_KAFKA_RESP_ERR_REQUEST_TIMED_OUT = 7, 289 /** Broker not available */ 290 RD_KAFKA_RESP_ERR_BROKER_NOT_AVAILABLE = 8, 291 /** Replica not available */ 292 RD_KAFKA_RESP_ERR_REPLICA_NOT_AVAILABLE = 9, 293 /** Message size too large */ 294 RD_KAFKA_RESP_ERR_MSG_SIZE_TOO_LARGE = 10, 295 /** StaleControllerEpochCode */ 296 RD_KAFKA_RESP_ERR_STALE_CTRL_EPOCH = 11, 297 /** Offset metadata string too large */ 298 RD_KAFKA_RESP_ERR_OFFSET_METADATA_TOO_LARGE = 12, 299 /** Broker disconnected before response received */ 300 RD_KAFKA_RESP_ERR_NETWORK_EXCEPTION = 13, 301 /** Group coordinator load in progress */ 302 RD_KAFKA_RESP_ERR_GROUP_LOAD_IN_PROGRESS = 14, 303 /** Group coordinator not available */ 304 RD_KAFKA_RESP_ERR_GROUP_COORDINATOR_NOT_AVAILABLE = 15, 305 /** Not coordinator for group */ 306 RD_KAFKA_RESP_ERR_NOT_COORDINATOR_FOR_GROUP = 16, 307 /** Invalid topic */ 308 RD_KAFKA_RESP_ERR_TOPIC_EXCEPTION = 17, 309 /** Message batch larger than configured server segment size */ 310 RD_KAFKA_RESP_ERR_RECORD_LIST_TOO_LARGE = 18, 311 /** Not enough in-sync replicas */ 312 RD_KAFKA_RESP_ERR_NOT_ENOUGH_REPLICAS = 19, 313 /** Message(s) written to insufficient number of in-sync replicas */ 314 RD_KAFKA_RESP_ERR_NOT_ENOUGH_REPLICAS_AFTER_APPEND = 20, 315 /** Invalid required acks value */ 316 RD_KAFKA_RESP_ERR_INVALID_REQUIRED_ACKS = 21, 317 /** Specified group generation id is not valid */ 318 RD_KAFKA_RESP_ERR_ILLEGAL_GENERATION = 22, 319 /** Inconsistent group protocol */ 320 RD_KAFKA_RESP_ERR_INCONSISTENT_GROUP_PROTOCOL = 23, 321 /** Invalid group.id */ 322 RD_KAFKA_RESP_ERR_INVALID_GROUP_ID = 24, 323 /** Unknown member */ 324 RD_KAFKA_RESP_ERR_UNKNOWN_MEMBER_ID = 25, 325 /** Invalid session timeout */ 326 RD_KAFKA_RESP_ERR_INVALID_SESSION_TIMEOUT = 26, 327 /** Group rebalance in progress */ 328 RD_KAFKA_RESP_ERR_REBALANCE_IN_PROGRESS = 27, 329 /** Commit offset data size is not valid */ 330 RD_KAFKA_RESP_ERR_INVALID_COMMIT_OFFSET_SIZE = 28, 331 /** Topic authorization failed */ 332 RD_KAFKA_RESP_ERR_TOPIC_AUTHORIZATION_FAILED = 29, 333 /** Group authorization failed */ 334 RD_KAFKA_RESP_ERR_GROUP_AUTHORIZATION_FAILED = 30, 335 /** Cluster authorization failed */ 336 RD_KAFKA_RESP_ERR_CLUSTER_AUTHORIZATION_FAILED = 31, 337 /** Invalid timestamp */ 338 RD_KAFKA_RESP_ERR_INVALID_TIMESTAMP = 32, 339 /** Unsupported SASL mechanism */ 340 RD_KAFKA_RESP_ERR_UNSUPPORTED_SASL_MECHANISM = 33, 341 /** Illegal SASL state */ 342 RD_KAFKA_RESP_ERR_ILLEGAL_SASL_STATE = 34, 343 /** Unuspported version */ 344 RD_KAFKA_RESP_ERR_UNSUPPORTED_VERSION = 35, 345 346 RD_KAFKA_RESP_ERR_END_ALL, 347 } 348 349 350 /** 351 * @brief Error code value, name and description. 352 * Typically for use with language bindings to automatically expose 353 * the full set of librdkafka error codes. 354 */ 355 struct rd_kafka_err_desc { 356 rd_kafka_resp_err_t code;/**< Error code */ 357 const(char) *name; /**< Error name, same as code enum sans prefix */ 358 const(char) *desc; /**< Human readable error description. */ 359 }; 360 361 362 /** 363 * @brief Returns the full list of error codes. 364 */ 365 366 void rd_kafka_get_err_descs (const rd_kafka_err_desc **errdescs,size_t *cntp); 367 368 369 370 371 /** 372 * @brief Returns a human readable representation of a kafka error. 373 * 374 * @param err Error code to translate 375 */ 376 377 const(char) *rd_kafka_err2str (rd_kafka_resp_err_t err); 378 379 380 381 /** 382 * @brief Returns the error code name (enum name). 383 * 384 * @param err Error code to translate 385 */ 386 387 const(char) *rd_kafka_err2name (rd_kafka_resp_err_t err); 388 389 390 /** 391 * @brief Returns the last error code generated by a legacy API call 392 * in the current thread. 393 * 394 * The legacy APIs are the ones using errno to propagate error value, namely: 395 * - rd_kafka_topic_new() 396 * - rd_kafka_consume_start() 397 * - rd_kafka_consume_stop() 398 * - rd_kafka_consume() 399 * - rd_kafka_consume_batch() 400 * - rd_kafka_consume_callback() 401 * - rd_kafka_consume_queue() 402 * - rd_kafka_produce() 403 * 404 * The main use for this function is to avoid converting system \p errno 405 * values to rd_kafka_resp_err_t codes for legacy APIs. 406 * 407 * @remark The last error is stored per-thread, if multiple rd_kafka_t handles 408 * are used in the same application thread the developer needs to 409 * make sure rd_kafka_last_error() is called immediately after 410 * a failed API call. 411 */ 412 413 rd_kafka_resp_err_t rd_kafka_last_error (); 414 415 416 /** 417 * @brief Converts the system errno value \p errnox to a rd_kafka_resp_err_t 418 * error code upon failure from the following functions: 419 * - rd_kafka_topic_new() 420 * - rd_kafka_consume_start() 421 * - rd_kafka_consume_stop() 422 * - rd_kafka_consume() 423 * - rd_kafka_consume_batch() 424 * - rd_kafka_consume_callback() 425 * - rd_kafka_consume_queue() 426 * - rd_kafka_produce() 427 * 428 * @param errnox System errno value to convert 429 * 430 * @returns Appropriate error code for \p errnox 431 * 432 * @remark A better alternative is to call rd_kafka_last_error() immediately 433 * after any of the above functions return -1 or NULL. 434 * 435 * @sa rd_kafka_last_error() 436 */ 437 438 rd_kafka_resp_err_t rd_kafka_errno2err(int errnox); 439 440 441 /** 442 * @brief Returns the thread-local system errno 443 * 444 * On most platforms this is the same as \p errno but in case of different 445 * runtimes between library and application (e.g., Windows static DLLs) 446 * this provides a means for expsing the errno librdkafka uses. 447 * 448 * @remark The value is local to the current calling thread. 449 */ 450 451 int rd_kafka_errno (); 452 453 454 455 /** 456 * @brief Topic+Partition place holder 457 * 458 * Generic place holder for a Topic+Partition and its related information 459 * used for multiple purposes: 460 * - consumer offset (see rd_kafka_commit(), et.al.) 461 * - group rebalancing callback (rd_kafka_conf_set_rebalance_cb()) 462 * - offset commit result callback (rd_kafka_conf_set_offset_commit_cb()) 463 */ 464 465 /** 466 * @brief Generic place holder for a specific Topic+Partition. 467 * 468 * @sa rd_kafka_topic_partition_list_new() 469 */ 470 struct rd_kafka_topic_partition_s { 471 char *topic; /**< Topic name */ 472 int32_t partition; /**< Partition */ 473 int64_t offset; /**< Offset */ 474 void *metadata; /**< Metadata */ 475 size_t metadata_size; /**< Metadata size */ 476 void *opaque; /**< Application opaque */ 477 rd_kafka_resp_err_t err; /**< Error code, depending on use. */ 478 void *_private; /**< INTERNAL USE ONLY, 479 * INITIALIZE TO ZERO, DO NOT TOUCH */ 480 } ; 481 482 alias rd_kafka_topic_partition_t = rd_kafka_topic_partition_s; 483 484 /** 485 * @brief Destroy a rd_kafka_topic_partition_t. 486 * @remark This must not be called for elements in a topic partition list. 487 */ 488 void rd_kafka_topic_partition_destroy (rd_kafka_topic_partition_t *rktpar); 489 490 491 /** 492 * @brief A growable list of Topic+Partitions. 493 * 494 */ 495 struct rd_kafka_topic_partition_list_s { 496 int cnt; /**< Current number of elements */ 497 int size; /**< Current allocated size */ 498 rd_kafka_topic_partition_t *elems; /**< Element array[] */ 499 } ; 500 alias rd_kafka_topic_partition_list_t = rd_kafka_topic_partition_list_s; 501 502 /** 503 * @brief Create a new list/vector Topic+Partition container. 504 * 505 * @param size Initial allocated size used when the expected number of 506 * elements is known or can be estimated. 507 * Avoids reallocation and possibly relocation of the 508 * elems array. 509 * 510 * @returns A newly allocated Topic+Partition list. 511 * 512 * @remark Use rd_kafka_topic_partition_list_destroy() to free all resources 513 * in use by a list and the list itself. 514 * @sa rd_kafka_topic_partition_list_add() 515 */ 516 517 rd_kafka_topic_partition_list_t *rd_kafka_topic_partition_list_new (int size); 518 519 520 /** 521 * @brief Free all resources used by the list and the list itself. 522 */ 523 524 void rd_kafka_topic_partition_list_destroy (rd_kafka_topic_partition_list_t *rkparlist); 525 526 /** 527 * @brief Add topic+partition to list 528 * 529 * @param rktparlist List to extend 530 * @param topic Topic name (copied) 531 * @param partition Partition id 532 * 533 * @returns The object which can be used to fill in additionals fields. 534 */ 535 536 rd_kafka_topic_partition_t * rd_kafka_topic_partition_list_add (rd_kafka_topic_partition_list_t *rktparlist, 537 const(char) *topic, int32_t partition); 538 539 540 /** 541 * @brief Add range of partitions from \p start to \p stop inclusive. 542 * 543 * @param rktparlist List to extend 544 * @param topic Topic name (copied) 545 * @param start Start partition of range 546 * @param stop Last partition of range (inclusive) 547 */ 548 549 void 550 rd_kafka_topic_partition_list_add_range (rd_kafka_topic_partition_list_t 551 *rktparlist, 552 const(char) *topic, 553 int32_t start, int32_t stop); 554 555 /** 556 * @brief Delete partition from list. 557 * 558 * @param rktparlist List to modify 559 * @param topic Topic name to match 560 * @param partition Partition to match 561 * 562 * @returns 1 if partition was found (and removed), else 0. 563 * 564 * @remark Any held indices to elems[] are unusable after this call returns 1. 565 */ 566 int 567 rd_kafka_topic_partition_list_del (rd_kafka_topic_partition_list_t *rktparlist, 568 const (char) *topic, int32_t partition); 569 570 571 572 /** 573 * @brief Delete partition from list by elems[] index. 574 * 575 * @returns 1 if partition was found (and removed), else 0. 576 * 577 * @sa rd_kafka_topic_partition_list_del() 578 */ 579 int 580 rd_kafka_topic_partition_list_del_by_idx ( 581 rd_kafka_topic_partition_list_t *rktparlist, 582 int idx); 583 /** 584 * @brief Make a copy of an existing list. 585 * 586 * @param src The existing list to copy. 587 * 588 * @returns A new list fully populated to be identical to \p src 589 */ 590 591 rd_kafka_topic_partition_list_t * 592 rd_kafka_topic_partition_list_copy (const rd_kafka_topic_partition_list_t *src); 593 594 595 596 597 /** 598 * @brief Set offset to \p offset for \p topic and \p partition 599 * 600 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or 601 * RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION if \p partition was not found 602 * in the list. 603 */ 604 605 rd_kafka_resp_err_t rd_kafka_topic_partition_list_set_offset ( 606 rd_kafka_topic_partition_list_t *rktparlist, 607 const(char) *topic, int32_t partition, int64_t offset); 608 609 610 611 /** 612 * @brief Find element by \p topic and \p partition. 613 * 614 * @returns a pointer to the first matching element, or NULL if not found. 615 */ 616 617 rd_kafka_topic_partition_t * 618 rd_kafka_topic_partition_list_find (rd_kafka_topic_partition_list_t *rktparlist, 619 const(char) *topic, int32_t partition); 620 621 /**@}*/ 622 623 624 625 /** 626 * @name Kafka messages 627 * @{ 628 * 629 */ 630 631 632 633 // FIXME: This doesn't show up in docs for some reason 634 // "Compound rd_kafka_message_t is not documented." 635 636 /** 637 * @brief A Kafka message as returned by the \c rd_kafka_consume*() family 638 * of functions as well as provided to the Producer \c dr_msg_cb(). 639 * 640 * For the consumer this object has two purposes: 641 * - provide the application with a consumed message. (\c err == 0) 642 * - report per-topic+partition consumer errors (\c err != 0) 643 * 644 * The application must check \c err to decide what action to take. 645 * 646 * When the application is finished with a message it must call 647 * rd_kafka_message_destroy() unless otherwise noted. 648 */ 649 struct rd_kafka_message_s { 650 rd_kafka_resp_err_t err; /**< Non-zero for error signaling. */ 651 rd_kafka_topic_t *rkt; /**< Topic */ 652 int32_t partition; /**< Partition */ 653 void *payload; /**< Producer: original message payload. 654 * Consumer: Depends on the value of \c err : 655 * - \c err==0: Message payload. 656 * - \c err!=0: Error string */ 657 size_t len; /**< Depends on the value of \c err : 658 * - \c err==0: Message payload length 659 * - \c err!=0: Error string length */ 660 void *key; /**< Depends on the value of \c err : 661 * - \c err==0: Optional message key */ 662 size_t key_len; /**< Depends on the value of \c err : 663 * - \c err==0: Optional message key length*/ 664 int64_t offset; /**< Consume: 665 * - Message offset (or offset for error 666 * if \c err!=0 if applicable). 667 * - dr_msg_cb: 668 * Message offset assigned by broker. 669 * If \c produce.offset.report is set then 670 * each message will have this field set, 671 * otherwise only the last message in 672 * each produced internal batch will 673 * have this field set, otherwise 0. */ 674 void *_private; /**< Consume: 675 * - rdkafka private pointer: DO NOT MODIFY 676 * - dr_msg_cb: 677 * msg_opaque from produce() call */ 678 } ; 679 680 alias rd_kafka_message_t = rd_kafka_message_s; 681 682 683 /** 684 * @brief Frees resources for \p rkmessage and hands ownership back to rdkafka. 685 */ 686 687 void rd_kafka_message_destroy(rd_kafka_message_t *rkmessage); 688 689 690 691 692 /** 693 * @brief Returns the error string for an errored rd_kafka_message_t or NULL if 694 * there was no error. 695 */ 696 const(char) * rd_kafka_message_errstr(const rd_kafka_message_t *rkmessage) { 697 if (!rkmessage.err) 698 return null; 699 700 if (rkmessage.payload) 701 return cast(const(char) *)(rkmessage.payload); 702 703 return rd_kafka_err2str(rkmessage.err); 704 } 705 706 707 /** 708 * @brief Returns the message timestamp for a consumed message. 709 * 710 * The timestamp is the number of milliseconds since the epoch (UTC). 711 * 712 * \p tstype is updated to indicate the type of timestamp. 713 * 714 * @returns message timestamp, or -1 if not available. 715 * 716 * @remark Message timestamps require broker version 0.10.0 or later. 717 */ 718 int64_t rd_kafka_message_timestamp (const rd_kafka_message_t *rkmessage, 719 rd_kafka_timestamp_type_t *tstype); 720 721 722 /**@}*/ 723 724 725 /** 726 * @name Configuration interface 727 * @{ 728 * 729 * @brief Main/global configuration property interface 730 * 731 */ 732 733 /** 734 * @enum rd_kafka_conf_res_t 735 * @brief Configuration result type 736 */ 737 enum rd_kafka_conf_res_t { 738 RD_KAFKA_CONF_UNKNOWN = -2, /**< Unknown configuration name. */ 739 RD_KAFKA_CONF_INVALID = -1, /**< Invalid configuration value. */ 740 RD_KAFKA_CONF_OK = 0 /**< Configuration okay */ 741 } ; 742 743 744 /** 745 * @brief Create configuration object. 746 * 747 * When providing your own configuration to the \c rd_kafka_*_new_*() calls 748 * the rd_kafka_conf_t objects needs to be created with this function 749 * which will set up the defaults. 750 * I.e.: 751 * @code 752 * rd_kafka_conf_t *myconf; 753 * rd_kafka_conf_res_t res; 754 * 755 * myconf = rd_kafka_conf_new(); 756 * res = rd_kafka_conf_set(myconf, "socket.timeout.ms", "600", 757 * errstr, sizeof(errstr)); 758 * if (res != RD_KAFKA_CONF_OK) 759 * die("%s\n", errstr); 760 * 761 * rk = rd_kafka_new(..., myconf); 762 * @endcode 763 * 764 * Please see CONFIGURATION.md for the default settings or use 765 * rd_kafka_conf_properties_show() to provide the information at runtime. 766 * 767 * The properties are identical to the Apache Kafka configuration properties 768 * whenever possible. 769 * 770 * @returns A new rd_kafka_conf_t object with defaults set. 771 * 772 * @sa rd_kafka_conf_set(), rd_kafka_conf_destroy() 773 */ 774 775 rd_kafka_conf_t *rd_kafka_conf_new(); 776 777 778 /** 779 * @brief Destroys a conf object. 780 */ 781 782 void rd_kafka_conf_destroy(rd_kafka_conf_t *conf); 783 784 785 /** 786 * @brief Creates a copy/duplicate of configuration object \p conf 787 */ 788 789 rd_kafka_conf_t *rd_kafka_conf_dup(const rd_kafka_conf_t *conf); 790 791 792 /** 793 * @brief Sets a configuration property. 794 * 795 * \p must have been previously created with rd_kafka_conf_new(). 796 * 797 * Returns \c rd_kafka_conf_res_t to indicate success or failure. 798 * In case of failure \p errstr is updated to contain a human readable 799 * error string. 800 */ 801 802 rd_kafka_conf_res_t rd_kafka_conf_set(rd_kafka_conf_t *conf, 803 const(char) *name, 804 const(char) *value, 805 char *errstr, size_t errstr_size); 806 807 /** 808 * @brief Enable event sourcing. 809 * \p events is a bitmask of \c RD_KAFKA_EVENT_* of events to enable 810 * for consumption by `rd_kafka_queue_poll()`. 811 */ 812 void rd_kafka_conf_set_events(rd_kafka_conf_t *conf, int events); 813 814 /** 815 @deprecated See rd_kafka_conf_set_dr_msg_cb() 816 $(D deprecated) 817 */ 818 819 deprecated("See rd_kafka_conf_set_dr_msg_cb"){ 820 alias dr_cb_callback = extern(D) void function(rd_kafka_t *rk,void *payload, size_t len, rd_kafka_resp_err_t err,void *opaque, void *msg_opaque) nothrow @nogc; 821 void rd_kafka_conf_set_dr_cb(rd_kafka_conf_t *conf, dr_cb_callback dr_cb) ; 822 } 823 824 825 /** 826 * @brief \b Producer: Set delivery report callback in provided \p conf object. 827 * 828 * The delivery report callback will be called once for each message 829 * accepted by rd_kafka_produce() (et.al) with \p err set to indicate 830 * the result of the produce request. 831 * 832 * The callback is called when a message is succesfully produced or 833 * if librdkafka encountered a permanent failure, or the retry counter for 834 * temporary errors has been exhausted. 835 * 836 * An application must call rd_kafka_poll() at regular intervals to 837 * serve queued delivery report callbacks. 838 */ 839 alias dr_msg_cb_callback = extern(D) void function(rd_kafka_t *rk,const rd_kafka_message_t *rkmessage,void *opaque) nothrow @nogc; 840 void rd_kafka_conf_set_dr_msg_cb(rd_kafka_conf_t *conf,dr_msg_cb_callback dr_msg_cb); 841 842 843 /** 844 * @brief \b Consumer: Set consume callback for use with rd_kafka_consumer_poll() 845 * 846 */ 847 void rd_kafka_conf_set_consume_cb (rd_kafka_conf_t *conf, void function(rd_kafka_message_t *rkmessage,void *opaque) nothrow @nogc consume_cb); 848 849 /** 850 * @brief \b Consumer: Set rebalance callback for use with 851 * coordinated consumer group balancing. 852 * 853 * The \p err field is set to either RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS 854 * or RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS and 'partitions' 855 * contains the full partition set that was either assigned or revoked. 856 * 857 * Registering a \p rebalance_cb turns off librdkafka's automatic 858 * partition assignment/revocation and instead delegates that responsibility 859 * to the application's \p rebalance_cb. 860 * 861 * The rebalance callback is responsible for updating librdkafka's 862 * assignment set based on the two events: RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS 863 * and RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS but should also be able to handle 864 * arbitrary rebalancing failures where \p err is neither of those. 865 * @remark In this latter case (arbitrary error), the application must 866 * call rd_kafka_assign(rk, NULL) to synchronize state. 867 * 868 * Without a rebalance callback this is done automatically by librdkafka 869 * but registering a rebalance callback gives the application flexibility 870 * in performing other operations along with the assinging/revocation, 871 * such as fetching offsets from an alternate location (on assign) 872 * or manually committing offsets (on revoke). 873 * 874 * @remark The \p partitions list is destroyed by librdkafka on return 875 * return from the rebalance_cb and must not be freed or 876 * saved by the application. 877 * 878 * The following example shows the application's responsibilities: 879 * @code 880 * static void rebalance_cb (rd_kafka_t *rk, rd_kafka_resp_err_t err, 881 * rd_kafka_topic_partition_list_t *partitions, 882 * void *opaque) { 883 * 884 * switch (err) 885 * { 886 * case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS: 887 * // application may load offets from arbitrary external 888 * // storage here and update \p partitions 889 * 890 * rd_kafka_assign(rk, partitions); 891 * break; 892 * 893 * case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS: 894 * if (manual_commits) // Optional explicit manual commit 895 * rd_kafka_commit(rk, partitions, 0); // sync commit 896 * 897 * rd_kafka_assign(rk, NULL); 898 * break; 899 * 900 * default: 901 * handle_unlikely_error(err); 902 * rd_kafka_assign(rk, NULL); // sync state 903 * break; 904 * } 905 * } 906 * @endcode 907 */ 908 alias rebalance_cb_callback = extern(D) void function (rd_kafka_t *rk,rd_kafka_resp_err_t err, rd_kafka_topic_partition_list_t *partitions,void *opaque) nothrow @nogc; 909 void rd_kafka_conf_set_rebalance_cb (rd_kafka_conf_t *conf, rebalance_cb_callback rebalance_cb); 910 911 912 913 /** 914 * @brief \b Consumer: Set offset commit callback for use with consumer groups. 915 * 916 * The results of automatic or manual offset commits will be scheduled 917 * for this callback and is served by rd_kafka_consumer_poll(). 918 * 919 * If no partitions had valid offsets to commit this callback will be called 920 * with \p err == RD_KAFKA_RESP_ERR__NO_OFFSET which is not to be considered 921 * an error. 922 * 923 * The \p offsets list contains per-partition information: 924 * - \c offset: committed offset (attempted) 925 * - \c err: commit error 926 */ 927 alias offset_commit_cb_call_back = extern(D) void function(rd_kafka_t *rk,rd_kafka_resp_err_t err,rd_kafka_topic_partition_list_t *offsets,void *opaque); 928 void rd_kafka_conf_set_offset_commit_cb (rd_kafka_conf_t *conf,offset_commit_cb_call_back offset_commit_cb); 929 930 931 /** 932 * @brief Set error callback in provided conf object. 933 * 934 * The error callback is used by librdkafka to signal critical errors 935 * back to the application. 936 * 937 * If no \p error_cb is registered then the errors will be logged instead. 938 */ 939 alias error_cb_callback = extern(D) void function (rd_kafka_t *rk, int err,const(char) *reason,void *opaque) nothrow @nogc; 940 void rd_kafka_conf_set_error_cb(rd_kafka_conf_t *conf,error_cb_callback error_cb); 941 942 /** 943 * @brief Set throttle callback. 944 * 945 * The throttle callback is used to forward broker throttle times to the 946 * application for Produce and Fetch (consume) requests. 947 * 948 * Callbacks are triggered whenever a non-zero throttle time is returned by 949 * the broker, or when the throttle time drops back to zero. 950 * 951 * An application must call rd_kafka_poll() or rd_kafka_consumer_poll() at 952 * regular intervals to serve queued callbacks. 953 * 954 * @remark Requires broker version 0.9.0 or later. 955 */ 956 alias throttle_cb_callback = extern(D) void function(rd_kafka_t *rk,const(char) *broker_name,int32_t broker_id,int throttle_time_ms,void *opaque) nothrow @nogc; 957 void rd_kafka_conf_set_throttle_cb (rd_kafka_conf_t *conf,throttle_cb_callback throttle_cb); 958 959 960 /** 961 * @brief Set logger callback. 962 * 963 * The default is to print to stderr, but a syslog logger is also available, 964 * see rd_kafka_log_print and rd_kafka_log_syslog for the builtin alternatives. 965 * Alternatively the application may provide its own logger callback. 966 * Or pass \p func as NULL to disable logging. 967 * 968 * This is the configuration alternative to the deprecated rd_kafka_set_logger() 969 */ 970 971 alias log_cb_callback = extern(D) void function (const rd_kafka_t *rk, int level,const(char) *fac, const(char) *buf) nothrow @nogc; 972 void rd_kafka_conf_set_log_cb(rd_kafka_conf_t *conf, log_cb_callback log_cb); 973 974 975 /** 976 * @brief Set statistics callback in provided conf object. 977 * 978 * The statistics callback is triggered from rd_kafka_poll() every 979 * \c statistics.interval.ms (needs to be configured separately). 980 * Function arguments: 981 * - \p rk - Kafka handle 982 * - \p json - String containing the statistics data in JSON format 983 * - \p json_len - Length of \p json string. 984 * - \p opaque - Application-provided opaque. 985 * 986 * If the application wishes to hold on to the \p json pointer and free 987 * it at a later time it must return 1 from the \p stats_cb. 988 * If the application returns 0 from the \p stats_cb then librdkafka 989 * will immediately free the \p json pointer. 990 */ 991 alias stats_cb_callback = extern(D) int function (rd_kafka_t *rk, 992 char *json, 993 size_t json_len, 994 void *opaque) nothrow @nogc; 995 void rd_kafka_conf_set_stats_cb(rd_kafka_conf_t *conf,stats_cb_callback stats_cb); 996 997 998 999 /** 1000 * @brief Set socket callback. 1001 * 1002 * The socket callback is responsible for opening a socket 1003 * according to the supplied \p domain, \p type and \p protocol. 1004 * The socket shall be created with \c CLOEXEC set in a racefree fashion, if 1005 * possible. 1006 * 1007 * Default: 1008 * - on linux: racefree CLOEXEC 1009 * - others : non-racefree CLOEXEC 1010 */ 1011 alias socket_cb_callback = extern(D) int function(int domain, int type,int protocol,void *opaque) nothrow @nogc; 1012 void rd_kafka_conf_set_socket_cb(rd_kafka_conf_t *conf, socket_cb_callback socket_cb); 1013 1014 1015 version(Windows) 1016 { 1017 } 1018 else 1019 { 1020 /** 1021 * @brief Set open callback. 1022 * 1023 * The open callback is responsible for opening the file specified by 1024 * pathname, flags and mode. 1025 * The file shall be opened with \c CLOEXEC set in a racefree fashion, if 1026 * possible. 1027 * 1028 * Default: 1029 * - on linux: racefree CLOEXEC 1030 * - others : non-racefree CLOEXEC 1031 */ 1032 alias open_cb_callback = extern(D) int function (const(char) *pathname,int flags, mode_t mode,void *opaque) nothrow @nogc; 1033 void rd_kafka_conf_set_open_cb (rd_kafka_conf_t *conf,open_cb_callback open_cb); 1034 } 1035 1036 /** 1037 * @brief Sets the application's opaque pointer that will be passed to callbacks 1038 */ 1039 1040 void rd_kafka_conf_set_opaque(rd_kafka_conf_t *conf, void *opaque); 1041 1042 /** 1043 * @brief Retrieves the opaque pointer previously set with rd_kafka_conf_set_opaque() 1044 */ 1045 1046 void *rd_kafka_opaque(const rd_kafka_t *rk); 1047 1048 1049 1050 /** 1051 * Sets the default topic configuration to use for automatically 1052 * subscribed topics (e.g., through pattern-matched topics). 1053 * The topic config object is not usable after this call. 1054 */ 1055 1056 void rd_kafka_conf_set_default_topic_conf (rd_kafka_conf_t *conf, rd_kafka_topic_conf_t *tconf); 1057 1058 1059 1060 /** 1061 * @brief Retrieve configuration value for property \p name. 1062 * 1063 * If \p dest is non-NULL the value will be written to \p dest with at 1064 * most \p dest_size. 1065 * 1066 * \p *dest_size is updated to the full length of the value, thus if 1067 * \p *dest_size initially is smaller than the full length the application 1068 * may reallocate \p dest to fit the returned \p *dest_size and try again. 1069 * 1070 * If \p dest is NULL only the full length of the value is returned. 1071 * 1072 * Returns \p RD_KAFKA_CONF_OK if the property name matched, else 1073 * \p RD_KAFKA_CONF_UNKNOWN. 1074 */ 1075 1076 rd_kafka_conf_res_t rd_kafka_conf_get (const rd_kafka_conf_t *conf, const(char) *name, char *dest, size_t *dest_size); 1077 1078 1079 /** 1080 * @brief Retrieve topic configuration value for property \p name. 1081 * 1082 * @sa rd_kafka_conf_get() 1083 */ 1084 1085 rd_kafka_conf_res_t rd_kafka_topic_conf_get (const rd_kafka_topic_conf_t *conf, const(char) *name, char *dest, size_t *dest_size); 1086 1087 1088 /** 1089 * @brief Dump the configuration properties and values of \p conf to an array 1090 * with \"key\", \"value\" pairs. 1091 * 1092 * The number of entries in the array is returned in \p *cntp. 1093 * 1094 * The dump must be freed with `rd_kafka_conf_dump_free()`. 1095 */ 1096 1097 const(char) **rd_kafka_conf_dump(rd_kafka_conf_t *conf, size_t *cntp); 1098 1099 1100 /** 1101 * @brief Dump the topic configuration properties and values of \p conf 1102 * to an array with \"key\", \"value\" pairs. 1103 * 1104 * The number of entries in the array is returned in \p *cntp. 1105 * 1106 * The dump must be freed with `rd_kafka_conf_dump_free()`. 1107 */ 1108 1109 const(char) **rd_kafka_topic_conf_dump(rd_kafka_topic_conf_t *conf, size_t *cntp); 1110 1111 /** 1112 * @brief Frees a configuration dump returned from `rd_kafka_conf_dump()` or 1113 * `rd_kafka_topic_conf_dump(). 1114 */ 1115 1116 void rd_kafka_conf_dump_free(const(char) **arr, size_t cnt); 1117 1118 /** 1119 * @brief Prints a table to \p fp of all supported configuration properties, 1120 * their default values as well as a description. 1121 */ 1122 1123 void rd_kafka_conf_properties_show(FILE *fp); 1124 1125 /**@}*/ 1126 1127 1128 /** 1129 * @name Topic configuration 1130 * @{ 1131 * 1132 * @brief Topic configuration property interface 1133 * 1134 */ 1135 1136 1137 /** 1138 * @brief Create topic configuration object 1139 * 1140 * @sa Same semantics as for rd_kafka_conf_new(). 1141 */ 1142 1143 rd_kafka_topic_conf_t *rd_kafka_topic_conf_new(); 1144 1145 1146 /** 1147 * @brief Creates a copy/duplicate of topic configuration object \p conf. 1148 */ 1149 1150 rd_kafka_topic_conf_t *rd_kafka_topic_conf_dup(const rd_kafka_topic_conf_t * conf); 1151 1152 1153 /** 1154 * @brief Destroys a topic conf object. 1155 */ 1156 1157 void rd_kafka_topic_conf_destroy(rd_kafka_topic_conf_t *topic_conf); 1158 1159 1160 /** 1161 * @brief Sets a single rd_kafka_topic_conf_t value by property name. 1162 * 1163 * \p topic_conf should have been previously set up 1164 * with `rd_kafka_topic_conf_new()`. 1165 * 1166 * @returns rd_kafka_conf_res_t to indicate success or failure. 1167 */ 1168 1169 rd_kafka_conf_res_t rd_kafka_topic_conf_set(rd_kafka_topic_conf_t *conf, const(char) *name,const(char) *value, char *errstr, size_t errstr_size); 1170 1171 /** 1172 * @brief Sets the application's opaque pointer that will be passed to all topic 1173 * callbacks as the \c rkt_opaque argument. 1174 */ 1175 1176 void rd_kafka_topic_conf_set_opaque(rd_kafka_topic_conf_t *conf, void *opaque); 1177 1178 1179 /** 1180 * @brief \b Producer: Set partitioner callback in provided topic conf object. 1181 * 1182 * The partitioner may be called in any thread at any time, 1183 * it may be called multiple times for the same message/key. 1184 * 1185 * Partitioner function constraints: 1186 * - MUST NOT call any rd_kafka_*() functions except: 1187 * rd_kafka_topic_partition_available() 1188 * - MUST NOT block or execute for prolonged periods of time. 1189 * - MUST return a value between 0 and partition_cnt-1, or the 1190 * special \c RD_KAFKA_PARTITION_UA value if partitioning 1191 * could not be performed. 1192 */ 1193 alias partitioner_callback = extern(D) int32_t function(const rd_kafka_topic_t *rkt,const (void) *keydata,size_t keylen,int32_t partition_cnt,void *rkt_opaque,void *msg_opaque) nothrow @nogc; 1194 void rd_kafka_topic_conf_set_partitioner_cb (rd_kafka_topic_conf_t *topic_conf, partitioner_callback partitioner ); 1195 1196 /** 1197 * @brief Check if partition is available (has a leader broker). 1198 * 1199 * @returns 1 if the partition is available, else 0. 1200 * 1201 * @warning This function must only be called from inside a partitioner function 1202 */ 1203 1204 int rd_kafka_topic_partition_available(const rd_kafka_topic_t *rkt, int32_t partition); 1205 1206 1207 /******************************************************************* 1208 * * 1209 * Partitioners provided by rdkafka * 1210 * * 1211 *******************************************************************/ 1212 1213 /** 1214 * @brief Random partitioner. 1215 * 1216 * Will try not to return unavailable partitions. 1217 * 1218 * @returns a random partition between 0 and \p partition_cnt - 1. 1219 * 1220 */ 1221 1222 int32_t rd_kafka_msg_partitioner_random(const rd_kafka_topic_t *rkt, const (void) *key, size_t keylen, int32_t partition_cnt,void *opaque, void *msg_opaque); 1223 1224 /** 1225 * @brief Consistent partitioner. 1226 * 1227 * Uses consistent hashing to map identical keys onto identical partitions. 1228 * 1229 * @returns a \"random\" partition between 0 and \p partition_cnt - 1 based on 1230 * the CRC value of the key 1231 */ 1232 1233 int32_t rd_kafka_msg_partitioner_consistent (const rd_kafka_topic_t *rkt, const (void) *key, size_t keylen, int32_t partition_cnt, void *opaque, void *msg_opaque); 1234 1235 /** 1236 * @brief Consistent-Random partitioner. 1237 * 1238 * This is the default partitioner. 1239 * Uses consistent hashing to map identical keys onto identical partitions, and 1240 * messages without keys will be assigned via the random partitioner. 1241 * 1242 * @returns a \"random\" partition between 0 and \p partition_cnt - 1 based on 1243 * the CRC value of the key (if provided) 1244 */ 1245 1246 int32_t rd_kafka_msg_partitioner_consistent_random (const rd_kafka_topic_t *rkt, const (void) *key, size_t keylen, int32_t partition_cnt, void *opaque, void *msg_opaque); 1247 1248 1249 /**@}*/ 1250 1251 1252 1253 /** 1254 * @name Main Kafka and Topic object handles 1255 * @{ 1256 * 1257 * 1258 */ 1259 1260 1261 1262 1263 /** 1264 * @brief Creates a new Kafka handle and starts its operation according to the 1265 * specified \p type (\p RD_KAFKA_CONSUMER or \p RD_KAFKA_PRODUCER). 1266 * 1267 * \p conf is an optional struct created with `rd_kafka_conf_new()` that will 1268 * be used instead of the default configuration. 1269 * The \p conf object is freed by this function on success and must not be used 1270 * or destroyed by the application sub-sequently. 1271 * See `rd_kafka_conf_set()` et.al for more information. 1272 * 1273 * \p errstr must be a pointer to memory of at least size \p errstr_size where 1274 * `rd_kafka_new()` may write a human readable error message in case the 1275 * creation of a new handle fails. In which case the function returns NULL. 1276 * 1277 * @remark \b RD_KAFKA_CONSUMER: When a new \p RD_KAFKA_CONSUMER 1278 * rd_kafka_t handle is created it may either operate in the 1279 * legacy simple consumer mode using the rd_kafka_consume_start() 1280 * interface, or the High-level KafkaConsumer API. 1281 * @remark An application must only use one of these groups of APIs on a given 1282 * rd_kafka_t RD_KAFKA_CONSUMER handle. 1283 1284 * 1285 * @returns The Kafka handle on success or NULL on error (see \p errstr) 1286 * 1287 * @sa To destroy the Kafka handle, use rd_kafka_destroy(). 1288 */ 1289 1290 rd_kafka_t *rd_kafka_new(rd_kafka_type_t type, rd_kafka_conf_t *conf, char *errstr, size_t errstr_size); 1291 1292 1293 /** 1294 * @brief Destroy Kafka handle. 1295 * 1296 * @remark This is a blocking operation. 1297 */ 1298 1299 void rd_kafka_destroy(rd_kafka_t *rk); 1300 1301 1302 1303 /** 1304 * @brief Returns Kafka handle name. 1305 */ 1306 1307 const(char) *rd_kafka_name(const rd_kafka_t *rk); 1308 1309 1310 /** 1311 * @brief Returns this client's broker-assigned group member id 1312 * 1313 * @remark This currently requires the high-level KafkaConsumer 1314 * 1315 * @returns An allocated string containing the current broker-assigned group 1316 * member id, or NULL if not available. 1317 * The application must free the string with \p free() or 1318 * rd_kafka_mem_free() 1319 */ 1320 1321 char *rd_kafka_memberid (const rd_kafka_t *rk); 1322 1323 1324 /** 1325 * @brief Creates a new topic handle for topic named \p topic. 1326 * 1327 * \p conf is an optional configuration for the topic created with 1328 * `rd_kafka_topic_conf_new()` that will be used instead of the default 1329 * topic configuration. 1330 * The \p conf object is freed by this function and must not be used or 1331 * destroyed by the application sub-sequently. 1332 * See `rd_kafka_topic_conf_set()` et.al for more information. 1333 * 1334 * Topic handles are refcounted internally and calling rd_kafka_topic_new() 1335 * again with the same topic name will return the previous topic handle 1336 * without updating the original handle's configuration. 1337 * Applications must eventually call rd_kafka_topic_destroy() for each 1338 * succesfull call to rd_kafka_topic_new() to clear up resources. 1339 * 1340 * @returns the new topic handle or NULL on error (use rd_kafka_errno2err() 1341 * to convert system \p errno to an rd_kafka_resp_err_t error code. 1342 * 1343 * @sa rd_kafka_topic_destroy() 1344 */ 1345 1346 rd_kafka_topic_t *rd_kafka_topic_new(rd_kafka_t *rk, const(char) *topic, rd_kafka_topic_conf_t *conf); 1347 1348 1349 1350 /** 1351 * @brief Destroy topic handle previously created with `rd_kafka_topic_new()`. 1352 * @remark MUST NOT be used for internally created topics (topic_new0()) 1353 */ 1354 1355 void rd_kafka_topic_destroy(rd_kafka_topic_t *rkt); 1356 1357 1358 /** 1359 * @brief Returns the topic name. 1360 */ 1361 1362 const(char) *rd_kafka_topic_name(const rd_kafka_topic_t *rkt); 1363 1364 1365 /** 1366 * @brief Get the \p rkt_opaque pointer that was set in the topic configuration. 1367 */ 1368 1369 void *rd_kafka_topic_opaque (const rd_kafka_topic_t *rkt); 1370 1371 1372 /** 1373 * @brief Unassigned partition. 1374 * 1375 * The unassigned partition is used by the producer API for messages 1376 * that should be partitioned using the configured or default partitioner. 1377 */ 1378 enum int RD_KAFKA_PARTITION_UA = -1; 1379 1380 1381 /** 1382 * @brief Polls the provided kafka handle for events. 1383 * 1384 * Events will cause application provided callbacks to be called. 1385 * 1386 * The \p timeout_ms argument specifies the maximum amount of time 1387 * (in milliseconds) that the call will block waiting for events. 1388 * For non-blocking calls, provide 0 as \p timeout_ms. 1389 * To wait indefinately for an event, provide -1. 1390 * 1391 * @remark An application should make sure to call poll() at regular 1392 * intervals to serve any queued callbacks waiting to be called. 1393 * 1394 * Events: 1395 * - delivery report callbacks (if dr_cb/dr_msg_cb is configured) [producer] 1396 * - error callbacks (rd_kafka_conf_set_error_cb()) [all] 1397 * - stats callbacks (rd_kafka_conf_set_stats_cb()) [all] 1398 * - throttle callbacks (rd_kafka_conf_set_throttle_cb()) [all] 1399 * 1400 * @returns the number of events served. 1401 */ 1402 1403 int rd_kafka_poll(rd_kafka_t *rk, int timeout_ms); 1404 1405 1406 /** 1407 * @brief Cancels the current callback dispatcher (rd_kafka_poll(), 1408 * rd_kafka_consume_callback(), etc). 1409 * 1410 * A callback may use this to force an immediate return to the calling 1411 * code (caller of e.g. rd_kafka_poll()) without processing any further 1412 * events. 1413 * 1414 * @remark This function MUST ONLY be called from within a librdkafka callback. 1415 */ 1416 1417 void rd_kafka_yield (rd_kafka_t *rk); 1418 1419 1420 1421 1422 /** 1423 * @brief Pause producing or consumption for the provided list of partitions. 1424 * 1425 * Success or error is returned per-partition \p err in the \p partitions list. 1426 * 1427 * @returns RD_KAFKA_RESP_ERR_NO_ERROR 1428 */ 1429 rd_kafka_resp_err_t rd_kafka_pause_partitions (rd_kafka_t *rk, rd_kafka_topic_partition_list_t *partitions); 1430 1431 1432 1433 /** 1434 * @brief Resume producing consumption for the provided list of partitions. 1435 * 1436 * Success or error is returned per-partition \p err in the \p partitions list. 1437 * 1438 * @returns RD_KAFKA_RESP_ERR_NO_ERROR 1439 */ 1440 rd_kafka_resp_err_t rd_kafka_resume_partitions (rd_kafka_t *rk, rd_kafka_topic_partition_list_t *partitions); 1441 1442 1443 1444 1445 /** 1446 * @brief Query broker for low (oldest/beginning) and high (newest/end) offsets 1447 * for partition. 1448 * 1449 * Offsets are returned in \p *low and \p *high respectively. 1450 * 1451 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or an error code on failure. 1452 */ 1453 rd_kafka_resp_err_t 1454 rd_kafka_query_watermark_offsets (rd_kafka_t *rk, 1455 const(char) *topic, int32_t partition, 1456 int64_t *low, int64_t *high, int timeout_ms); 1457 1458 1459 /** 1460 * @brief Get last known low (oldest/beginning) and high (newest/end) offsets 1461 * for partition. 1462 * 1463 * The low offset is updated periodically (if statistics.interval.ms is set) 1464 * while the high offset is updated on each fetched message set from the broker. 1465 * 1466 * If there is no cached offset (either low or high, or both) then 1467 * RD_KAFKA_OFFSET_INVALID will be returned for the respective offset. 1468 * 1469 * Offsets are returned in \p *low and \p *high respectively. 1470 * 1471 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or an error code on failure. 1472 * 1473 * @remark Shall only be used with an active consumer instance. 1474 */ 1475 rd_kafka_resp_err_t 1476 rd_kafka_get_watermark_offsets (rd_kafka_t *rk, 1477 const(char) *topic, int32_t partition, 1478 int64_t *low, int64_t *high); 1479 1480 1481 1482 /** 1483 * @brief Free pointer returned by librdkafka 1484 * 1485 * This is typically an abstraction for the free(3) call and makes sure 1486 * the application can use the same memory allocator as librdkafka for 1487 * freeing pointers returned by librdkafka. 1488 * 1489 * In standard setups it is usually not necessary to use this interface 1490 * rather than the free(3) functione. 1491 * 1492 * @remark rd_kafka_mem_free() must only be used for pointers returned by APIs 1493 * that explicitly mention using this function for freeing. 1494 */ 1495 1496 void rd_kafka_mem_free (rd_kafka_t *rk, void *ptr); 1497 1498 1499 /**@}*/ 1500 1501 1502 1503 1504 1505 /** 1506 * @name Queue API 1507 * @{ 1508 * 1509 * Message queues allows the application to re-route consumed messages 1510 * from multiple topic+partitions into one single queue point. 1511 * This queue point containing messages from a number of topic+partitions 1512 * may then be served by a single rd_kafka_consume*_queue() call, 1513 * rather than one call per topic+partition combination. 1514 */ 1515 1516 1517 /** 1518 * @brief Create a new message queue. 1519 * 1520 * See rd_kafka_consume_start_queue(), rd_kafka_consume_queue(), et.al. 1521 */ 1522 1523 rd_kafka_queue_t *rd_kafka_queue_new(rd_kafka_t *rk); 1524 1525 /** 1526 * Destroy a queue, purging all of its enqueued messages. 1527 */ 1528 1529 void rd_kafka_queue_destroy(rd_kafka_queue_t *rkqu); 1530 1531 /** 1532 * @returns a reference to the main librdkafka event queue. 1533 * This is the queue served by rd_kafka_poll(). 1534 * 1535 * Use rd_kafka_queue_destroy() to loose the reference. 1536 */ 1537 rd_kafka_queue_t *rd_kafka_queue_get_main (rd_kafka_t *rk); 1538 1539 1540 /** 1541 * @returns a reference to the librdkafka consumer queue. 1542 * This is the queue served by rd_kafka_consumer_poll(). 1543 * 1544 * Use rd_kafka_queue_destroy() to loose the reference. 1545 * 1546 * @remark rd_kafka_queue_destroy() MUST be called on this queue 1547 * prior to calling rd_kafka_consumer_close(). 1548 */ 1549 rd_kafka_queue_t *rd_kafka_queue_get_consumer (rd_kafka_t *rk); 1550 1551 1552 /** 1553 * @brief Forward/re-route queue \p src to \p dst. 1554 * If \p dst is \c NULL the forwarding is removed. 1555 * 1556 * The internal refcounts for both queues are increased. 1557 */ 1558 void rd_kafka_queue_forward (rd_kafka_queue_t *src, rd_kafka_queue_t *dst); 1559 1560 1561 /** 1562 * @returns the current number of elements in queue. 1563 */ 1564 size_t rd_kafka_queue_length (rd_kafka_queue_t *rkqu); 1565 1566 1567 /** 1568 * @brief Enable IO event triggering for queue. 1569 * 1570 * To ease integration with IO based polling loops this API 1571 * allows an application to create a separate file-descriptor 1572 * that librdkafka will write \p payload (of size \p size) to 1573 * whenever a new element is enqueued on a previously empty queue. 1574 * 1575 * To remove event triggering call with \p fd = -1. 1576 * 1577 * librdkafka will maintain a copy of the \p payload. 1578 * 1579 * @remark When using forwarded queues the IO event must only be enabled 1580 * on the final forwarded-to (destination) queue. 1581 */ 1582 void rd_kafka_queue_io_event_enable (rd_kafka_queue_t *rkqu, int fd, 1583 const (void) *payload, size_t size); 1584 1585 1586 /**@}*/ 1587 1588 /** 1589 * 1590 * @name Simple Consumer API (legacy) 1591 * @{ 1592 * 1593 */ 1594 1595 1596 enum RD_KAFKA_OFFSET_BEGINNING = -2; /**< Start consuming from beginning of 1597 * kafka partition queue: oldest msg */ 1598 enum RD_KAFKA_OFFSET_END = -1; /**< Start consuming from end of kafka 1599 * partition queue: next msg */ 1600 enum RD_KAFKA_OFFSET_STORED = -1000; /**< Start consuming from offset retrieved 1601 * from offset store */ 1602 enum RD_KAFKA_OFFSET_INVALID = -1001; /**< Invalid offset */ 1603 1604 1605 /** @cond NO_DOC */ 1606 enum RD_KAFKA_OFFSET_TAIL_BASE = -2000; /* internal: do not use */ 1607 /** @endcond */ 1608 1609 /** 1610 * @brief Start consuming \p CNT messages from topic's current end offset. 1611 * 1612 * That is, if current end offset is 12345 and \p CNT is 200, it will start 1613 * consuming from offset \c 12345-200 = \c 12145. */ 1614 auto RD_KAFKA_OFFSET_TAIL(T)(T CNT) { return (RD_KAFKA_OFFSET_TAIL_BASE - (CNT));} 1615 1616 /** 1617 * @brief Start consuming messages for topic \p rkt and \p partition 1618 * at offset \p offset which may either be an absolute \c (0..N) 1619 * or one of the logical offsets: 1620 * - RD_KAFKA_OFFSET_BEGINNING 1621 * - RD_KAFKA_OFFSET_END 1622 * - RD_KAFKA_OFFSET_STORED 1623 * - RD_KAFKA_OFFSET_TAIL 1624 * 1625 * rdkafka will attempt to keep \c queued.min.messages (config property) 1626 * messages in the local queue by repeatedly fetching batches of messages 1627 * from the broker until the threshold is reached. 1628 * 1629 * The application shall use one of the `rd_kafka_consume*()` functions 1630 * to consume messages from the local queue, each kafka message being 1631 * represented as a `rd_kafka_message_t *` object. 1632 * 1633 * `rd_kafka_consume_start()` must not be called multiple times for the same 1634 * topic and partition without stopping consumption first with 1635 * `rd_kafka_consume_stop()`. 1636 * 1637 * @returns 0 on success or -1 on error in which case errno is set accordingly: 1638 * - EBUSY - Conflicts with an existing or previous subscription 1639 * (RD_KAFKA_RESP_ERR__CONFLICT) 1640 * - EINVAL - Invalid offset, or incomplete configuration (lacking group.id) 1641 * (RD_KAFKA_RESP_ERR__INVALID_ARG) 1642 * - ESRCH - requested \p partition is invalid. 1643 * (RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION) 1644 * - ENOENT - topic is unknown in the Kafka cluster. 1645 * (RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC) 1646 * 1647 * Use `rd_kafka_errno2err()` to convert sytem \c errno to `rd_kafka_resp_err_t` 1648 */ 1649 1650 int rd_kafka_consume_start(rd_kafka_topic_t *rkt, int32_t partition, 1651 int64_t offset); 1652 1653 /** 1654 * @brief Same as rd_kafka_consume_start() but re-routes incoming messages to 1655 * the provided queue \p rkqu (which must have been previously allocated 1656 * with `rd_kafka_queue_new()`. 1657 * 1658 * The application must use one of the `rd_kafka_consume_*_queue()` functions 1659 * to receive fetched messages. 1660 * 1661 * `rd_kafka_consume_start_queue()` must not be called multiple times for the 1662 * same topic and partition without stopping consumption first with 1663 * `rd_kafka_consume_stop()`. 1664 * `rd_kafka_consume_start()` and `rd_kafka_consume_start_queue()` must not 1665 * be combined for the same topic and partition. 1666 */ 1667 1668 int rd_kafka_consume_start_queue(rd_kafka_topic_t *rkt, int32_t partition, 1669 int64_t offset, rd_kafka_queue_t *rkqu); 1670 1671 /** 1672 * @brief Stop consuming messages for topic \p rkt and \p partition, purging 1673 * all messages currently in the local queue. 1674 * 1675 * NOTE: To enforce synchronisation this call will block until the internal 1676 * fetcher has terminated and offsets are committed to configured 1677 * storage method. 1678 * 1679 * The application needs to be stop all consumers before calling 1680 * `rd_kafka_destroy()` on the main object handle. 1681 * 1682 * @returns 0 on success or -1 on error (see `errno`). 1683 */ 1684 1685 int rd_kafka_consume_stop(rd_kafka_topic_t *rkt, int32_t partition); 1686 1687 1688 1689 /** 1690 * @brief Seek consumer for topic+partition to \p offset which is either an 1691 * absolute or logical offset. 1692 * 1693 * If \p timeout_ms is not 0 the call will wait this long for the 1694 * seek to be performed. If the timeout is reached the internal state 1695 * will be unknown and this function returns `RD_KAFKA_RESP_ERR__TIMED_OUT`. 1696 * If \p timeout_ms is 0 it will initiate the seek but return 1697 * immediately without any error reporting (e.g., async). 1698 * 1699 * This call triggers a fetch queue barrier flush. 1700 * 1701 * @returns `RD_KAFKA_RESP_ERR__NO_ERROR` on success else an error code. 1702 */ 1703 1704 rd_kafka_resp_err_t rd_kafka_seek (rd_kafka_topic_t *rkt, 1705 int32_t partition, 1706 int64_t offset, 1707 int timeout_ms); 1708 1709 1710 /** 1711 * @brief Consume a single message from topic \p rkt and \p partition 1712 * 1713 * \p timeout_ms is maximum amount of time to wait for a message to be received. 1714 * Consumer must have been previously started with `rd_kafka_consume_start()`. 1715 * 1716 * Returns a message object on success or \c NULL on error. 1717 * The message object must be destroyed with `rd_kafka_message_destroy()` 1718 * when the application is done with it. 1719 * 1720 * Errors (when returning NULL): 1721 * - ETIMEDOUT - \p timeout_ms was reached with no new messages fetched. 1722 * - ENOENT - \p rkt + \p partition is unknown. 1723 * (no prior `rd_kafka_consume_start()` call) 1724 * 1725 * NOTE: The returned message's \c ..->err must be checked for errors. 1726 * NOTE: \c ..->err \c == \c RD_KAFKA_RESP_ERR__PARTITION_EOF signals that the 1727 * end of the partition has been reached, which should typically not be 1728 * considered an error. The application should handle this case 1729 * (e.g., ignore). 1730 */ 1731 1732 rd_kafka_message_t *rd_kafka_consume(rd_kafka_topic_t *rkt, int32_t partition, 1733 int timeout_ms); 1734 1735 1736 1737 /** 1738 * @brief Consume up to \p rkmessages_size from topic \p rkt and \p partition 1739 * putting a pointer to each message in the application provided 1740 * array \p rkmessages (of size \p rkmessages_size entries). 1741 * 1742 * `rd_kafka_consume_batch()` provides higher throughput performance 1743 * than `rd_kafka_consume()`. 1744 * 1745 * \p timeout_ms is the maximum amount of time to wait for all of 1746 * \p rkmessages_size messages to be put into \p rkmessages. 1747 * If no messages were available within the timeout period this function 1748 * returns 0 and \p rkmessages remains untouched. 1749 * This differs somewhat from `rd_kafka_consume()`. 1750 * 1751 * The message objects must be destroyed with `rd_kafka_message_destroy()` 1752 * when the application is done with it. 1753 * 1754 * @returns the number of rkmessages added in \p rkmessages, 1755 * or -1 on error (same error codes as for `rd_kafka_consume()`. 1756 * 1757 * @sa rd_kafka_consume() 1758 */ 1759 1760 ssize_t rd_kafka_consume_batch(rd_kafka_topic_t *rkt, int32_t partition, 1761 int timeout_ms, 1762 rd_kafka_message_t **rkmessages, 1763 size_t rkmessages_size); 1764 1765 1766 1767 /** 1768 * @brief Consumes messages from topic \p rkt and \p partition, calling 1769 * the provided callback for each consumed messsage. 1770 * 1771 * `rd_kafka_consume_callback()` provides higher throughput performance 1772 * than both `rd_kafka_consume()` and `rd_kafka_consume_batch()`. 1773 * 1774 * \p timeout_ms is the maximum amount of time to wait for one or more messages 1775 * to arrive. 1776 * 1777 * The provided \p consume_cb function is called for each message, 1778 * the application \b MUST \b NOT call `rd_kafka_message_destroy()` on the 1779 * provided \p rkmessage. 1780 * 1781 * The \p opaque argument is passed to the 'consume_cb' as \p opaque. 1782 * 1783 * @returns the number of messages processed or -1 on error. 1784 * 1785 * @sa rd_kafka_consume() 1786 */ 1787 alias consume_callback_callback = extern(D) void function(rd_kafka_message_t*rkmessage,void *opaque) nothrow @nogc; 1788 /// ditto 1789 int rd_kafka_consume_callback(rd_kafka_topic_t *rkt, int32_t partition,int timeout_ms, consume_callback_callback consume_cb ,void *opaque); 1790 1791 1792 /** 1793 * @name Simple Consumer API (legacy): Queue consumers 1794 * @{ 1795 * 1796 * The following `..._queue()` functions are analogue to the functions above 1797 * but reads messages from the provided queue \p rkqu instead. 1798 * \p rkqu must have been previously created with `rd_kafka_queue_new()` 1799 * and the topic consumer must have been started with 1800 * `rd_kafka_consume_start_queue()` utilising the the same queue. 1801 */ 1802 1803 /** 1804 * @brief Consume from queue 1805 * 1806 * @sa rd_kafka_consume() 1807 */ 1808 1809 rd_kafka_message_t *rd_kafka_consume_queue(rd_kafka_queue_t *rkqu, 1810 int timeout_ms); 1811 1812 /** 1813 * @brief Consume batch of messages from queue 1814 * 1815 * @sa rd_kafka_consume_batch() 1816 */ 1817 1818 ssize_t rd_kafka_consume_batch_queue(rd_kafka_queue_t *rkqu, 1819 int timeout_ms, 1820 rd_kafka_message_t **rkmessages, 1821 size_t rkmessages_size); 1822 1823 /** 1824 * @brief Consume multiple messages from queue with callback 1825 * 1826 * @sa rd_kafka_consume_callback() 1827 */ 1828 alias consume_callback_queue_callback = extern(D) void function(rd_kafka_message_t *rkmessage,void *opaque) nothrow @nogc; 1829 /// ditto 1830 int rd_kafka_consume_callback_queue(rd_kafka_queue_t *rkqu,int timeout_ms, 1831 consume_callback_queue_callback consume_cb, 1832 void *opaque); 1833 1834 1835 /**@}*/ 1836 1837 1838 1839 1840 /** 1841 * @name Simple Consumer API (legacy): Topic+partition offset store. 1842 * @{ 1843 * 1844 * If \c auto.commit.enable is true the offset is stored automatically prior to 1845 * returning of the message(s) in each of the rd_kafka_consume*() functions 1846 * above. 1847 */ 1848 1849 1850 /** 1851 * @brief Store offset \p offset for topic \p rkt partition \p partition. 1852 * 1853 * The offset will be committed (written) to the offset store according 1854 * to \c `auto.commit.interval.ms`. 1855 * 1856 * @remark \c `auto.commit.enable` must be set to "false" when using this API. 1857 * 1858 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or an error code on error. 1859 */ 1860 1861 rd_kafka_resp_err_t rd_kafka_offset_store(rd_kafka_topic_t *rkt, 1862 int32_t partition, int64_t offset); 1863 /**@}*/ 1864 1865 1866 1867 1868 /** 1869 * @name KafkaConsumer (C) 1870 * @{ 1871 * @brief High-level KafkaConsumer C API 1872 * 1873 * 1874 * 1875 */ 1876 1877 /** 1878 * @brief Subscribe to topic set using balanced consumer groups. 1879 * 1880 * Wildcard (regex) topics are supported by the librdkafka assignor: 1881 * any topic name in the \p topics list that is prefixed with \c \"^\" will 1882 * be regex-matched to the full list of topics in the cluster and matching 1883 * topics will be added to the subscription list. 1884 */ 1885 rd_kafka_resp_err_t 1886 rd_kafka_subscribe (rd_kafka_t *rk, 1887 const rd_kafka_topic_partition_list_t *topics); 1888 1889 1890 /** 1891 * @brief Unsubscribe from the current subscription set. 1892 */ 1893 1894 rd_kafka_resp_err_t rd_kafka_unsubscribe (rd_kafka_t *rk); 1895 1896 1897 /** 1898 * @brief Returns the current topic subscription 1899 * 1900 * @returns An error code on failure, otherwise \p topic is updated 1901 * to point to a newly allocated topic list (possibly empty). 1902 * 1903 * @remark The application is responsible for calling 1904 * rd_kafka_topic_partition_list_destroy on the returned list. 1905 */ 1906 rd_kafka_resp_err_t 1907 rd_kafka_subscription (rd_kafka_t *rk, 1908 rd_kafka_topic_partition_list_t **topics); 1909 1910 1911 1912 /** 1913 * @brief Poll the consumer for messages or events. 1914 * 1915 * Will block for at most \p timeout_ms milliseconds. 1916 * 1917 * @remark An application should make sure to call consumer_poll() at regular 1918 * intervals, even if no messages are expected, to serve any 1919 * queued callbacks waiting to be called. This is especially 1920 * important when a rebalance_cb has been registered as it needs 1921 * to be called and handled properly to synchronize internal 1922 * consumer state. 1923 * 1924 * @returns A message object which is a proper message if \p ->err is 1925 * RD_KAFKA_RESP_ERR_NO_ERROR, or an event or error for any other 1926 * value. 1927 * 1928 * @sa rd_kafka_message_t 1929 */ 1930 1931 rd_kafka_message_t *rd_kafka_consumer_poll (rd_kafka_t *rk, int timeout_ms); 1932 1933 /** 1934 * @brief Close down the KafkaConsumer. 1935 * 1936 * @remark This call will block until the consumer has revoked its assignment, 1937 * calling the \c rebalance_cb if it is configured, committed offsets 1938 * to broker, and left the consumer group. 1939 * The maximum blocking time is roughly limited to session.timeout.ms. 1940 * 1941 * @returns An error code indicating if the consumer close was succesful 1942 * or not. 1943 * 1944 * @remark The application still needs to call rd_kafka_destroy() after 1945 * this call finishes to clean up the underlying handle resources. 1946 * 1947 * 1948 */ 1949 1950 rd_kafka_resp_err_t rd_kafka_consumer_close (rd_kafka_t *rk); 1951 1952 1953 1954 /** 1955 * @brief Atomic assignment of partitions to consume. 1956 * 1957 * The new \p partitions will replace the existing assignment. 1958 * 1959 * When used from a rebalance callback the application shall pass the 1960 * partition list passed to the callback (or a copy of it) (even if the list 1961 * is empty) rather than NULL to maintain internal join state. 1962 1963 * A zero-length \p partitions will treat the partitions as a valid, 1964 * albeit empty, assignment, and maintain internal state, while a \c NULL 1965 * value for \p partitions will reset and clear the internal state. 1966 */ 1967 rd_kafka_resp_err_t 1968 rd_kafka_assign (rd_kafka_t *rk, 1969 const rd_kafka_topic_partition_list_t *partitions); 1970 1971 /** 1972 * @brief Returns the current partition assignment 1973 * 1974 * @returns An error code on failure, otherwise \p partitions is updated 1975 * to point to a newly allocated partition list (possibly empty). 1976 * 1977 * @remark The application is responsible for calling 1978 * rd_kafka_topic_partition_list_destroy on the returned list. 1979 */ 1980 rd_kafka_resp_err_t 1981 rd_kafka_assignment (rd_kafka_t *rk, 1982 rd_kafka_topic_partition_list_t **partitions); 1983 1984 1985 1986 1987 /** 1988 * @brief Commit offsets on broker for the provided list of partitions. 1989 * 1990 * \p offsets should contain \c topic, \c partition, \c offset and possibly 1991 * \c metadata. 1992 * If \p offsets is NULL the current partition assignment will be used instead. 1993 * 1994 * If \p async is false this operation will block until the broker offset commit 1995 * is done, returning the resulting success or error code. 1996 * 1997 * If a rd_kafka_conf_set_offset_commit_cb() offset commit callback has been 1998 * configured: 1999 * * if async: callback will be enqueued for a future call to rd_kafka_poll(). 2000 * * if !async: callback will be called from rd_kafka_commit() 2001 */ 2002 rd_kafka_resp_err_t 2003 rd_kafka_commit (rd_kafka_t *rk, const rd_kafka_topic_partition_list_t *offsets, 2004 int async); 2005 2006 2007 /** 2008 * @brief Commit message's offset on broker for the message's partition. 2009 * 2010 * @sa rd_kafka_commit 2011 */ 2012 rd_kafka_resp_err_t 2013 rd_kafka_commit_message (rd_kafka_t *rk, const rd_kafka_message_t *rkmessage, 2014 int async); 2015 2016 2017 /** 2018 * @brief Commit offsets on broker for the provided list of partitions. 2019 * 2020 * See rd_kafka_commit for \p offsets semantics. 2021 * 2022 * The result of the offset commit will be posted on the provided \p rkqu queue. 2023 * 2024 * If the application uses one of the poll APIs (rd_kafka_poll(), 2025 * rd_kafka_consumer_poll(), rd_kafka_queue_poll(), ..) to serve the queue 2026 * the \p cb callback is required. \p opaque is passed to the callback. 2027 * 2028 * If using the event API the callback is ignored and the offset commit result 2029 * will be returned as an RD_KAFKA_EVENT_COMMIT event. The \p opaque 2030 * value will be available with rd_kafka_event_opaque() 2031 * 2032 * If \p rkqu is NULL a temporary queue will be created and the callback will 2033 * be served by this call. 2034 * 2035 * @sa rd_kafka_commit() 2036 * @sa rd_kafka_conf_set_offset_commit_cb() 2037 */ 2038 rd_kafka_resp_err_t 2039 rd_kafka_commit_queue (rd_kafka_t *rk, 2040 const rd_kafka_topic_partition_list_t *offsets, 2041 rd_kafka_queue_t *rkqu, 2042 void function(rd_kafka_t *rk, 2043 rd_kafka_resp_err_t err, 2044 rd_kafka_topic_partition_list_t *offsets, 2045 void *opaque) nothrow @nogc cb, 2046 void *opaque); 2047 2048 2049 /** 2050 * @brief Retrieve committed offsets for topics+partitions. 2051 * 2052 * The \p offset field of each requested partition will either be set to 2053 * stored offset or to RD_KAFKA_OFFSET_INVALID in case there was no stored 2054 * offset for that partition. 2055 * 2056 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success in which case the 2057 * \p offset or \p err field of each \p partitions' element is filled 2058 * in with the stored offset, or a partition specific error. 2059 * Else returns an error code. 2060 */ 2061 rd_kafka_resp_err_t 2062 rd_kafka_committed (rd_kafka_t *rk, 2063 rd_kafka_topic_partition_list_t *partitions, 2064 int timeout_ms); 2065 2066 2067 2068 /** 2069 * @brief Retrieve current positions (offsets) for topics+partitions. 2070 * 2071 * The \p offset field of each requested partition will be set to the offset 2072 * of the last consumed message + 1, or RD_KAFKA_OFFSET_INVALID in case there was 2073 * no previous message. 2074 * 2075 * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success in which case the 2076 * \p offset or \p err field of each \p partitions' element is filled 2077 * in with the stored offset, or a partition specific error. 2078 * Else returns an error code. 2079 */ 2080 rd_kafka_resp_err_t 2081 rd_kafka_position (rd_kafka_t *rk, 2082 rd_kafka_topic_partition_list_t *partitions); 2083 2084 /**@}*/ 2085 2086 2087 2088 /** 2089 * @name Producer API 2090 * @{ 2091 * 2092 * 2093 */ 2094 2095 2096 /** 2097 * @brief Producer message flags 2098 */ 2099 enum RD_KAFKA_MSG_F_FREE = 0x1; /**< Delegate freeing of payload to rdkafka. */ 2100 enum RD_KAFKA_MSG_F_COPY = 0x2; /**< rdkafka will make a copy of the payload. */ 2101 2102 2103 2104 /** 2105 * @brief Produce and send a single message to broker. 2106 * 2107 * \p rkt is the target topic which must have been previously created with 2108 * `rd_kafka_topic_new()`. 2109 * 2110 * `rd_kafka_produce()` is an asynch non-blocking API. 2111 * 2112 * \p partition is the target partition, either: 2113 * - RD_KAFKA_PARTITION_UA (unassigned) for 2114 * automatic partitioning using the topic's partitioner function, or 2115 * - a fixed partition (0..N) 2116 * 2117 * \p msgflags is zero or more of the following flags OR:ed together: 2118 * RD_KAFKA_MSG_F_BLOCK - block \p produce*() call if 2119 * \p queue.buffering.max.messages or 2120 * \p queue.buffering.max.kbytes are exceeded. 2121 * Messages are considered in-queue from the point they 2122 * are accepted by produce() until their corresponding 2123 * delivery report callback/event returns. 2124 * It is thus a requirement to call 2125 * rd_kafka_poll() (or equiv.) from a separate 2126 * thread when F_BLOCK is used. 2127 * See WARNING on \c RD_KAFKA_MSG_F_BLOCK above. 2128 * 2129 * RD_KAFKA_MSG_F_FREE - rdkafka will free(3) \p payload when it is done 2130 * with it. 2131 * RD_KAFKA_MSG_F_COPY - the \p payload data will be copied and the 2132 * \p payload pointer will not be used by rdkafka 2133 * after the call returns. 2134 * 2135 * .._F_FREE and .._F_COPY are mutually exclusive. 2136 * 2137 * If the function returns -1 and RD_KAFKA_MSG_F_FREE was specified, then 2138 * the memory associated with the payload is still the caller's 2139 * responsibility. 2140 * 2141 * \p payload is the message payload of size \p len bytes. 2142 * 2143 * \p key is an optional message key of size \p keylen bytes, if non-NULL it 2144 * will be passed to the topic partitioner as well as be sent with the 2145 * message to the broker and passed on to the consumer. 2146 * 2147 * \p msg_opaque is an optional application-provided per-message opaque 2148 * pointer that will provided in the delivery report callback (`dr_cb`) for 2149 * referencing this message. 2150 * 2151 * Returns 0 on success or -1 on error in which case errno is set accordingly: 2152 * - ENOBUFS - maximum number of outstanding messages has been reached: 2153 * "queue.buffering.max.messages" 2154 * (RD_KAFKA_RESP_ERR__QUEUE_FULL) 2155 * - EMSGSIZE - message is larger than configured max size: 2156 * "messages.max.bytes". 2157 * (RD_KAFKA_RESP_ERR_MSG_SIZE_TOO_LARGE) 2158 * - ESRCH - requested \p partition is unknown in the Kafka cluster. 2159 * (RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION) 2160 * - ENOENT - topic is unknown in the Kafka cluster. 2161 * (RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC) 2162 * 2163 * @sa Use rd_kafka_errno2err() to convert `errno` to rdkafka error code. 2164 */ 2165 2166 int rd_kafka_produce(rd_kafka_topic_t *rkt, int32_t partition, 2167 int msgflags, 2168 void *payload, size_t len, 2169 const (void) *key, size_t keylen, 2170 void *msg_opaque); 2171 2172 2173 2174 /** 2175 * @brief Produce multiple messages. 2176 * 2177 * If partition is RD_KAFKA_PARTITION_UA the configured partitioner will 2178 * be run for each message (slower), otherwise the messages will be enqueued 2179 * to the specified partition directly (faster). 2180 * 2181 * The messages are provided in the array \p rkmessages of count \p message_cnt 2182 * elements. 2183 * The \p partition and \p msgflags are used for all provided messages. 2184 * 2185 * Honoured \p rkmessages[] fields are: 2186 * - payload,len Message payload and length 2187 * - key,key_len Optional message key 2188 * - _private Message opaque pointer (msg_opaque) 2189 * - err Will be set according to success or failure. 2190 * Application only needs to check for errors if 2191 * return value != \p message_cnt. 2192 * 2193 * @returns the number of messages succesfully enqueued for producing. 2194 */ 2195 2196 int rd_kafka_produce_batch(rd_kafka_topic_t *rkt, int32_t partition, 2197 int msgflags, 2198 rd_kafka_message_t *rkmessages, int message_cnt); 2199 2200 2201 /** 2202 * @brief Wait until all outstanding produce requests, et.al, are completed. 2203 * This should typically be done prior to destroying a producer instance 2204 * to make sure all queued and in-flight produce requests are completed 2205 * before terminating. 2206 * 2207 * @remark This function will call rd_kafka_poll() and thus trigger callbacks. 2208 * 2209 * @returns RD_KAFKA_RESP_ERR__TIMED_OUT if \p timeout_ms was reached before all 2210 * outstanding requests were completed, else RD_KAFKA_RESP_ERR_NO_ERROR 2211 */ 2212 rd_kafka_resp_err_t rd_kafka_flush (rd_kafka_t *rk, int timeout_ms); 2213 2214 2215 /**@}*/ 2216 2217 2218 /** 2219 * @name Metadata API 2220 * @{ 2221 * 2222 * 2223 */ 2224 2225 2226 /** 2227 * @brief Broker information 2228 */ 2229 struct rd_kafka_metadata_broker { 2230 int32_t id; /**< Broker Id */ 2231 char *host; /**< Broker hostname */ 2232 int port; /**< Broker listening port */ 2233 } ; 2234 alias rd_kafka_metadata_broker_t = rd_kafka_metadata_broker; 2235 2236 /** 2237 * @brief Partition information 2238 */ 2239 struct rd_kafka_metadata_partition { 2240 int32_t id; /**< Partition Id */ 2241 rd_kafka_resp_err_t err; /**< Partition error reported by broker */ 2242 int32_t leader; /**< Leader broker */ 2243 int replica_cnt; /**< Number of brokers in \p replicas */ 2244 int32_t *replicas; /**< Replica brokers */ 2245 int isr_cnt; /**< Number of ISR brokers in \p isrs */ 2246 int32_t *isrs; /**< In-Sync-Replica brokers */ 2247 } ; 2248 alias rd_kafka_metadata_partition_t = rd_kafka_metadata_partition; 2249 2250 /** 2251 * @brief Topic information 2252 */ 2253 struct rd_kafka_metadata_topic { 2254 char *topic; /**< Topic name */ 2255 int partition_cnt; /**< Number of partitions in \p partitions*/ 2256 rd_kafka_metadata_partition *partitions; /**< Partitions */ 2257 rd_kafka_resp_err_t err; /**< Topic error reported by broker */ 2258 } ; 2259 alias rd_kafka_metadata_topic_t = rd_kafka_metadata_topic; 2260 2261 2262 /** 2263 * @brief Metadata container 2264 */ 2265 struct rd_kafka_metadata_t { 2266 int broker_cnt; /**< Number of brokers in \p brokers */ 2267 rd_kafka_metadata_broker *brokers; /**< Brokers */ 2268 2269 int topic_cnt; /**< Number of topics in \p topics */ 2270 rd_kafka_metadata_topic *topics; /**< Topics */ 2271 2272 int32_t orig_broker_id; /**< Broker originating this metadata */ 2273 char *orig_broker_name; /**< Name of originating broker */ 2274 } ; 2275 //alias rd_kafka_metadata_t = rd_kafka_metadata; 2276 2277 /** 2278 * @brief Request Metadata from broker. 2279 * 2280 * Parameters: 2281 * - \p all_topics if non-zero: request info about all topics in cluster, 2282 * if zero: only request info about locally known topics. 2283 * - \p only_rkt only request info about this topic 2284 * - \p metadatap pointer to hold metadata result. 2285 * The \p *metadatap pointer must be released 2286 * with rd_kafka_metadata_destroy(). 2287 * - \p timeout_ms maximum response time before failing. 2288 * 2289 * Returns RD_KAFKA_RESP_ERR_NO_ERROR on success (in which case *metadatap) 2290 * will be set, else RD_KAFKA_RESP_ERR__TIMED_OUT on timeout or 2291 * other error code on error. 2292 */ 2293 2294 rd_kafka_resp_err_t rd_kafka_metadata(rd_kafka_t *rk, int all_topics, rd_kafka_topic_t *only_rkt,const rd_kafka_metadata_t * * metadatap, int timeout_ms); 2295 2296 /** 2297 * @brief Release metadata memory. 2298 */ 2299 2300 void rd_kafka_metadata_destroy(const rd_kafka_metadata_t *metadata); 2301 2302 2303 /**@}*/ 2304 2305 2306 2307 /** 2308 * @name Client group information 2309 * @{ 2310 * 2311 * 2312 */ 2313 2314 2315 /** 2316 * @brief Group member information 2317 * 2318 * For more information on \p member_metadata format, see 2319 * https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-GroupMembershipAPI 2320 * 2321 */ 2322 struct rd_kafka_group_member_info { 2323 char *member_id; /**< Member id (generated by broker) */ 2324 char *client_id; /**< Client's \p client.id */ 2325 char *client_host; /**< Client's hostname */ 2326 void *member_metadata; /**< Member metadata (binary), 2327 * format depends on \p protocol_type. */ 2328 int member_metadata_size; /**< Member metadata size in bytes */ 2329 void *member_assignment; /**< Member assignment (binary), 2330 * format depends on \p protocol_type. */ 2331 int member_assignment_size; /**< Member assignment size in bytes */ 2332 }; 2333 2334 /** 2335 * @brief Group information 2336 */ 2337 struct rd_kafka_group_info { 2338 rd_kafka_metadata_broker broker; /**< Originating broker info */ 2339 char *group; /**< Group name */ 2340 rd_kafka_resp_err_t err; /**< Broker-originated error */ 2341 char *state; /**< Group state */ 2342 char *protocol_type; /**< Group protocol type */ 2343 char *protocol; /**< Group protocol */ 2344 rd_kafka_group_member_info *members; /**< Group members */ 2345 int member_cnt; /**< Group member count */ 2346 }; 2347 2348 /** 2349 * @brief List of groups 2350 * 2351 * @sa rd_kafka_group_list_destroy() to release list memory. 2352 */ 2353 struct rd_kafka_group_list { 2354 rd_kafka_group_info *groups; /**< Groups */ 2355 int group_cnt; /**< Group count */ 2356 }; 2357 2358 2359 /** 2360 * @brief List and describe client groups in cluster. 2361 * 2362 * \p group is an optional group name to describe, otherwise (\p NULL) all 2363 * groups are returned. 2364 * 2365 * \p timeout_ms is the (approximate) maximum time to wait for response 2366 * from brokers and must be a positive value. 2367 * 2368 * @returns \p RD_KAFKA_RESP_ERR__NO_ERROR on success and \p grplistp is 2369 * updated to point to a newly allocated list of groups. 2370 * Else returns an error code on failure and \p grplistp remains 2371 * untouched. 2372 * 2373 * @sa Use rd_kafka_group_list_destroy() to release list memory. 2374 */ 2375 2376 rd_kafka_resp_err_t 2377 rd_kafka_list_groups (rd_kafka_t *rk, const(char) *group, 2378 const rd_kafka_group_list **grplistp, 2379 int timeout_ms); 2380 2381 /** 2382 * @brief Release list memory 2383 */ 2384 2385 void rd_kafka_group_list_destroy (const rd_kafka_group_list *grplist); 2386 2387 2388 /**@}*/ 2389 2390 2391 2392 /** 2393 * @name Miscellaneous APIs 2394 * @{ 2395 * 2396 */ 2397 2398 2399 /** 2400 * @brief Adds one or more brokers to the kafka handle's list of initial 2401 * bootstrap brokers. 2402 * 2403 * Additional brokers will be discovered automatically as soon as rdkafka 2404 * connects to a broker by querying the broker metadata. 2405 * 2406 * If a broker name resolves to multiple addresses (and possibly 2407 * address families) all will be used for connection attempts in 2408 * round-robin fashion. 2409 * 2410 * \p brokerlist is a ,-separated list of brokers in the format: 2411 * \c \<broker1\>,\<broker2\>,.. 2412 * Where each broker is in either the host or URL based format: 2413 * \c \<host\>[:\<port\>] 2414 * \c \<proto\>://\<host\>[:port] 2415 * \c \<proto\> is either \c PLAINTEXT, \c SSL, \c SASL, \c SASL_PLAINTEXT 2416 * The two formats can be mixed but ultimately the value of the 2417 * `security.protocol` config property decides what brokers are allowed. 2418 * 2419 * Example: 2420 * brokerlist = "broker1:10000,broker2" 2421 * brokerlist = "SSL://broker3:9000,ssl://broker2" 2422 * 2423 * @returns the number of brokers successfully added. 2424 * 2425 * @remark Brokers may also be defined with the \c metadata.broker.list or 2426 * \c bootstrap.servers configuration property (preferred method). 2427 */ 2428 2429 int rd_kafka_brokers_add(rd_kafka_t *rk, const(char) *brokerlist); 2430 2431 2432 2433 2434 /** 2435 * @brief Set logger function. 2436 * 2437 * The default is to print to stderr, but a syslog logger is also available, 2438 * see rd_kafka_log_(print|syslog) for the builtin alternatives. 2439 * Alternatively the application may provide its own logger callback. 2440 * Or pass 'func' as NULL to disable logging. 2441 * 2442 * @deprecated Use rd_kafka_conf_set_log_cb() 2443 * 2444 * @remark \p rk may be passed as NULL in the callback. 2445 */ 2446 2447 deprecated("please use rd_kafka_conf_set_log_cb"){ 2448 alias func_callback = void function(const rd_kafka_t *rk, int level,const(char) *fac, const(char) *buf) nothrow @nogc; 2449 void rd_kafka_set_logger(rd_kafka_t *rk,func_callback func); 2450 } 2451 2452 2453 /** 2454 * @brief Specifies the maximum logging level produced by 2455 * internal kafka logging and debugging. 2456 * 2457 * If the \p \"debug\" configuration property is set the level is automatically 2458 * adjusted to \c LOG_DEBUG (7). 2459 */ 2460 2461 void rd_kafka_set_log_level(rd_kafka_t *rk, int level); 2462 2463 2464 /** 2465 * @brief Builtin (default) log sink: print to stderr 2466 */ 2467 2468 void rd_kafka_log_print(const rd_kafka_t *rk, int level, 2469 const(char) *fac, const(char) *buf); 2470 2471 2472 /** 2473 * @brief Builtin log sink: print to syslog. 2474 */ 2475 2476 void rd_kafka_log_syslog(const rd_kafka_t *rk, int level, 2477 const(char) *fac, const(char) *buf); 2478 2479 2480 /** 2481 * @brief Returns the current out queue length. 2482 * 2483 * The out queue contains messages waiting to be sent to, or acknowledged by, 2484 * the broker. 2485 * 2486 * An application should wait for this queue to reach zero before terminating 2487 * to make sure outstanding requests (such as offset commits) are fully 2488 * processed. 2489 * 2490 * @returns number of messages in the out queue. 2491 */ 2492 2493 int rd_kafka_outq_len(rd_kafka_t *rk); 2494 2495 2496 2497 /** 2498 * @brief Dumps rdkafka's internal state for handle \p rk to stream \p fp 2499 * 2500 * This is only useful for debugging rdkafka, showing state and statistics 2501 * for brokers, topics, partitions, etc. 2502 */ 2503 2504 void rd_kafka_dump(FILE *fp, rd_kafka_t *rk); 2505 2506 2507 2508 /** 2509 * @brief Retrieve the current number of threads in use by librdkafka. 2510 * 2511 * Used by regression tests. 2512 */ 2513 2514 int rd_kafka_thread_cnt(); 2515 2516 2517 /** 2518 * @brief Wait for all rd_kafka_t objects to be destroyed. 2519 * 2520 * Returns 0 if all kafka objects are now destroyed, or -1 if the 2521 * timeout was reached. 2522 * Since `rd_kafka_destroy()` is an asynch operation the 2523 * `rd_kafka_wait_destroyed()` function can be used for applications where 2524 * a clean shutdown is required. 2525 */ 2526 2527 int rd_kafka_wait_destroyed(int timeout_ms); 2528 2529 2530 /**@}*/ 2531 2532 2533 2534 2535 /** 2536 * @name Experimental APIs 2537 * @{ 2538 */ 2539 2540 /** 2541 * @brief Redirect the main (rd_kafka_poll()) queue to the KafkaConsumer's 2542 * queue (rd_kafka_consumer_poll()). 2543 * 2544 * @warning It is not permitted to call rd_kafka_poll() after directing the 2545 * main queue with rd_kafka_poll_set_consumer(). 2546 */ 2547 2548 rd_kafka_resp_err_t rd_kafka_poll_set_consumer (rd_kafka_t *rk); 2549 2550 2551 /**@}*/ 2552 2553 /** 2554 * @name Event interface 2555 * 2556 * @brief The event API provides an alternative pollable non-callback interface 2557 * to librdkafka's message and event queues. 2558 * 2559 * @{ 2560 */ 2561 2562 2563 /** 2564 * @brief Event types 2565 */ 2566 alias int rd_kafka_event_type_t; 2567 enum RD_KAFKA_EVENT_NONE = 0x0; 2568 enum RD_KAFKA_EVENT_DR = 0x1; /**< Producer Delivery report batch */ 2569 enum RD_KAFKA_EVENT_FETCH = 0x2; /**< Fetched message (consumer) */ 2570 enum RD_KAFKA_EVENT_LOG = 0x4; /**< Log message */ 2571 enum RD_KAFKA_EVENT_ERROR = 0x8; /**< Error */ 2572 enum RD_KAFKA_EVENT_REBALANCE = 0x10; /**< Group rebalance (consumer) */ 2573 enum RD_KAFKA_EVENT_OFFSET_COMMIT = 0x20; /**< Offset commit result */ 2574 2575 struct rd_kafka_op_s; 2576 alias rd_kafka_op_s rd_kafka_event_t; 2577 2578 2579 /** 2580 * @returns the event type for the given event. 2581 * 2582 * @remark As a convenience it is okay to pass \p rkev as NULL in which case 2583 * RD_KAFKA_EVENT_NONE is returned. 2584 */ 2585 rd_kafka_event_type_t rd_kafka_event_type (const rd_kafka_event_t *rkev); 2586 2587 /** 2588 * @returns the event type's name for the given event. 2589 * 2590 * @remark As a convenience it is okay to pass \p rkev as NULL in which case 2591 * the name for RD_KAFKA_EVENT_NONE is returned. 2592 */ 2593 const (char) *rd_kafka_event_name (const rd_kafka_event_t *rkev); 2594 2595 2596 /** 2597 * @brief Destroy an event. 2598 * 2599 * @remark Any references to this event, such as extracted messages, 2600 * will not be usable after this call. 2601 * 2602 * @remark As a convenience it is okay to pass \p rkev as NULL in which case 2603 * no action is performed. 2604 */ 2605 void rd_kafka_event_destroy (rd_kafka_event_t *rkev); 2606 2607 2608 /** 2609 * @returns the next message from an event. 2610 * 2611 * Call repeatedly until it returns NULL. 2612 * 2613 * Event types: 2614 * - RD_KAFKA_EVENT_FETCH (1 message) 2615 * - RD_KAFKA_EVENT_DR (>=1 message(s)) 2616 * 2617 * @remark The returned message(s) MUST NOT be 2618 * freed with rd_kafka_message_destroy(). 2619 */ 2620 const (rd_kafka_message_t) *rd_kafka_event_message_next (rd_kafka_event_t *rkev); 2621 2622 2623 /** 2624 * @brief Extacts \p size message(s) from the event into the 2625 * pre-allocated array \p rkmessages. 2626 * 2627 * Event types: 2628 * - RD_KAFKA_EVENT_FETCH (1 message) 2629 * - RD_KAFKA_EVENT_DR (>=1 message(s)) 2630 * 2631 * @returns the number of messages extracted. 2632 */ 2633 size_t rd_kafka_event_message_array (rd_kafka_event_t *rkev, 2634 const rd_kafka_message_t **rkmessages, 2635 size_t size); 2636 2637 2638 /** 2639 * @returns the number of remaining messages in the event. 2640 * 2641 * Event types: 2642 * - RD_KAFKA_EVENT_FETCH (1 message) 2643 * - RD_KAFKA_EVENT_DR (>=1 message(s)) 2644 */ 2645 size_t rd_kafka_event_message_count (rd_kafka_event_t *rkev); 2646 2647 2648 /** 2649 * @returns the error code for the event. 2650 * 2651 * Event types: 2652 * - all 2653 */ 2654 rd_kafka_resp_err_t rd_kafka_event_error (rd_kafka_event_t *rkev); 2655 2656 2657 /** 2658 * @returns the error string (if any). 2659 * An application should check that rd_kafka_event_error() returns 2660 * non-zero before calling this function. 2661 * 2662 * Event types: 2663 * - all 2664 */ 2665 const (char) *rd_kafka_event_error_string (rd_kafka_event_t *rkev); 2666 2667 2668 2669 /** 2670 * @returns the user opaque (if any) 2671 * 2672 * Event types: 2673 * - RD_KAFKA_OFFSET_COMMIT 2674 */ 2675 void *rd_kafka_event_opaque (rd_kafka_event_t *rkev); 2676 2677 2678 /** 2679 * @brief Extract log message from the event. 2680 * 2681 * Event types: 2682 * - RD_KAFKA_EVENT_LOG 2683 * 2684 * @returns 0 on success or -1 if unsupported event type. 2685 */ 2686 int rd_kafka_event_log (rd_kafka_event_t *rkev, 2687 const (char) **fac, const (char) **str, int *level); 2688 2689 2690 /** 2691 * @returns the topic partition list from the event. 2692 * 2693 * @remark The list MUST NOT be freed with rd_kafka_topic_partition_list_destroy() 2694 * 2695 * Event types: 2696 * - RD_KAFKA_EVENT_REBALANCE 2697 * - RD_KAFKA_EVENT_OFFSET_COMMIT 2698 */ 2699 rd_kafka_topic_partition_list_t * 2700 rd_kafka_event_topic_partition_list (rd_kafka_event_t *rkev); 2701 2702 2703 /** 2704 * @returns a newly allocated topic_partition container, if applicable for the event type, 2705 * else NULL. 2706 * 2707 * @remark The returned pointer MUST be freed with rd_kafka_topic_partition_destroy(). 2708 * 2709 * Event types: 2710 * RD_KAFKA_EVENT_ERROR (for partition level errors) 2711 */ 2712 rd_kafka_topic_partition_t * 2713 rd_kafka_event_topic_partition (rd_kafka_event_t *rkev); 2714 2715 2716 /** 2717 * @brief Poll a queue for an event for max \p timeout_ms. 2718 * 2719 * @returns an event, or NULL. 2720 * 2721 * @remark Use rd_kafka_event_destroy() to free the event. 2722 */ 2723 rd_kafka_event_t *rd_kafka_queue_poll (rd_kafka_queue_t *rkqu, int timeout_ms); 2724 2725 /**@}*/