librdkafka源码解析 Consumer

消息体定义:(消费者消息)

包含topic,partition,value(*key),消息长度,offset

typedef struct rd_kafka_message_s {
        rd_kafka_resp_err_t err; /**< Non-zero for error signaling. */
        rd_kafka_topic_t *rkt;   /**< Topic */
        int32_t partition;       /**< Partition */
        void *payload;           /**< Producer: original message payload.
                                  * Consumer: Depends on the value of \c err :
                                  * - \c err==0: Message payload.
                                  * - \c err!=0: Error string */
        size_t len;              /**< Depends on the value of \c err :
                                  * - \c err==0: Message payload length
                                  * - \c err!=0: Error string length */
        void *key;               /**< Depends on the value of \c err :
                                  * - \c err==0: Optional message key */
        size_t key_len;          /**< Depends on the value of \c err :
                                  * - \c err==0: Optional message key length*/
        int64_t offset;          /**< Consumer:
                                  * - Message offset (or offset for error
                                  *   if \c err!=0 if applicable).
                                  *   Producer, dr_msg_cb:
                                  *   Message offset assigned by broker.
                                  *   May be RD_KAFKA_OFFSET_INVALID
                                  *   for retried messages when
                                  *   idempotence is enabled. */
        void *_private;          /**< Consumer:
                                  *  - rdkafka private pointer: DO NOT MODIFY
                                  *  Producer:
                                  *  - dr_msg_cb:
                                  *    msg_opaque from produce() call or
                                  *    RD_KAFKA_V_OPAQUE from producev(). */
} rd_kafka_message_t;

 

typedef struct rd_kafka_q_s rd_kafka_q_t;
typedef struct rd_kafka_toppar_s rd_kafka_toppar_t;
typedef struct rd_kafka_op_s rd_kafka_op_t;

 

/**
 * @struct Queue for rd_kafka_op_t*.
 *
 * @remark All readers of the queue must call rd_kafka_q_mark_served()
 *         after reading the queue (while still holding the queue lock) to
 *         clear the wakeup-sent flag.
 */
struct rd_kafka_q_s {
        mtx_t rkq_lock;
        cnd_t rkq_cond;
        struct rd_kafka_q_s *rkq_fwdq; /* Forwarded/Routed queue.
                                        * Used in place of this queue
                                        * for all operations. */

        struct rd_kafka_op_tailq rkq_q; /* TAILQ_HEAD(, rd_kafka_op_s) */
        int rkq_qlen;                   /* Number of entries in queue */
        int64_t rkq_qsize;              /* Size of all entries in queue */
        int rkq_refcnt;
        int rkq_flags;
#define RD_KAFKA_Q_F_ALLOCATED 0x1 /* Allocated: rd_free on destroy */
#define RD_KAFKA_Q_F_READY                                                     \
        0x2 /* Queue is ready to be used.                                      \
             * Flag is cleared on destroy */
#define RD_KAFKA_Q_F_FWD_APP                                                   \
        0x4 /* Queue is being forwarded by a call                              \
             * to rd_kafka_queue_forward. */
#define RD_KAFKA_Q_F_YIELD                                                     \
        0x8 /* Have waiters return even if                                     \
             * no rko was enqueued.                                            \
             * This is used to wake up a waiter                                \
             * by triggering the cond-var                                      \
             * but without having to enqueue                                   \
             * an op. */

        rd_kafka_t *rkq_rk;
        struct rd_kafka_q_io *rkq_qio; /* FD-based application signalling */

        /* Op serve callback (optional).
         * Mainly used for forwarded queues to use the original queue's
         * serve function from the forwarded position.
         * Shall return 1 if op was handled, else 0. */
        rd_kafka_q_serve_cb_t *rkq_serve;
        void *rkq_opaque;

#if ENABLE_DEVEL
        char rkq_name[64]; /* Debugging: queue name (FUNC:LINE) */
#else
        const char *rkq_name; /* Debugging: queue name (FUNC) */
#endif
};
struct rd_kafka_op_s {
        TAILQ_ENTRY(rd_kafka_op_s) rko_link;

        rd_kafka_op_type_t rko_type; /* Internal op type */
        rd_kafka_event_type_t rko_evtype;
        int rko_flags; /* See RD_KAFKA_OP_F_... above */
        int32_t rko_version;
        rd_kafka_resp_err_t rko_err;
        rd_kafka_error_t *rko_error;
        int32_t rko_len;          /* Depends on type, typically the
                                   * message length. */
        rd_kafka_prio_t rko_prio; /**< In-queue priority.
                                   *   Higher value means higher prio*/

