karafka-rdkafka 0.30.2-aarch64-linux-gnu → 0.32.0-aarch64-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +100 -36
- data/README.md +3 -1
- data/docker-compose-ssl.yml +1 -0
- data/docker-compose.yml +1 -0
- data/ext/librdkafka.so +0 -0
- data/karafka-rdkafka.gemspec +5 -4
- data/lib/rdkafka/admin/acl_binding_result.rb +4 -16
- data/lib/rdkafka/admin/alter_consumer_group_offsets_report.rb +2 -2
- data/lib/rdkafka/admin/create_acl_report.rb +1 -3
- data/lib/rdkafka/admin/create_topic_report.rb +2 -6
- data/lib/rdkafka/admin/delete_consumer_group_offsets_report.rb +2 -2
- data/lib/rdkafka/admin/delete_groups_report.rb +2 -6
- data/lib/rdkafka/admin/delete_topic_report.rb +2 -6
- data/lib/rdkafka/admin/describe_cluster_handle.rb +31 -0
- data/lib/rdkafka/admin/describe_cluster_report.rb +51 -0
- data/lib/rdkafka/admin/describe_consumer_groups_handle.rb +31 -0
- data/lib/rdkafka/admin/describe_consumer_groups_report.rb +151 -0
- data/lib/rdkafka/admin/describe_result_parsing.rb +47 -0
- data/lib/rdkafka/admin/describe_topics_handle.rb +31 -0
- data/lib/rdkafka/admin/describe_topics_report.rb +118 -0
- data/lib/rdkafka/admin/list_consumer_group_offsets_handle.rb +31 -0
- data/lib/rdkafka/admin/list_consumer_group_offsets_report.rb +52 -0
- data/lib/rdkafka/admin.rb +424 -9
- data/lib/rdkafka/bindings/admin/acls.rb +85 -0
- data/lib/rdkafka/bindings/admin/configs.rb +37 -0
- data/lib/rdkafka/bindings/admin/list_offsets.rb +26 -0
- data/lib/rdkafka/bindings/admin.rb +211 -0
- data/lib/rdkafka/bindings/callbacks.rb +155 -0
- data/lib/rdkafka/bindings/configuration.rb +50 -0
- data/lib/rdkafka/bindings/consumer.rb +125 -0
- data/lib/rdkafka/bindings/errors.rb +17 -0
- data/lib/rdkafka/bindings/handle.rb +16 -0
- data/lib/rdkafka/bindings/messages.rb +28 -0
- data/lib/rdkafka/bindings/metadata.rb +17 -0
- data/lib/rdkafka/bindings/polling.rb +17 -0
- data/lib/rdkafka/bindings/producer.rb +82 -0
- data/lib/rdkafka/bindings/share_consumer.rb +67 -0
- data/lib/rdkafka/bindings/structs.rb +62 -0
- data/lib/rdkafka/bindings.rb +16 -775
- data/lib/rdkafka/callbacks/describe_cluster_handler.rb +36 -0
- data/lib/rdkafka/callbacks/describe_consumer_groups_handler.rb +36 -0
- data/lib/rdkafka/callbacks/describe_topics_handler.rb +36 -0
- data/lib/rdkafka/callbacks/list_consumer_group_offsets_handler.rb +62 -0
- data/lib/rdkafka/callbacks.rb +15 -7
- data/lib/rdkafka/clients.rb +13 -46
- data/lib/rdkafka/config.rb +70 -0
- data/lib/rdkafka/consumer/allocator.rb +0 -2
- data/lib/rdkafka/consumer/message.rb +6 -9
- data/lib/rdkafka/consumer/topic_partition_list.rb +7 -7
- data/lib/rdkafka/consumer.rb +76 -36
- data/lib/rdkafka/defaults.rb +6 -4
- data/lib/rdkafka/native_kafka.rb +45 -31
- data/lib/rdkafka/producer/delivery_handle.rb +18 -16
- data/lib/rdkafka/producer/delivery_report.rb +51 -1
- data/lib/rdkafka/producer/partitions_count_cache.rb +109 -26
- data/lib/rdkafka/producer.rb +141 -71
- data/lib/rdkafka/share_consumer.rb +70 -34
- data/lib/rdkafka/version.rb +3 -3
- data/lib/rdkafka.rb +14 -1
- data/package-lock.json +9 -9
- data/renovate.json +7 -0
- metadata +31 -31
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# List Offsets
|
|
6
|
+
RD_KAFKA_ADMIN_OP_LISTOFFSETS = 21
|
|
7
|
+
RD_KAFKA_EVENT_LISTOFFSETS_RESULT = 0x400000
|
|
8
|
+
|
|
9
|
+
# rd_kafka_IsolationLevel_t
|
|
10
|
+
RD_KAFKA_ISOLATION_LEVEL_READ_UNCOMMITTED = 0
|
|
11
|
+
RD_KAFKA_ISOLATION_LEVEL_READ_COMMITTED = 1
|
|
12
|
+
|
|
13
|
+
# rd_kafka_OffsetSpec_t
|
|
14
|
+
RD_KAFKA_OFFSET_SPEC_MAX_TIMESTAMP = -3
|
|
15
|
+
RD_KAFKA_OFFSET_SPEC_EARLIEST = -2
|
|
16
|
+
RD_KAFKA_OFFSET_SPEC_LATEST = -1
|
|
17
|
+
|
|
18
|
+
attach_function :rd_kafka_ListOffsets, [:pointer, :pointer, :pointer, :pointer], :void, blocking: true
|
|
19
|
+
attach_function :rd_kafka_event_ListOffsets_result, [:pointer], :pointer
|
|
20
|
+
attach_function :rd_kafka_ListOffsets_result_infos, [:pointer, :pointer], :pointer
|
|
21
|
+
attach_function :rd_kafka_ListOffsetsResultInfo_topic_partition, [:pointer], :pointer
|
|
22
|
+
attach_function :rd_kafka_ListOffsetsResultInfo_timestamp, [:pointer], :int64
|
|
23
|
+
attach_function :rd_kafka_AdminOptions_set_isolation_level, [:pointer, :int], :pointer
|
|
24
|
+
attach_function :rd_kafka_topic_partition_get_leader_epoch, [:pointer], :int32
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Create Topics
|
|
6
|
+
RD_KAFKA_ADMIN_OP_CREATETOPICS = 1 # rd_kafka_admin_op_t
|
|
7
|
+
RD_KAFKA_EVENT_CREATETOPICS_RESULT = 100 # rd_kafka_event_type_t
|
|
8
|
+
|
|
9
|
+
attach_function :rd_kafka_CreateTopics, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
10
|
+
attach_function :rd_kafka_NewTopic_new, [:pointer, :size_t, :size_t, :pointer, :size_t], :pointer, blocking: true
|
|
11
|
+
attach_function :rd_kafka_NewTopic_set_config, [:pointer, :string, :string], :int32, blocking: true
|
|
12
|
+
attach_function :rd_kafka_NewTopic_destroy, [:pointer], :void, blocking: true
|
|
13
|
+
attach_function :rd_kafka_event_CreateTopics_result, [:pointer], :pointer, blocking: true
|
|
14
|
+
attach_function :rd_kafka_CreateTopics_result_topics, [:pointer, :pointer], :pointer, blocking: true
|
|
15
|
+
|
|
16
|
+
# Delete Topics
|
|
17
|
+
RD_KAFKA_ADMIN_OP_DELETETOPICS = 2 # rd_kafka_admin_op_t
|
|
18
|
+
RD_KAFKA_EVENT_DELETETOPICS_RESULT = 101 # rd_kafka_event_type_t
|
|
19
|
+
|
|
20
|
+
attach_function :rd_kafka_DeleteTopics, [:pointer, :pointer, :size_t, :pointer, :pointer], :int32, blocking: true
|
|
21
|
+
attach_function :rd_kafka_DeleteTopic_new, [:pointer], :pointer, blocking: true
|
|
22
|
+
attach_function :rd_kafka_DeleteTopic_destroy, [:pointer], :void, blocking: true
|
|
23
|
+
attach_function :rd_kafka_event_DeleteTopics_result, [:pointer], :pointer, blocking: true
|
|
24
|
+
attach_function :rd_kafka_DeleteTopics_result_topics, [:pointer, :pointer], :pointer, blocking: true
|
|
25
|
+
|
|
26
|
+
# Create partitions
|
|
27
|
+
RD_KAFKA_ADMIN_OP_CREATEPARTITIONS = 3
|
|
28
|
+
RD_KAFKA_ADMIN_OP_CREATEPARTITIONS_RESULT = 102
|
|
29
|
+
|
|
30
|
+
attach_function :rd_kafka_CreatePartitions, [:pointer, :pointer, :size_t, :pointer, :pointer], :void
|
|
31
|
+
attach_function :rd_kafka_NewPartitions_new, %i[pointer size_t pointer size_t], :pointer
|
|
32
|
+
attach_function :rd_kafka_NewPartitions_destroy, [:pointer], :void
|
|
33
|
+
attach_function :rd_kafka_event_CreatePartitions_result, [:pointer], :pointer
|
|
34
|
+
attach_function :rd_kafka_CreatePartitions_result_topics, [:pointer, :pointer], :pointer
|
|
35
|
+
|
|
36
|
+
# Delete Group
|
|
37
|
+
RD_KAFKA_ADMIN_OP_DELETEGROUPS = 7 # rd_kafka_admin_op_t
|
|
38
|
+
RD_KAFKA_EVENT_DELETEGROUPS_RESULT = 106 # rd_kafka_event_type_t
|
|
39
|
+
|
|
40
|
+
attach_function :rd_kafka_DeleteGroups, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
41
|
+
attach_function :rd_kafka_DeleteGroup_new, [:pointer], :pointer, blocking: true
|
|
42
|
+
attach_function :rd_kafka_DeleteGroup_destroy, [:pointer], :void, blocking: true
|
|
43
|
+
attach_function :rd_kafka_event_DeleteGroups_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DeleteGroups_result_t*
|
|
44
|
+
attach_function :rd_kafka_DeleteGroups_result_groups, [:pointer, :pointer], :pointer, blocking: true # rd_kafka_DeleteGroups_result_t*, size_t* => rd_kafka_group_result_t**
|
|
45
|
+
|
|
46
|
+
# Alter Consumer Group Offsets
|
|
47
|
+
RD_KAFKA_ADMIN_OP_ALTERCONSUMERGROUPOFFSETS = 15 # rd_kafka_admin_op_t
|
|
48
|
+
RD_KAFKA_EVENT_ALTERCONSUMERGROUPOFFSETS_RESULT = 0x10000 # rd_kafka_event_type_t
|
|
49
|
+
|
|
50
|
+
attach_function :rd_kafka_AlterConsumerGroupOffsets, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
51
|
+
attach_function :rd_kafka_AlterConsumerGroupOffsets_new, [:pointer, :pointer], :pointer, blocking: true # const char*, const rd_kafka_topic_partition_list_t* => rd_kafka_AlterConsumerGroupOffsets_t*
|
|
52
|
+
attach_function :rd_kafka_AlterConsumerGroupOffsets_destroy, [:pointer], :void, blocking: true
|
|
53
|
+
attach_function :rd_kafka_event_AlterConsumerGroupOffsets_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_AlterConsumerGroupOffsets_result_t*
|
|
54
|
+
attach_function :rd_kafka_AlterConsumerGroupOffsets_result_groups, [:pointer, :pointer], :pointer, blocking: true # rd_kafka_AlterConsumerGroupOffsets_result_t*, size_t* => rd_kafka_group_result_t**
|
|
55
|
+
|
|
56
|
+
# List Consumer Group Offsets
|
|
57
|
+
RD_KAFKA_ADMIN_OP_LISTCONSUMERGROUPOFFSETS = 14 # rd_kafka_admin_op_t
|
|
58
|
+
RD_KAFKA_EVENT_LISTCONSUMERGROUPOFFSETS_RESULT = 0x8000 # rd_kafka_event_type_t
|
|
59
|
+
|
|
60
|
+
attach_function :rd_kafka_ListConsumerGroupOffsets, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
61
|
+
attach_function :rd_kafka_ListConsumerGroupOffsets_new, [:pointer, :pointer], :pointer, blocking: true # const char*, const rd_kafka_topic_partition_list_t* => rd_kafka_ListConsumerGroupOffsets_t*
|
|
62
|
+
attach_function :rd_kafka_ListConsumerGroupOffsets_destroy, [:pointer], :void, blocking: true
|
|
63
|
+
attach_function :rd_kafka_event_ListConsumerGroupOffsets_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_ListConsumerGroupOffsets_result_t*
|
|
64
|
+
attach_function :rd_kafka_ListConsumerGroupOffsets_result_groups, [:pointer, :pointer], :pointer, blocking: true # rd_kafka_ListConsumerGroupOffsets_result_t*, size_t* => rd_kafka_group_result_t**
|
|
65
|
+
attach_function :rd_kafka_AdminOptions_set_require_stable_offsets, [:pointer, :int], :pointer, blocking: true # => rd_kafka_error_t*
|
|
66
|
+
|
|
67
|
+
# Delete Consumer Group Offsets
|
|
68
|
+
RD_KAFKA_ADMIN_OP_DELETECONSUMERGROUPOFFSETS = 8 # rd_kafka_admin_op_t
|
|
69
|
+
RD_KAFKA_EVENT_DELETECONSUMERGROUPOFFSETS_RESULT = 107 # rd_kafka_event_type_t
|
|
70
|
+
|
|
71
|
+
attach_function :rd_kafka_DeleteConsumerGroupOffsets, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
72
|
+
attach_function :rd_kafka_DeleteConsumerGroupOffsets_new, [:pointer, :pointer], :pointer, blocking: true # const char*, const rd_kafka_topic_partition_list_t* => rd_kafka_DeleteConsumerGroupOffsets_t*
|
|
73
|
+
attach_function :rd_kafka_DeleteConsumerGroupOffsets_destroy, [:pointer], :void, blocking: true
|
|
74
|
+
attach_function :rd_kafka_event_DeleteConsumerGroupOffsets_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DeleteConsumerGroupOffsets_result_t*
|
|
75
|
+
attach_function :rd_kafka_DeleteConsumerGroupOffsets_result_groups, [:pointer, :pointer], :pointer, blocking: true # rd_kafka_DeleteConsumerGroupOffsets_result_t*, size_t* => rd_kafka_group_result_t**
|
|
76
|
+
|
|
77
|
+
# Delete Records
|
|
78
|
+
RD_KAFKA_ADMIN_OP_DELETERECORDS = 6 # rd_kafka_admin_op_t
|
|
79
|
+
RD_KAFKA_EVENT_DELETERECORDS_RESULT = 105 # rd_kafka_event_type_t
|
|
80
|
+
|
|
81
|
+
attach_function :rd_kafka_DeleteRecords, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
82
|
+
attach_function :rd_kafka_DeleteRecords_new, [:pointer], :pointer, blocking: true
|
|
83
|
+
attach_function :rd_kafka_DeleteRecords_destroy, [:pointer], :void, blocking: true
|
|
84
|
+
attach_function :rd_kafka_event_DeleteRecords_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DeleteRecords_result_t*
|
|
85
|
+
attach_function :rd_kafka_DeleteRecords_result_offsets, [:pointer], :pointer, blocking: true # rd_kafka_DeleteRecords_result_t* => rd_kafka_topic_partition_list_t*
|
|
86
|
+
|
|
87
|
+
# List Consumer Groups
|
|
88
|
+
RD_KAFKA_ADMIN_OP_LISTCONSUMERGROUPS = 12 # rd_kafka_admin_op_t
|
|
89
|
+
RD_KAFKA_EVENT_LISTCONSUMERGROUPS_RESULT = 0x2000 # rd_kafka_event_type_t
|
|
90
|
+
|
|
91
|
+
# Consumer group states (rd_kafka_consumer_group_state_t)
|
|
92
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_UNKNOWN = 0
|
|
93
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_PREPARING_REBALANCE = 1
|
|
94
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_COMPLETING_REBALANCE = 2
|
|
95
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_STABLE = 3
|
|
96
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_DEAD = 4
|
|
97
|
+
RD_KAFKA_CONSUMER_GROUP_STATE_EMPTY = 5
|
|
98
|
+
|
|
99
|
+
attach_function :rd_kafka_ListConsumerGroups, [:pointer, :pointer, :pointer], :void, blocking: true
|
|
100
|
+
attach_function :rd_kafka_event_ListConsumerGroups_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_ListConsumerGroups_result_t*
|
|
101
|
+
attach_function :rd_kafka_ListConsumerGroups_result_valid, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_ConsumerGroupListing_t**
|
|
102
|
+
attach_function :rd_kafka_ListConsumerGroups_result_errors, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_error_t**
|
|
103
|
+
attach_function :rd_kafka_ConsumerGroupListing_group_id, [:pointer], :pointer, blocking: true # => const char*
|
|
104
|
+
attach_function :rd_kafka_ConsumerGroupListing_is_simple_consumer_group, [:pointer], :int, blocking: true
|
|
105
|
+
attach_function :rd_kafka_ConsumerGroupListing_state, [:pointer], :int, blocking: true
|
|
106
|
+
attach_function :rd_kafka_consumer_group_state_name, [:int], :pointer, blocking: true # => const char*
|
|
107
|
+
|
|
108
|
+
# Describe Consumer Groups
|
|
109
|
+
RD_KAFKA_ADMIN_OP_DESCRIBECONSUMERGROUPS = 13 # rd_kafka_admin_op_t
|
|
110
|
+
RD_KAFKA_EVENT_DESCRIBECONSUMERGROUPS_RESULT = 0x4000 # rd_kafka_event_type_t
|
|
111
|
+
|
|
112
|
+
# Consumer group types (rd_kafka_consumer_group_type_t)
|
|
113
|
+
RD_KAFKA_CONSUMER_GROUP_TYPE_UNKNOWN = 0
|
|
114
|
+
RD_KAFKA_CONSUMER_GROUP_TYPE_CONSUMER = 1
|
|
115
|
+
RD_KAFKA_CONSUMER_GROUP_TYPE_CLASSIC = 2
|
|
116
|
+
|
|
117
|
+
attach_function :rd_kafka_DescribeConsumerGroups, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
|
118
|
+
attach_function :rd_kafka_event_DescribeConsumerGroups_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DescribeConsumerGroups_result_t*
|
|
119
|
+
attach_function :rd_kafka_DescribeConsumerGroups_result_groups, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_ConsumerGroupDescription_t**
|
|
120
|
+
attach_function :rd_kafka_ConsumerGroupDescription_group_id, [:pointer], :pointer, blocking: true # => const char*
|
|
121
|
+
attach_function :rd_kafka_ConsumerGroupDescription_error, [:pointer], :pointer, blocking: true # => const rd_kafka_error_t*
|
|
122
|
+
attach_function :rd_kafka_ConsumerGroupDescription_is_simple_consumer_group, [:pointer], :int, blocking: true
|
|
123
|
+
attach_function :rd_kafka_ConsumerGroupDescription_partition_assignor, [:pointer], :pointer, blocking: true # => const char*
|
|
124
|
+
attach_function :rd_kafka_ConsumerGroupDescription_state, [:pointer], :int, blocking: true
|
|
125
|
+
attach_function :rd_kafka_ConsumerGroupDescription_type, [:pointer], :int, blocking: true
|
|
126
|
+
attach_function :rd_kafka_ConsumerGroupDescription_authorized_operations, [:pointer, :pointer], :pointer, blocking: true # grpdesc*, size_t* => const rd_kafka_AclOperation_t*
|
|
127
|
+
attach_function :rd_kafka_ConsumerGroupDescription_coordinator, [:pointer], :pointer, blocking: true # => const rd_kafka_Node_t*
|
|
128
|
+
attach_function :rd_kafka_ConsumerGroupDescription_member_count, [:pointer], :size_t, blocking: true
|
|
129
|
+
attach_function :rd_kafka_ConsumerGroupDescription_member, [:pointer, :size_t], :pointer, blocking: true # => const rd_kafka_MemberDescription_t*
|
|
130
|
+
attach_function :rd_kafka_MemberDescription_client_id, [:pointer], :pointer, blocking: true # => const char*
|
|
131
|
+
attach_function :rd_kafka_MemberDescription_group_instance_id, [:pointer], :pointer, blocking: true # => const char*
|
|
132
|
+
attach_function :rd_kafka_MemberDescription_consumer_id, [:pointer], :pointer, blocking: true # => const char*
|
|
133
|
+
attach_function :rd_kafka_MemberDescription_host, [:pointer], :pointer, blocking: true # => const char*
|
|
134
|
+
attach_function :rd_kafka_MemberDescription_assignment, [:pointer], :pointer, blocking: true # => const rd_kafka_MemberAssignment_t*
|
|
135
|
+
attach_function :rd_kafka_MemberDescription_target_assignment, [:pointer], :pointer, blocking: true # => const rd_kafka_MemberAssignment_t*
|
|
136
|
+
attach_function :rd_kafka_MemberAssignment_partitions, [:pointer], :pointer, blocking: true # => const rd_kafka_topic_partition_list_t*
|
|
137
|
+
attach_function :rd_kafka_consumer_group_type_name, [:int], :pointer, blocking: true # => const char*
|
|
138
|
+
|
|
139
|
+
# Describe Topics and Describe Cluster
|
|
140
|
+
RD_KAFKA_ADMIN_OP_DESCRIBETOPICS = 19 # rd_kafka_admin_op_t
|
|
141
|
+
RD_KAFKA_EVENT_DESCRIBETOPICS_RESULT = 0x100000 # rd_kafka_event_type_t
|
|
142
|
+
RD_KAFKA_ADMIN_OP_DESCRIBECLUSTER = 20 # rd_kafka_admin_op_t
|
|
143
|
+
RD_KAFKA_EVENT_DESCRIBECLUSTER_RESULT = 0x200000 # rd_kafka_event_type_t
|
|
144
|
+
|
|
145
|
+
attach_function :rd_kafka_AdminOptions_set_include_authorized_operations, [:pointer, :int], :pointer, blocking: true # => rd_kafka_error_t*
|
|
146
|
+
attach_function :rd_kafka_TopicCollection_of_topic_names, [:pointer, :size_t], :pointer, blocking: true # const char**, size_t => rd_kafka_TopicCollection_t*
|
|
147
|
+
attach_function :rd_kafka_TopicCollection_destroy, [:pointer], :void, blocking: true
|
|
148
|
+
attach_function :rd_kafka_DescribeTopics, [:pointer, :pointer, :pointer, :pointer], :void, blocking: true
|
|
149
|
+
attach_function :rd_kafka_event_DescribeTopics_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DescribeTopics_result_t*
|
|
150
|
+
attach_function :rd_kafka_DescribeTopics_result_topics, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_TopicDescription_t**
|
|
151
|
+
attach_function :rd_kafka_TopicDescription_name, [:pointer], :pointer, blocking: true # => const char*
|
|
152
|
+
attach_function :rd_kafka_TopicDescription_topic_id, [:pointer], :pointer, blocking: true # => rd_kafka_Uuid_t*
|
|
153
|
+
attach_function :rd_kafka_TopicDescription_is_internal, [:pointer], :int, blocking: true
|
|
154
|
+
attach_function :rd_kafka_TopicDescription_partitions, [:pointer, :pointer], :pointer, blocking: true # desc*, size_t* => rd_kafka_TopicPartitionInfo_t**
|
|
155
|
+
attach_function :rd_kafka_TopicDescription_authorized_operations, [:pointer, :pointer], :pointer, blocking: true # desc*, size_t* => rd_kafka_AclOperation_t*
|
|
156
|
+
attach_function :rd_kafka_TopicDescription_error, [:pointer], :pointer, blocking: true # => rd_kafka_error_t*
|
|
157
|
+
attach_function :rd_kafka_TopicPartitionInfo_partition, [:pointer], :int, blocking: true
|
|
158
|
+
attach_function :rd_kafka_TopicPartitionInfo_leader, [:pointer], :pointer, blocking: true # => rd_kafka_Node_t*
|
|
159
|
+
attach_function :rd_kafka_TopicPartitionInfo_replicas, [:pointer, :pointer], :pointer, blocking: true # info*, size_t* => rd_kafka_Node_t**
|
|
160
|
+
attach_function :rd_kafka_TopicPartitionInfo_isr, [:pointer, :pointer], :pointer, blocking: true # info*, size_t* => rd_kafka_Node_t**
|
|
161
|
+
attach_function :rd_kafka_Uuid_base64str, [:pointer], :pointer, blocking: true # => const char*
|
|
162
|
+
attach_function :rd_kafka_Uuid_most_significant_bits, [:pointer], :int64, blocking: true
|
|
163
|
+
attach_function :rd_kafka_Uuid_least_significant_bits, [:pointer], :int64, blocking: true
|
|
164
|
+
attach_function :rd_kafka_DescribeCluster, [:pointer, :pointer, :pointer], :void, blocking: true
|
|
165
|
+
attach_function :rd_kafka_event_DescribeCluster_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DescribeCluster_result_t*
|
|
166
|
+
attach_function :rd_kafka_DescribeCluster_result_nodes, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_Node_t**
|
|
167
|
+
attach_function :rd_kafka_DescribeCluster_result_controller, [:pointer], :pointer, blocking: true # => rd_kafka_Node_t*
|
|
168
|
+
attach_function :rd_kafka_DescribeCluster_result_cluster_id, [:pointer], :pointer, blocking: true # => const char*
|
|
169
|
+
attach_function :rd_kafka_DescribeCluster_result_authorized_operations, [:pointer, :pointer], :pointer, blocking: true # result*, size_t* => rd_kafka_AclOperation_t*
|
|
170
|
+
attach_function :rd_kafka_Node_id, [:pointer], :int, blocking: true
|
|
171
|
+
attach_function :rd_kafka_Node_host, [:pointer], :pointer, blocking: true # => const char*
|
|
172
|
+
attach_function :rd_kafka_Node_port, [:pointer], :uint16, blocking: true
|
|
173
|
+
attach_function :rd_kafka_Node_rack, [:pointer], :pointer, blocking: true # => const char*
|
|
174
|
+
|
|
175
|
+
# Background Queue and Callback
|
|
176
|
+
|
|
177
|
+
attach_function :rd_kafka_conf_set_background_event_cb, [:pointer, :pointer], :void
|
|
178
|
+
attach_function :rd_kafka_queue_destroy, [:pointer], :void
|
|
179
|
+
|
|
180
|
+
# Admin Options
|
|
181
|
+
|
|
182
|
+
attach_function :rd_kafka_AdminOptions_new, [:pointer, :int32], :pointer
|
|
183
|
+
attach_function :rd_kafka_AdminOptions_set_opaque, [:pointer, :pointer], :void
|
|
184
|
+
attach_function :rd_kafka_AdminOptions_destroy, [:pointer], :void
|
|
185
|
+
attach_function :rd_kafka_AdminOptions_set_request_timeout, [:pointer, :int, :pointer, :size_t], :int32
|
|
186
|
+
attach_function :rd_kafka_AdminOptions_set_operation_timeout, [:pointer, :int, :pointer, :size_t], :int32
|
|
187
|
+
attach_function :rd_kafka_AdminOptions_set_validate_only, [:pointer, :int, :pointer, :size_t], :int32
|
|
188
|
+
|
|
189
|
+
# Extracting data from event types
|
|
190
|
+
|
|
191
|
+
attach_function :rd_kafka_event_type, [:pointer], :int32
|
|
192
|
+
attach_function :rd_kafka_event_opaque, [:pointer], :pointer
|
|
193
|
+
attach_function :rd_kafka_event_destroy, [:pointer], :void
|
|
194
|
+
attach_function :rd_kafka_event_error, [:pointer], :int32
|
|
195
|
+
attach_function :rd_kafka_event_error_string, [:pointer], :pointer
|
|
196
|
+
|
|
197
|
+
# Extracting data from topic results
|
|
198
|
+
|
|
199
|
+
attach_function :rd_kafka_topic_result_error, [:pointer], :int32
|
|
200
|
+
attach_function :rd_kafka_topic_result_error_string, [:pointer], :pointer
|
|
201
|
+
attach_function :rd_kafka_topic_result_name, [:pointer], :pointer
|
|
202
|
+
|
|
203
|
+
attach_function :rd_kafka_group_result_error, [:pointer], NativeError.by_ref # rd_kafka_group_result_t* => rd_kafka_error_t*
|
|
204
|
+
attach_function :rd_kafka_group_result_name, [:pointer], :pointer
|
|
205
|
+
attach_function :rd_kafka_group_result_partitions, [:pointer], :pointer # rd_kafka_group_result_t* => rd_kafka_topic_partition_list_t*
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
require_relative "admin/configs"
|
|
210
|
+
require_relative "admin/list_offsets"
|
|
211
|
+
require_relative "admin/acls"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
LogCallback = FFI::Function.new(
|
|
6
|
+
:void, [:pointer, :int, :string, :string]
|
|
7
|
+
) do |_client_ptr, level, _level_string, line|
|
|
8
|
+
severity = case level
|
|
9
|
+
when 0, 1, 2
|
|
10
|
+
Logger::FATAL
|
|
11
|
+
when 3
|
|
12
|
+
Logger::ERROR
|
|
13
|
+
when 4
|
|
14
|
+
Logger::WARN
|
|
15
|
+
when 5, 6
|
|
16
|
+
Logger::INFO
|
|
17
|
+
when 7
|
|
18
|
+
Logger::DEBUG
|
|
19
|
+
else
|
|
20
|
+
Logger::UNKNOWN
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Rdkafka::Config.ensure_log_thread
|
|
24
|
+
Rdkafka::Config.log_queue << [severity, "rdkafka: #{line}"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
StatsCallback = FFI::Function.new(
|
|
28
|
+
:int, [:pointer, :string, :int, :pointer]
|
|
29
|
+
) do |_client_ptr, json, _json_len, _opaque|
|
|
30
|
+
# Read the callback once: another thread may clear it while this one runs
|
|
31
|
+
statistics_callback = Rdkafka::Config.statistics_callback
|
|
32
|
+
|
|
33
|
+
if statistics_callback
|
|
34
|
+
stats = JSON.parse(json)
|
|
35
|
+
|
|
36
|
+
# If user requested statistics callbacks, we can use the statistics data to get the
|
|
37
|
+
# partitions count for each topic when this data is published. That way we do not have
|
|
38
|
+
# to query this information when user is using `partition_key`. This takes around 0.02ms
|
|
39
|
+
# every statistics interval period (most likely every 5 seconds) and saves us from making
|
|
40
|
+
# any queries to the cluster for the partition count.
|
|
41
|
+
#
|
|
42
|
+
# One edge case is if user would set the `statistics.interval.ms` much higher than the
|
|
43
|
+
# default current partition count refresh (30 seconds). This is taken care of as the lack
|
|
44
|
+
# of reporting to the partitions cache will cause cache expire and blocking refresh.
|
|
45
|
+
#
|
|
46
|
+
# If user sets `topic.metadata.refresh.interval.ms` too high this is on the user.
|
|
47
|
+
#
|
|
48
|
+
# Since this cache is shared, having few consumers and/or producers in one process will
|
|
49
|
+
# automatically improve the querying times even with low refresh times.
|
|
50
|
+
(stats["topics"] || EMPTY_HASH).each do |topic_name, details|
|
|
51
|
+
partitions_count = details["partitions"].keys.count { |k| !(k == RD_KAFKA_PARTITION_UA_STR) }
|
|
52
|
+
|
|
53
|
+
next unless partitions_count.positive?
|
|
54
|
+
|
|
55
|
+
Rdkafka::Producer.partitions_count_cache.set(topic_name, partitions_count)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
statistics_callback.call(stats)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Return 0 so librdkafka frees the json string
|
|
62
|
+
RD_KAFKA_RESP_ERR_NO_ERROR
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Retrieves fatal error details from a kafka client handle.
|
|
66
|
+
# This is a helper method to extract fatal error information consistently
|
|
67
|
+
# across different parts of the codebase (callbacks, testing utilities, etc.).
|
|
68
|
+
#
|
|
69
|
+
# @param client_ptr [FFI::Pointer] Native kafka client pointer
|
|
70
|
+
# @return [Hash, nil] Hash with :error_code and :error_string if fatal error occurred,
|
|
71
|
+
# nil otherwise
|
|
72
|
+
#
|
|
73
|
+
# @example
|
|
74
|
+
# details = Rdkafka::Bindings.extract_fatal_error(client_ptr)
|
|
75
|
+
# if details
|
|
76
|
+
# puts "Fatal error #{details[:error_code]}: #{details[:error_string]}"
|
|
77
|
+
# end
|
|
78
|
+
def self.extract_fatal_error(client_ptr)
|
|
79
|
+
error_buffer = FFI::MemoryPointer.new(:char, FATAL_ERROR_BUFFER_SIZE)
|
|
80
|
+
|
|
81
|
+
error_code = rd_kafka_fatal_error(client_ptr, error_buffer, FATAL_ERROR_BUFFER_SIZE)
|
|
82
|
+
|
|
83
|
+
return nil if error_code == RD_KAFKA_RESP_ERR_NO_ERROR
|
|
84
|
+
|
|
85
|
+
{
|
|
86
|
+
error_code: error_code,
|
|
87
|
+
error_string: error_buffer.read_string
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
ErrorCallback = FFI::Function.new(
|
|
92
|
+
:void, [:pointer, :int, :string, :pointer]
|
|
93
|
+
) do |client_ptr, err_code, reason, _opaque|
|
|
94
|
+
error_callback = Rdkafka::Config.error_callback
|
|
95
|
+
|
|
96
|
+
if error_callback
|
|
97
|
+
instance_name = client_ptr.null? ? nil : Rdkafka::Bindings.rd_kafka_name(client_ptr)
|
|
98
|
+
|
|
99
|
+
# Handle fatal errors according to librdkafka documentation:
|
|
100
|
+
# When ERR__FATAL is received, we must call rd_kafka_fatal_error()
|
|
101
|
+
# to get the actual underlying fatal error code and description.
|
|
102
|
+
error = if err_code == RD_KAFKA_RESP_ERR__FATAL
|
|
103
|
+
Rdkafka::RdkafkaError.build_fatal(
|
|
104
|
+
client_ptr,
|
|
105
|
+
fallback_error_code: err_code,
|
|
106
|
+
fallback_message: reason,
|
|
107
|
+
instance_name: instance_name
|
|
108
|
+
)
|
|
109
|
+
else
|
|
110
|
+
Rdkafka::RdkafkaError.build(err_code, broker_message: reason, instance_name: instance_name)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
error.set_backtrace(caller)
|
|
114
|
+
error_callback.call(error)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# The OAuth callback is currently global and contextless. This means that the callback will be
|
|
119
|
+
# called for all instances, and the callback must be able to determine to which instance it is
|
|
120
|
+
# associated. The instance name will be provided in the callback, allowing the callback to
|
|
121
|
+
# reference the correct instance.
|
|
122
|
+
#
|
|
123
|
+
# An example of how to use the instance name in the callback is given below.
|
|
124
|
+
# The `refresh_token` is configured as the `oauthbearer_token_refresh_callback`.
|
|
125
|
+
# `instances` is a map of client names to client instances, maintained by the user.
|
|
126
|
+
#
|
|
127
|
+
# ```
|
|
128
|
+
# def refresh_token(config, client_name)
|
|
129
|
+
# client = instances[client_name]
|
|
130
|
+
# client.oauthbearer_set_token(
|
|
131
|
+
# token: 'new-token-value',
|
|
132
|
+
# lifetime_ms: token-lifetime-ms,
|
|
133
|
+
# principal_name: 'principal-name'
|
|
134
|
+
# )
|
|
135
|
+
# end
|
|
136
|
+
# ```
|
|
137
|
+
OAuthbearerTokenRefreshCallback = FFI::Function.new(
|
|
138
|
+
:void, [:pointer, :string, :pointer]
|
|
139
|
+
) do |client_ptr, config, opaque_ptr|
|
|
140
|
+
refresh_callback = Rdkafka::Config.oauthbearer_token_refresh_callback
|
|
141
|
+
|
|
142
|
+
if refresh_callback && !client_ptr.null?
|
|
143
|
+
client_name = Rdkafka::Bindings.rd_kafka_name(client_ptr)
|
|
144
|
+
|
|
145
|
+
# Share consumers have no way to query their librdkafka client name (the share handle
|
|
146
|
+
# exposes no name accessor), so hand it over here - where librdkafka provides it -
|
|
147
|
+
# letting applications correlate this callback's client name with a ShareConsumer via
|
|
148
|
+
# ShareConsumer#name.
|
|
149
|
+
Rdkafka::Config.opaques[opaque_ptr.to_i]&.capture_client_name(client_name)
|
|
150
|
+
|
|
151
|
+
refresh_callback.call(config, client_name)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Configuration
|
|
6
|
+
|
|
7
|
+
enum :kafka_config_response, [
|
|
8
|
+
:config_unknown, -2,
|
|
9
|
+
:config_invalid, -1,
|
|
10
|
+
:config_ok, 0
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
attach_function :rd_kafka_conf_new, [], :pointer
|
|
14
|
+
attach_function :rd_kafka_conf_set, [:pointer, :string, :string, :pointer, :size_t], :kafka_config_response
|
|
15
|
+
attach_function :rd_kafka_conf_get, [:pointer, :string, :pointer, :pointer], :kafka_config_response
|
|
16
|
+
attach_function :rd_kafka_conf, [:pointer], :pointer
|
|
17
|
+
attach_function :rd_kafka_conf_dump, [:pointer, :pointer], :pointer
|
|
18
|
+
attach_function :rd_kafka_conf_dump_free, [:pointer, :size_t], :void
|
|
19
|
+
attach_function :rd_kafka_conf_destroy, [:pointer], :void
|
|
20
|
+
callback :log_cb, [:pointer, :int, :string, :string], :void
|
|
21
|
+
attach_function :rd_kafka_conf_set_log_cb, [:pointer, :log_cb], :void
|
|
22
|
+
attach_function :rd_kafka_conf_set_opaque, [:pointer, :pointer], :void
|
|
23
|
+
callback :stats_cb, [:pointer, :string, :int, :pointer], :int
|
|
24
|
+
attach_function :rd_kafka_conf_set_stats_cb, [:pointer, :stats_cb], :void
|
|
25
|
+
callback :error_cb, [:pointer, :int, :string, :pointer], :void
|
|
26
|
+
attach_function :rd_kafka_conf_set_error_cb, [:pointer, :error_cb], :void
|
|
27
|
+
attach_function :rd_kafka_rebalance_protocol, [:pointer], :string
|
|
28
|
+
callback :oauthbearer_token_refresh_cb, [:pointer, :string, :pointer], :void
|
|
29
|
+
attach_function :rd_kafka_conf_set_oauthbearer_token_refresh_cb, [:pointer, :oauthbearer_token_refresh_cb], :void
|
|
30
|
+
attach_function :rd_kafka_oauthbearer_set_token, [:pointer, :string, :int64, :pointer, :pointer, :size_t, :pointer, :size_t], :int
|
|
31
|
+
attach_function :rd_kafka_oauthbearer_set_token_failure, [:pointer, :string], :int
|
|
32
|
+
# Log queue
|
|
33
|
+
attach_function :rd_kafka_set_log_queue, [:pointer, :pointer], :void
|
|
34
|
+
attach_function :rd_kafka_queue_get_main, [:pointer], :pointer
|
|
35
|
+
attach_function :rd_kafka_queue_get_background, [:pointer], :pointer
|
|
36
|
+
|
|
37
|
+
# Queue IO Event Support - for fiber scheduler integration
|
|
38
|
+
# Enables notifications to a custom FD when queue transitions from empty to non-empty
|
|
39
|
+
# Arguments:
|
|
40
|
+
# - queue (rd_kafka_queue_t*) - the queue to monitor
|
|
41
|
+
# - fd (int) - file descriptor to write to (provide your own pipe/eventfd)
|
|
42
|
+
# - payload (const void*) - data to write to fd
|
|
43
|
+
# - size (size_t) - size of payload
|
|
44
|
+
attach_function :rd_kafka_queue_io_event_enable, [:pointer, :int, :pointer, :size_t], :void
|
|
45
|
+
# Per topic configs
|
|
46
|
+
attach_function :rd_kafka_topic_conf_new, [], :pointer
|
|
47
|
+
attach_function :rd_kafka_topic_conf_destroy, [:pointer], :void
|
|
48
|
+
attach_function :rd_kafka_topic_conf_set, [:pointer, :string, :string, :pointer, :size_t], :kafka_config_response
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Consumer
|
|
6
|
+
|
|
7
|
+
attach_function :rd_kafka_subscribe, [:pointer, :pointer], :int, blocking: true
|
|
8
|
+
attach_function :rd_kafka_unsubscribe, [:pointer], :int, blocking: true
|
|
9
|
+
attach_function :rd_kafka_subscription, [:pointer, :pointer], :int, blocking: true
|
|
10
|
+
attach_function :rd_kafka_assign, [:pointer, :pointer], :int, blocking: true
|
|
11
|
+
attach_function :rd_kafka_incremental_assign, [:pointer, :pointer], :int, blocking: true
|
|
12
|
+
attach_function :rd_kafka_incremental_unassign, [:pointer, :pointer], :int, blocking: true
|
|
13
|
+
attach_function :rd_kafka_assignment, [:pointer, :pointer], :int, blocking: true
|
|
14
|
+
attach_function :rd_kafka_assignment_lost, [:pointer], :int, blocking: true
|
|
15
|
+
attach_function :rd_kafka_committed, [:pointer, :pointer, :int], :int, blocking: true
|
|
16
|
+
attach_function :rd_kafka_commit, [:pointer, :pointer, :bool], :int, blocking: true
|
|
17
|
+
attach_function :rd_kafka_poll_set_consumer, [:pointer], :void, blocking: true
|
|
18
|
+
attach_function :rd_kafka_consumer_poll, [:pointer, :int], :pointer, blocking: true
|
|
19
|
+
# Non-blocking consumer poll variant (does not release GVL)
|
|
20
|
+
# More efficient for poll(0) calls in fiber schedulers.
|
|
21
|
+
attach_function :rd_kafka_consumer_poll_nb, :rd_kafka_consumer_poll, [:pointer, :int], :pointer, blocking: false
|
|
22
|
+
attach_function :rd_kafka_consumer_close, [:pointer], :int, blocking: true
|
|
23
|
+
attach_function :rd_kafka_queue_get_consumer, [:pointer], :pointer
|
|
24
|
+
attach_function :rd_kafka_consume_batch_queue, [:pointer, :int, :pointer, :size_t], :ssize_t, blocking: true
|
|
25
|
+
attach_function :rd_kafka_consume_batch_queue_nb, :rd_kafka_consume_batch_queue, [:pointer, :int, :pointer, :size_t], :ssize_t, blocking: false
|
|
26
|
+
attach_function :rd_kafka_offsets_store, [:pointer, :pointer], :int, blocking: true
|
|
27
|
+
attach_function :rd_kafka_pause_partitions, [:pointer, :pointer], :int, blocking: true
|
|
28
|
+
attach_function :rd_kafka_resume_partitions, [:pointer, :pointer], :int, blocking: true
|
|
29
|
+
attach_function :rd_kafka_seek, [:pointer, :int32, :int64, :int], :int, blocking: true
|
|
30
|
+
attach_function :rd_kafka_offsets_for_times, [:pointer, :pointer, :int], :int, blocking: true
|
|
31
|
+
attach_function :rd_kafka_position, [:pointer, :pointer], :int, blocking: true
|
|
32
|
+
# those two are used for eos support
|
|
33
|
+
attach_function :rd_kafka_consumer_group_metadata, [:pointer], :pointer, blocking: true
|
|
34
|
+
attach_function :rd_kafka_consumer_group_metadata_destroy, [:pointer], :void, blocking: true
|
|
35
|
+
|
|
36
|
+
# Headers
|
|
37
|
+
attach_function :rd_kafka_header_get_all, [:pointer, :size_t, :pointer, :pointer, SizePtr], :int
|
|
38
|
+
attach_function :rd_kafka_message_headers, [:pointer, :pointer], :int
|
|
39
|
+
|
|
40
|
+
# Rebalance
|
|
41
|
+
|
|
42
|
+
callback :rebalance_cb_function, [:pointer, :int, :pointer, :pointer], :void
|
|
43
|
+
attach_function :rd_kafka_conf_set_rebalance_cb, [:pointer, :rebalance_cb_function], :void, blocking: true
|
|
44
|
+
|
|
45
|
+
RebalanceCallback = FFI::Function.new(
|
|
46
|
+
:void, [:pointer, :int, :pointer, :pointer]
|
|
47
|
+
) do |client_ptr, code, partitions_ptr, opaque_ptr|
|
|
48
|
+
case code
|
|
49
|
+
when RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
|
50
|
+
if Rdkafka::Bindings.rd_kafka_rebalance_protocol(client_ptr) == "COOPERATIVE"
|
|
51
|
+
Rdkafka::Bindings.rd_kafka_incremental_assign(client_ptr, partitions_ptr)
|
|
52
|
+
else
|
|
53
|
+
Rdkafka::Bindings.rd_kafka_assign(client_ptr, partitions_ptr)
|
|
54
|
+
end
|
|
55
|
+
else # RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS or errors
|
|
56
|
+
if Rdkafka::Bindings.rd_kafka_rebalance_protocol(client_ptr) == "COOPERATIVE"
|
|
57
|
+
Rdkafka::Bindings.rd_kafka_incremental_unassign(client_ptr, partitions_ptr)
|
|
58
|
+
else
|
|
59
|
+
Rdkafka::Bindings.rd_kafka_assign(client_ptr, FFI::Pointer::NULL)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
|
64
|
+
next unless opaque
|
|
65
|
+
|
|
66
|
+
tpl = Rdkafka::Consumer::TopicPartitionList.from_native_tpl(partitions_ptr).freeze
|
|
67
|
+
begin
|
|
68
|
+
case code
|
|
69
|
+
when RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
|
70
|
+
opaque.call_on_partitions_assigned(tpl)
|
|
71
|
+
when RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS
|
|
72
|
+
opaque.call_on_partitions_revoked(tpl)
|
|
73
|
+
end
|
|
74
|
+
rescue Exception => err
|
|
75
|
+
Rdkafka::Config.logger.error("Unhandled exception: #{err.class} - #{err.message}")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Offset commit
|
|
80
|
+
|
|
81
|
+
callback :offset_commit_cb_function, [:pointer, :int, :pointer, :pointer], :void
|
|
82
|
+
attach_function :rd_kafka_conf_set_offset_commit_cb, [:pointer, :offset_commit_cb_function], :void, blocking: true
|
|
83
|
+
|
|
84
|
+
# Served from the consumer poll (or the events poll when `consumer_poll_set` is false) and
|
|
85
|
+
# from the consumer close, on the thread that calls them
|
|
86
|
+
OffsetCommitCallback = FFI::Function.new(
|
|
87
|
+
:void, [:pointer, :int, :pointer, :pointer]
|
|
88
|
+
) do |_client_ptr, code, offsets_ptr, opaque_ptr|
|
|
89
|
+
opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
|
90
|
+
next unless opaque
|
|
91
|
+
|
|
92
|
+
# Success and `no_offset` (a commit with nothing new to commit) are not failures
|
|
93
|
+
failed = code != RD_KAFKA_RESP_ERR_NO_ERROR && code != RD_KAFKA_RESP_ERR__NO_OFFSET
|
|
94
|
+
every = opaque.offsets_committed_listened?
|
|
95
|
+
on_failure = failed && opaque.offsets_commit_failed_listened?
|
|
96
|
+
|
|
97
|
+
# The list has an entry for every assigned partition, so build it only when it is used
|
|
98
|
+
if every || on_failure
|
|
99
|
+
error = code.zero? ? nil : Rdkafka::RdkafkaError.new(code)
|
|
100
|
+
tpl = if offsets_ptr.null?
|
|
101
|
+
Rdkafka::Consumer::TopicPartitionList.new
|
|
102
|
+
else
|
|
103
|
+
Rdkafka::Consumer::TopicPartitionList.from_native_tpl(offsets_ptr)
|
|
104
|
+
end
|
|
105
|
+
tpl.freeze
|
|
106
|
+
|
|
107
|
+
begin
|
|
108
|
+
opaque.call_on_offsets_committed(error, tpl) if every
|
|
109
|
+
rescue Exception => err
|
|
110
|
+
Rdkafka::Config.logger.error("Unhandled exception: #{err.class} - #{err.message}")
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
begin
|
|
114
|
+
opaque.call_on_offsets_commit_failed(error, tpl) if on_failure
|
|
115
|
+
rescue Exception => err
|
|
116
|
+
Rdkafka::Config.logger.error("Unhandled exception: #{err.class} - #{err.message}")
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Watermark offsets
|
|
122
|
+
|
|
123
|
+
attach_function :rd_kafka_query_watermark_offsets, [:pointer, :string, :int, :pointer, :pointer, :int], :int, blocking: true
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
attach_function :rd_kafka_err2name, [:int], :string
|
|
6
|
+
attach_function :rd_kafka_err2str, [:int], :string
|
|
7
|
+
attach_function :rd_kafka_error_is_fatal, [:pointer], :int
|
|
8
|
+
attach_function :rd_kafka_error_is_retriable, [:pointer], :int
|
|
9
|
+
attach_function :rd_kafka_error_txn_requires_abort, [:pointer], :int
|
|
10
|
+
attach_function :rd_kafka_error_destroy, [:pointer], :void
|
|
11
|
+
attach_function :rd_kafka_error_code, [:pointer], :int32
|
|
12
|
+
attach_function :rd_kafka_error_string, [:pointer], :pointer
|
|
13
|
+
attach_function :rd_kafka_get_err_descs, [:pointer, :pointer], :void
|
|
14
|
+
attach_function :rd_kafka_fatal_error, [:pointer, :pointer, :size_t], :int
|
|
15
|
+
attach_function :rd_kafka_test_fatal_error, [:pointer, :int, :string], :int
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Handle
|
|
6
|
+
|
|
7
|
+
enum :kafka_type, [
|
|
8
|
+
:rd_kafka_producer,
|
|
9
|
+
:rd_kafka_consumer
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
attach_function :rd_kafka_new, [:kafka_type, :pointer, :pointer, :size_t], :pointer
|
|
13
|
+
|
|
14
|
+
attach_function :rd_kafka_destroy, [:pointer], :void
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Messages, topics and topic partition lists
|
|
6
|
+
|
|
7
|
+
attach_function :rd_kafka_message_destroy, [:pointer], :void
|
|
8
|
+
attach_function :rd_kafka_message_timestamp, [:pointer, :pointer], :int64
|
|
9
|
+
attach_function :rd_kafka_message_latency, [:pointer], :int64
|
|
10
|
+
attach_function :rd_kafka_message_broker_id, [:pointer], :int32
|
|
11
|
+
attach_function :rd_kafka_message_status, [:pointer], :int
|
|
12
|
+
|
|
13
|
+
# Message persistence status (rd_kafka_msg_status_t)
|
|
14
|
+
RD_KAFKA_MSG_STATUS_NOT_PERSISTED = 0
|
|
15
|
+
RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED = 1
|
|
16
|
+
RD_KAFKA_MSG_STATUS_PERSISTED = 2
|
|
17
|
+
|
|
18
|
+
attach_function :rd_kafka_topic_new, [:pointer, :string, :pointer], :pointer
|
|
19
|
+
attach_function :rd_kafka_topic_destroy, [:pointer], :pointer
|
|
20
|
+
attach_function :rd_kafka_topic_name, [:pointer], :string
|
|
21
|
+
|
|
22
|
+
attach_function :rd_kafka_topic_partition_list_new, [:int32], :pointer
|
|
23
|
+
attach_function :rd_kafka_topic_partition_list_add, [:pointer, :string, :int32], :pointer
|
|
24
|
+
attach_function :rd_kafka_topic_partition_list_set_offset, [:pointer, :string, :int32, :int64], :void
|
|
25
|
+
attach_function :rd_kafka_topic_partition_list_destroy, [:pointer], :void
|
|
26
|
+
attach_function :rd_kafka_topic_partition_list_copy, [:pointer], :pointer
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rdkafka
|
|
4
|
+
module Bindings
|
|
5
|
+
# Metadata
|
|
6
|
+
|
|
7
|
+
attach_function :rd_kafka_name, [:pointer], :string
|
|
8
|
+
# Both return a newly allocated string the caller must release with rd_kafka_mem_free; they
|
|
9
|
+
# are attached as :pointer (not :string) so we can free them instead of leaking. clusterid
|
|
10
|
+
# also takes a timeout_ms (the previous arity was wrong, leaving that argument as garbage).
|
|
11
|
+
attach_function :rd_kafka_memberid, [:pointer], :pointer, blocking: true
|
|
12
|
+
attach_function :rd_kafka_clusterid, [:pointer, :int], :pointer, blocking: true
|
|
13
|
+
attach_function :rd_kafka_mem_free, [:pointer, :pointer], :void
|
|
14
|
+
attach_function :rd_kafka_metadata, [:pointer, :int, :pointer, :pointer, :int], :int, blocking: true
|
|
15
|
+
attach_function :rd_kafka_metadata_destroy, [:pointer], :void, blocking: true
|
|
16
|
+
end
|
|
17
|
+
end
|