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 /**@}*/