        rd_kafka_toppar_t *rko_rktp;

        /*
         * Generic fields
         */

        /* Indicates request: enqueue reply on rko_replyq.q with .version.
         * .q is refcounted. */
        rd_kafka_replyq_t rko_replyq;

        /* Original queue's op serve callback and opaque, if any.
         * Mainly used for forwarded queues to use the original queue's
         * serve function from the forwarded position. */
        rd_kafka_q_serve_cb_t *rko_serve;
        void *rko_serve_opaque;

        rd_kafka_t *rko_rk;

#if ENABLE_DEVEL
        const char *rko_source; /**< Where op was created */
#endif

        /* RD_KAFKA_OP_CB */
        rd_kafka_op_cb_t *rko_op_cb;

        union {
                struct {
                        rd_kafka_buf_t *rkbuf;
                        rd_kafka_msg_t rkm;
                        int evidx;
                } fetch;

                struct {
                        rd_kafka_topic_partition_list_t *partitions;
                        /** Require stable (txn-commited) offsets */
                        rd_bool_t require_stable;
                        int do_free; /* free .partitions on destroy() */
                } offset_fetch;

                struct {
                        rd_kafka_topic_partition_list_t *partitions;
                        void (*cb)(rd_kafka_t *rk,
                                   rd_kafka_resp_err_t err,
                                   rd_kafka_topic_partition_list_t *offsets,
                                   void *opaque);
                        void *opaque;
                        int silent_empty; /**< Fail silently if there are no
                                           *   offsets to commit. */
                        rd_ts_t ts_timeout;
                        char *reason;
                } offset_commit;

                struct {
                        rd_kafka_topic_partition_list_t *topics;
                } subscribe; /* also used for GET_SUBSCRIPTION */

                struct {
                        rd_kafka_topic_partition_list_t *partitions;
                        rd_kafka_assign_method_t method;
                } assign; /* also used for GET_ASSIGNMENT */

                struct {
                        rd_kafka_topic_partition_list_t *partitions;
                } rebalance;

                struct {
                        const char *str;
                } rebalance_protocol;

                struct {
                        char *str;
                } name;

                rd_kafka_consumer_group_metadata_t *cg_metadata;

                struct {
                        int64_t offset;
                        char *errstr;
                        rd_kafka_msg_t rkm;
                        rd_kafka_topic_t *rkt;
                        int fatal; /**< This was a ERR__FATAL error that has
                                    *   been translated to the fatal error
                                    *   code. */
                } err;             /* used for ERR and CONSUMER_ERR */

                struct {
                        int throttle_time;
                        int32_t nodeid;
                        char *nodename;
                } throttle;

                struct {
                        char *json;
                        size_t json_len;
                } stats;

                struct {
                        rd_kafka_buf_t *rkbuf;
                } xbuf; /* XMIT_BUF and RECV_BUF */

                /* RD_KAFKA_OP_METADATA */
                struct {
                        rd_kafka_metadata_t *md;
                        int force; /* force request regardless of outstanding
                                    * metadata requests. */
                } metadata;

                struct {
                        rd_kafka_topic_t *rkt;
                        rd_kafka_msgq_t msgq;
                        rd_kafka_msgq_t msgq2;
                        int do_purge2;
                } dr;

                struct {
                        int32_t nodeid;
                        char nodename[RD_KAFKA_NODENAME_SIZE];
                } node;

                struct {
                        int64_t offset;
                        char *reason;
                } offset_reset;

                struct {
                        int64_t offset;
                        struct rd_kafka_cgrp_s *rkcg;
                } fetch_start; /* reused for SEEK */

                struct {
                        int pause;
                        int flag;
                } pause;

                struct {
                        char fac[64];
                        int level;
                        char *str;
                        int ctx;
                } log;

                struct {
                        rd_kafka_AdminOptions_t options;   /**< Copy of user's
                                                            * options */
                        rd_ts_t abs_timeout;               /**< Absolute timeout
                                                            *   for this request. */
                        rd_kafka_timer_t tmr;              /**< Timeout timer */
                        struct rd_kafka_enq_once_s *eonce; /**< Enqueue op
                                                            * only once,
                                                            * used to
                                                            * (re)trigger
                                                            * the request op
                                                            * upon broker state
                                                            * changes while
                                                            * waiting for the
                                                            * controller, or
                                                            * due to .tmr
                                                            * timeout. */
                        rd_list_t
                            args; /**< Type depends on request, e.g.
                                   *   rd_kafka_NewTopic_t for CreateTopics
                                   */

                        rd_kafka_buf_t *reply_buf; /**< Protocol reply,
                                                    *   temporary reference not
                                                    *   owned by this rko */

                        /**< Worker callbacks, see rdkafka_admin.c */
                        struct rd_kafka_admin_worker_cbs *cbs;

                        /** Worker state */
                        enum { RD_KAFKA_ADMIN_STATE_INIT,
                               RD_KAFKA_ADMIN_STATE_WAIT_BROKER,
                               RD_KAFKA_ADMIN_STATE_WAIT_CONTROLLER,
                               RD_KAFKA_ADMIN_STATE_WAIT_FANOUTS,
                               RD_KAFKA_ADMIN_STATE_CONSTRUCT_REQUEST,
                               RD_KAFKA_ADMIN_STATE_WAIT_RESPONSE,
                        } state;

                        int32_t broker_id; /**< Requested broker id to
                                            *   communicate with.
                                            *   Used for AlterConfigs, et.al,
                                            *   that needs to speak to a
                                            *   specific broker rather than
                                            *   the controller.
                                            *   See RD_KAFKA_ADMIN_TARGET_..
                                            *   for special values (coordinator,
                                            *   fanout, etc).
                                            */
                        /** The type of coordinator to look up */
                        rd_kafka_coordtype_t coordtype;
                        /** Which coordinator to look up */
                        char *coordkey;

                        /** Application's reply queue */
                        rd_kafka_replyq_t replyq;
                        rd_kafka_event_type_t reply_event_type;

                        /** A collection of fanout child ops. */
                        struct {
                                /** The type of request being fanned out.
                                 *  This is used for the ADMIN_RESULT. */
                                rd_kafka_op_type_t reqtype;

                                /** Worker callbacks, see rdkafka_admin.c */
                                struct rd_kafka_admin_fanout_worker_cbs *cbs;

                                /** Number of outstanding requests remaining to
                                 *  wait for. */
                                int outstanding;

                                /** Incremental results from fanouts.
                                 *  This list is pre-allocated to the number
                                 *  of input objects and can thus be set
                                 *  by index to retain original ordering. */
                                rd_list_t results;

                                /** Reply event type */
                                rd_kafka_event_type_t reply_event_type;

                        } fanout;

                        /** A reference to the parent ADMIN_FANOUT op that
                         *  spawned this op, if applicable. NULL otherwise. */
                        struct rd_kafka_op_s *fanout_parent;

                } admin_request;

                struct {
                        rd_kafka_op_type_t reqtype; /**< Request op type,
                                                     *   used for logging. */

                        rd_list_t args; /**< Args moved from the request op
                                         *   when the result op is created.
                                         *
                                         *   Type depends on request.
                                         */

                        char *errstr; /**< Error string, if rko_err
                                       *   is set, else NULL. */

                        rd_list_t results; /**< Type depends on request type:
                                            *
                                            * (rd_kafka_topic_result_t *):
                                            * CreateTopics, DeleteTopics,
                                            * CreatePartitions.
                                            *
                                            * (rd_kafka_ConfigResource_t *):
                                            * AlterConfigs, DescribeConfigs
                                            */

                        void *opaque; /**< Application's opaque as set by
                                       *   rd_kafka_AdminOptions_set_opaque
                                       */

                        /** A reference to the parent ADMIN_FANOUT op that
                         *  spawned this op, if applicable. NULL otherwise. */
                        struct rd_kafka_op_s *fanout_parent;
                } admin_result;

                struct {
                        int flags; /**< purge_flags from rd_kafka_purge() */
                } purge;

                /**< Mock cluster command */
                struct {
                        enum { RD_KAFKA_MOCK_CMD_TOPIC_SET_ERROR,
                               RD_KAFKA_MOCK_CMD_TOPIC_CREATE,
                               RD_KAFKA_MOCK_CMD_PART_SET_LEADER,
                               RD_KAFKA_MOCK_CMD_PART_SET_FOLLOWER,
                               RD_KAFKA_MOCK_CMD_PART_SET_FOLLOWER_WMARKS,
                               RD_KAFKA_MOCK_CMD_BROKER_SET_UPDOWN,
                               RD_KAFKA_MOCK_CMD_BROKER_SET_RTT,
                               RD_KAFKA_MOCK_CMD_BROKER_SET_RACK,
                               RD_KAFKA_MOCK_CMD_COORD_SET,
                               RD_KAFKA_MOCK_CMD_APIVERSION_SET,
                        } cmd;

                        rd_kafka_resp_err_t err; /**< Error for:
                                                  *    TOPIC_SET_ERROR */
                        char *name;              /**< For:
                                                  *    TOPIC_SET_ERROR
                                                  *    TOPIC_CREATE
                                                  *    PART_SET_FOLLOWER
                                                  *    PART_SET_FOLLOWER_WMARKS
                                                  *    BROKER_SET_RACK
                                                  *    COORD_SET (key_type) */
                        char *str;               /**< For:
                                                  *    COORD_SET (key) */
                        int32_t partition;       /**< For:
                                                  *    PART_SET_FOLLOWER
                                                  *    PART_SET_FOLLOWER_WMARKS
                                                  *    PART_SET_LEADER
                                                  *    APIVERSION_SET (ApiKey)
                                                  */
                        int32_t broker_id;       /**< For:
                                                  *    PART_SET_FOLLOWER
                                                  *    PART_SET_LEADER
                                                  *    BROKER_SET_UPDOWN
                                                  *    BROKER_SET_RACK
                                                  *    COORD_SET */
                        int64_t lo;              /**< Low offset, for:
                                                  *    TOPIC_CREATE (part cnt)
                                                  *    PART_SET_FOLLOWER_WMARKS
                                                  *    BROKER_SET_UPDOWN
                                                  *    APIVERSION_SET (minver)
                                                  *    BROKER_SET_RTT
                                                  */
                        int64_t hi;              /**< High offset, for:
                                                  *    TOPIC_CREATE (repl fact)
                                                  *    PART_SET_FOLLOWER_WMARKS
                                                  *    APIVERSION_SET (maxver)
                                                  */
                } mock;

                struct {
                        struct rd_kafka_broker_s *rkb; /**< Broker who's state
                                                        *   changed. */
                        /**< Callback to trigger on the op handler's thread. */
                        void (*cb)(struct rd_kafka_broker_s *rkb);
                } broker_monitor;

                struct {
                        /** Consumer group metadata for send_offsets_to.. */
                        rd_kafka_consumer_group_metadata_t *cgmetadata;
                        /** Consumer group id for AddOffsetsTo.. */
                        char *group_id;
                        int timeout_ms;      /**< Operation timeout */
                        rd_ts_t abs_timeout; /**< Absolute time */
                        /**< Offsets to commit */
                        rd_kafka_topic_partition_list_t *offsets;
                } txn;

                struct {
                        /* This struct serves two purposes, the fields
                         * with "Request:" are used for the async workers state
                         * while the "Reply:" fields is a separate reply
                         * rko that is enqueued for the caller upon
                         * completion or failure. */

                        /** Request: Partitions to query.
                         *  Reply:   Queried partitions with .err field set. */
                        rd_kafka_topic_partition_list_t *partitions;

                        /** Request: Absolute timeout */
                        rd_ts_t ts_timeout;

                        /** Request: Metadata query timer */
                        rd_kafka_timer_t query_tmr;

                        /** Request: Timeout timer */
                        rd_kafka_timer_t timeout_tmr;

                        /** Request: Enqueue op only once, used to (re)trigger
                         *  metadata cache lookups, topic refresh, timeout. */
                        struct rd_kafka_enq_once_s *eonce;

                        /** Request: Caller's replyq */
                        rd_kafka_replyq_t replyq;

                        /** Request: Number of metadata queries made. */
                        int query_cnt;

                        /** Reply: Leaders (result)
                         * (rd_kafka_partition_leader*) */
                        rd_list_t *leaders;

                        /** Reply: Callback on completion (or failure) */
                        rd_kafka_op_cb_t *cb;

                        /** Reply: Callback opaque */
                        void *opaque;

                } leaders;

        } rko_u;
};

 

posted @ 2022-03-17 15:26  Aemnprsu_wx  阅读(327)  评论(0编辑  收藏  举报