rdkafka 0.22.2 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -3
  3. data/README.md +21 -14
  4. data/Rakefile +21 -21
  5. data/bin/verify_kafka_warnings +39 -0
  6. data/dist/{librdkafka-2.8.0.tar.gz → librdkafka-2.14.2.tar.gz} +0 -0
  7. data/docker-compose-ssl.yml +35 -0
  8. data/docker-compose.yml +2 -2
  9. data/ext/Rakefile +27 -27
  10. data/lib/rdkafka/abstract_handle.rb +54 -7
  11. data/lib/rdkafka/admin/acl_binding_result.rb +5 -5
  12. data/lib/rdkafka/admin/config_binding_result.rb +2 -2
  13. data/lib/rdkafka/admin/config_resource_binding_result.rb +1 -0
  14. data/lib/rdkafka/admin/create_acl_handle.rb +10 -6
  15. data/lib/rdkafka/admin/create_acl_report.rb +3 -2
  16. data/lib/rdkafka/admin/create_partitions_handle.rb +8 -7
  17. data/lib/rdkafka/admin/create_partitions_report.rb +1 -0
  18. data/lib/rdkafka/admin/create_topic_handle.rb +8 -7
  19. data/lib/rdkafka/admin/create_topic_report.rb +3 -0
  20. data/lib/rdkafka/admin/delete_acl_handle.rb +9 -8
  21. data/lib/rdkafka/admin/delete_acl_report.rb +5 -3
  22. data/lib/rdkafka/admin/delete_groups_handle.rb +10 -7
  23. data/lib/rdkafka/admin/delete_groups_report.rb +3 -0
  24. data/lib/rdkafka/admin/delete_topic_handle.rb +8 -7
  25. data/lib/rdkafka/admin/delete_topic_report.rb +3 -0
  26. data/lib/rdkafka/admin/describe_acl_handle.rb +9 -8
  27. data/lib/rdkafka/admin/describe_acl_report.rb +5 -3
  28. data/lib/rdkafka/admin/describe_configs_handle.rb +7 -10
  29. data/lib/rdkafka/admin/describe_configs_report.rb +8 -6
  30. data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +7 -10
  31. data/lib/rdkafka/admin/incremental_alter_configs_report.rb +8 -6
  32. data/lib/rdkafka/admin/list_offsets_handle.rb +31 -0
  33. data/lib/rdkafka/admin/list_offsets_report.rb +51 -0
  34. data/lib/rdkafka/admin.rb +357 -159
  35. data/lib/rdkafka/bindings.rb +205 -111
  36. data/lib/rdkafka/callbacks/base_handler.rb +62 -0
  37. data/lib/rdkafka/callbacks/create_acl_handler.rb +37 -0
  38. data/lib/rdkafka/callbacks/create_partitions_handler.rb +37 -0
  39. data/lib/rdkafka/callbacks/create_topic_handler.rb +37 -0
  40. data/lib/rdkafka/callbacks/delete_acl_handler.rb +42 -0
  41. data/lib/rdkafka/callbacks/delete_groups_handler.rb +37 -0
  42. data/lib/rdkafka/callbacks/delete_topic_handler.rb +37 -0
  43. data/lib/rdkafka/callbacks/describe_acl_handler.rb +35 -0
  44. data/lib/rdkafka/callbacks/describe_configs_handler.rb +42 -0
  45. data/lib/rdkafka/callbacks/incremental_alter_configs_handler.rb +42 -0
  46. data/lib/rdkafka/callbacks/list_offsets_handler.rb +42 -0
  47. data/lib/rdkafka/callbacks.rb +125 -216
  48. data/lib/rdkafka/config.rb +126 -66
  49. data/lib/rdkafka/consumer/headers.rb +22 -7
  50. data/lib/rdkafka/consumer/message.rb +12 -11
  51. data/lib/rdkafka/consumer/partition.rb +15 -4
  52. data/lib/rdkafka/consumer/topic_partition_list.rb +64 -38
  53. data/lib/rdkafka/consumer.rb +513 -59
  54. data/lib/rdkafka/defaults.rb +125 -0
  55. data/lib/rdkafka/error.rb +40 -14
  56. data/lib/rdkafka/helpers/metadata.rb +29 -0
  57. data/lib/rdkafka/helpers/oauth.rb +45 -13
  58. data/lib/rdkafka/helpers/time.rb +5 -0
  59. data/lib/rdkafka/metadata.rb +128 -37
  60. data/lib/rdkafka/native_kafka.rb +91 -8
  61. data/lib/rdkafka/producer/delivery_handle.rb +6 -6
  62. data/lib/rdkafka/producer/delivery_report.rb +10 -6
  63. data/lib/rdkafka/producer/partitions_count_cache.rb +51 -55
  64. data/lib/rdkafka/producer.rb +193 -95
  65. data/lib/rdkafka/version.rb +6 -3
  66. data/lib/rdkafka.rb +15 -0
  67. data/package-lock.json +331 -0
  68. data/package.json +9 -0
  69. data/rdkafka.gemspec +58 -36
  70. data/renovate.json +39 -23
  71. metadata +39 -125
  72. data/.github/CODEOWNERS +0 -3
  73. data/.github/FUNDING.yml +0 -1
  74. data/.github/workflows/ci_linux_x86_64_gnu.yml +0 -271
  75. data/.github/workflows/ci_linux_x86_64_musl.yml +0 -194
  76. data/.github/workflows/ci_macos_arm64.yml +0 -284
  77. data/.github/workflows/push_linux_x86_64_gnu.yml +0 -65
  78. data/.github/workflows/push_linux_x86_64_musl.yml +0 -79
  79. data/.github/workflows/push_macos_arm64.yml +0 -54
  80. data/.github/workflows/push_ruby.yml +0 -37
  81. data/.github/workflows/verify-action-pins.yml +0 -16
  82. data/.gitignore +0 -14
  83. data/.rspec +0 -2
  84. data/.ruby-gemset +0 -1
  85. data/.ruby-version +0 -1
  86. data/.yardopts +0 -2
  87. data/Gemfile +0 -5
  88. data/ext/README.md +0 -19
  89. data/ext/build_common.sh +0 -361
  90. data/ext/build_linux_x86_64_gnu.sh +0 -306
  91. data/ext/build_linux_x86_64_musl.sh +0 -763
  92. data/ext/build_macos_arm64.sh +0 -550
  93. data/spec/rdkafka/abstract_handle_spec.rb +0 -117
  94. data/spec/rdkafka/admin/create_acl_handle_spec.rb +0 -56
  95. data/spec/rdkafka/admin/create_acl_report_spec.rb +0 -18
  96. data/spec/rdkafka/admin/create_topic_handle_spec.rb +0 -52
  97. data/spec/rdkafka/admin/create_topic_report_spec.rb +0 -16
  98. data/spec/rdkafka/admin/delete_acl_handle_spec.rb +0 -85
  99. data/spec/rdkafka/admin/delete_acl_report_spec.rb +0 -72
  100. data/spec/rdkafka/admin/delete_topic_handle_spec.rb +0 -52
  101. data/spec/rdkafka/admin/delete_topic_report_spec.rb +0 -16
  102. data/spec/rdkafka/admin/describe_acl_handle_spec.rb +0 -85
  103. data/spec/rdkafka/admin/describe_acl_report_spec.rb +0 -73
  104. data/spec/rdkafka/admin_spec.rb +0 -971
  105. data/spec/rdkafka/bindings_spec.rb +0 -199
  106. data/spec/rdkafka/callbacks_spec.rb +0 -20
  107. data/spec/rdkafka/config_spec.rb +0 -258
  108. data/spec/rdkafka/consumer/headers_spec.rb +0 -73
  109. data/spec/rdkafka/consumer/message_spec.rb +0 -139
  110. data/spec/rdkafka/consumer/partition_spec.rb +0 -57
  111. data/spec/rdkafka/consumer/topic_partition_list_spec.rb +0 -248
  112. data/spec/rdkafka/consumer_spec.rb +0 -1274
  113. data/spec/rdkafka/error_spec.rb +0 -89
  114. data/spec/rdkafka/metadata_spec.rb +0 -79
  115. data/spec/rdkafka/native_kafka_spec.rb +0 -130
  116. data/spec/rdkafka/producer/delivery_handle_spec.rb +0 -45
  117. data/spec/rdkafka/producer/delivery_report_spec.rb +0 -25
  118. data/spec/rdkafka/producer/partitions_count_cache_spec.rb +0 -359
  119. data/spec/rdkafka/producer_spec.rb +0 -1345
  120. data/spec/spec_helper.rb +0 -195
@@ -14,9 +14,16 @@ module Rdkafka
14
14
 
15
15
  # Registry for registering all the handles.
16
16
  REGISTRY = {}
17
+ # Guards REGISTRY mutations. The registry is shared across producing/consuming threads and the
18
+ # background polling thread (which removes handles from FFI callbacks), so the Hash must not be
19
+ # mutated concurrently. This is effectively safe on MRI under the GVL but not on JRuby, where a
20
+ # lost write could leave a handle unregistered (never unlocked -> `wait` times out for a
21
+ # delivered message) or never removed (permanent leak).
22
+ REGISTRY_MUTEX = Mutex.new
17
23
  # Default wait timeout is 31 years
18
24
  MAX_WAIT_TIMEOUT_FOREVER = 10_000_000_000
19
25
 
26
+ private_constant :REGISTRY_MUTEX
20
27
  private_constant :MAX_WAIT_TIMEOUT_FOREVER
21
28
 
22
29
  class << self
@@ -25,17 +32,28 @@ module Rdkafka
25
32
  # @param handle [AbstractHandle] any handle we want to register
26
33
  def register(handle)
27
34
  address = handle.to_ptr.address
28
- REGISTRY[address] = handle
35
+ REGISTRY_MUTEX.synchronize { REGISTRY[address] = handle }
29
36
  end
30
37
 
31
38
  # Removes handle from the register based on the handle address
32
39
  #
33
40
  # @param address [Integer] address of the registered handle we want to remove
34
41
  def remove(address)
35
- REGISTRY.delete(address)
42
+ REGISTRY_MUTEX.synchronize { REGISTRY.delete(address) }
36
43
  end
37
44
  end
38
45
 
46
+ # Operation result prepared by the background event callback. Background events are
47
+ # destroyed as soon as the callback returns, so anything the waiting thread needs has to be
48
+ # copied out of event-owned memory into Ruby objects and stored here before `#unlock` runs.
49
+ # When result parsing fails, holds the captured exception so it can be re-raised on the
50
+ # waiting thread.
51
+ attr_accessor :result
52
+
53
+ # Broker-provided error message copied out of event-owned memory by the background event
54
+ # callback, used by `#raise_error`.
55
+ attr_accessor :broker_message
56
+
39
57
  def initialize
40
58
  @mutex = Thread::Mutex.new
41
59
  @resource = Thread::ConditionVariable.new
@@ -54,16 +72,34 @@ module Rdkafka
54
72
  # If there is a timeout this does not mean the operation failed, rdkafka might still be working
55
73
  # on the operation. In this case it is possible to call wait again.
56
74
  #
57
- # @param max_wait_timeout [Numeric, nil] Amount of time to wait before timing out.
58
- # If this is nil we will wait forever
75
+ # @param max_wait_timeout [Numeric, nil] DEPRECATED: Use max_wait_timeout_ms instead.
76
+ # Amount of time in seconds to wait before timing out. Will be removed in v1.0.0.
77
+ # @param max_wait_timeout_ms [Numeric, nil] Amount of time in milliseconds to wait before
78
+ # timing out. If this is nil we will wait forever. Defaults to 60,000ms (60 seconds).
59
79
  # @param raise_response_error [Boolean] should we raise error when waiting finishes
60
80
  #
61
81
  # @return [Object] Operation-specific result
62
82
  #
63
83
  # @raise [RdkafkaError] When the operation failed
64
84
  # @raise [WaitTimeoutError] When the timeout has been reached and the handle is still pending
65
- def wait(max_wait_timeout: 60, raise_response_error: true)
66
- timeout = max_wait_timeout ? monotonic_now + max_wait_timeout : MAX_WAIT_TIMEOUT_FOREVER
85
+ def wait(max_wait_timeout: :not_provided, max_wait_timeout_ms: :not_provided, raise_response_error: true)
86
+ # Determine which timeout value to use
87
+ if max_wait_timeout != :not_provided && max_wait_timeout_ms != :not_provided
88
+ warn "DEPRECATION WARNING: Both max_wait_timeout and max_wait_timeout_ms were provided. " \
89
+ "Using max_wait_timeout_ms. The max_wait_timeout parameter is deprecated and will be removed in v1.0.0."
90
+ timeout_ms = max_wait_timeout_ms
91
+ elsif max_wait_timeout != :not_provided
92
+ warn "DEPRECATION WARNING: max_wait_timeout (seconds) is deprecated. " \
93
+ "Use max_wait_timeout_ms (milliseconds) instead. This parameter will be removed in v1.0.0."
94
+ timeout_ms = max_wait_timeout ? (max_wait_timeout * 1000).to_i : nil
95
+ elsif max_wait_timeout_ms == :not_provided
96
+ timeout_ms = Defaults::HANDLE_WAIT_TIMEOUT_MS
97
+ else
98
+ timeout_ms = max_wait_timeout_ms
99
+ end
100
+
101
+ timeout_s = timeout_ms ? timeout_ms / 1000.0 : nil
102
+ timeout = timeout_s ? monotonic_now + timeout_s : MAX_WAIT_TIMEOUT_FOREVER
67
103
 
68
104
  @mutex.synchronize do
69
105
  loop do
@@ -74,7 +110,7 @@ module Rdkafka
74
110
  @resource.wait(@mutex, to_wait)
75
111
  else
76
112
  raise WaitTimeoutError.new(
77
- "Waiting for #{operation_name} timed out after #{max_wait_timeout} seconds"
113
+ "Waiting for #{operation_name} timed out after #{timeout_ms} ms"
78
114
  )
79
115
  end
80
116
  elsif self[:response] != 0 && raise_response_error
@@ -104,6 +140,17 @@ module Rdkafka
104
140
  raise "Must be implemented by subclass!"
105
141
  end
106
142
 
143
+ # Returns the operation result prepared by the background event callback, re-raising an
144
+ # exception that was captured while the event memory was still readable.
145
+ #
146
+ # @return [Object] operation-specific result
147
+ # @raise [RdkafkaError] when result parsing in the event callback failed
148
+ def prepared_result
149
+ raise(result) if result.is_a?(Exception)
150
+
151
+ result
152
+ end
153
+
107
154
  # Allow subclasses to override
108
155
  def raise_error
109
156
  raise RdkafkaError.new(self[:response])
@@ -3,17 +3,17 @@
3
3
  module Rdkafka
4
4
  class Admin
5
5
  # Extracts attributes of rd_kafka_AclBinding_t
6
- #
7
6
  class AclBindingResult
8
7
  attr_reader :result_error, :error_string, :matching_acl_resource_type,
9
- :matching_acl_resource_name, :matching_acl_resource_pattern_type,
10
- :matching_acl_principal, :matching_acl_host, :matching_acl_operation,
11
- :matching_acl_permission_type
8
+ :matching_acl_resource_name, :matching_acl_resource_pattern_type,
9
+ :matching_acl_principal, :matching_acl_host, :matching_acl_operation,
10
+ :matching_acl_permission_type
12
11
 
13
12
  # This attribute was initially released under the name that is now an alias
14
13
  # We keep it for backwards compatibility but it was changed for the consistency
15
- alias matching_acl_pattern_type matching_acl_resource_pattern_type
14
+ alias_method :matching_acl_pattern_type, :matching_acl_resource_pattern_type
16
15
 
16
+ # @param matching_acl [FFI::Pointer] pointer to the ACL binding struct
17
17
  def initialize(matching_acl)
18
18
  rd_kafka_error_pointer = Rdkafka::Bindings.rd_kafka_AclBinding_error(matching_acl)
19
19
  @result_error = Rdkafka::Bindings.rd_kafka_error_code(rd_kafka_error_pointer)
@@ -17,12 +17,12 @@ module Rdkafka
17
17
  @synonyms = []
18
18
 
19
19
  # The code below builds up the config synonyms using same config binding
20
- pointer_to_size_t = FFI::MemoryPointer.new(:int32)
20
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
21
21
  synonym_ptr = Bindings.rd_kafka_ConfigEntry_synonyms(config_ptr, pointer_to_size_t)
22
22
  synonyms_ptr = synonym_ptr.read_array_of_pointer(pointer_to_size_t.read_int)
23
23
 
24
24
  (1..pointer_to_size_t.read_int).map do |ar|
25
- self.class.new synonyms_ptr[ar - 1]
25
+ @synonyms << self.class.new(synonyms_ptr[ar - 1])
26
26
  end
27
27
  end
28
28
  end
@@ -6,6 +6,7 @@ module Rdkafka
6
6
  class ConfigResourceBindingResult
7
7
  attr_reader :name, :type, :configs, :configs_count
8
8
 
9
+ # @param config_resource_ptr [FFI::Pointer] pointer to the config resource struct
9
10
  def initialize(config_resource_ptr)
10
11
  ffi_binding = Bindings::ConfigResource.new(config_resource_ptr)
11
12
 
@@ -2,25 +2,29 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for create ACL operation
5
6
  class CreateAclHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :response_string, :pointer
8
+ :response, :int
9
9
 
10
10
  # @return [String] the name of the operation
11
11
  def operation_name
12
12
  "create acl"
13
13
  end
14
14
 
15
- # @return [CreateAclReport] instance with rdkafka_response value as 0 and rdkafka_response_string value as empty string if the acl creation was successful
15
+ # @return [CreateAclReport] report prepared by the background event callback, with
16
+ # rdkafka_response value as 0 and rdkafka_response_string value as empty string if the
17
+ # acl creation was successful
16
18
  def create_result
17
- CreateAclReport.new(rdkafka_response: self[:response], rdkafka_response_string: self[:response_string])
19
+ prepared_result
18
20
  end
19
21
 
22
+ # Raises an error if the operation failed
23
+ # @raise [RdkafkaError]
20
24
  def raise_error
21
25
  raise RdkafkaError.new(
22
- self[:response],
23
- broker_message: self[:response_string].read_string
26
+ self[:response],
27
+ broker_message: broker_message
24
28
  )
25
29
  end
26
30
  end
@@ -2,17 +2,18 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for create ACL operation result
5
6
  class CreateAclReport
6
-
7
7
  # Upon successful creation of Acl RD_KAFKA_RESP_ERR_NO_ERROR - 0 is returned as rdkafka_response
8
8
  # @return [Integer]
9
9
  attr_reader :rdkafka_response
10
10
 
11
-
12
11
  # Upon successful creation of Acl empty string will be returned as rdkafka_response_string
13
12
  # @return [String]
14
13
  attr_reader :rdkafka_response_string
15
14
 
15
+ # @param rdkafka_response [Integer] response code from librdkafka
16
+ # @param rdkafka_response_string [FFI::Pointer] pointer to response string
16
17
  def initialize(rdkafka_response:, rdkafka_response_string:)
17
18
  @rdkafka_response = rdkafka_response
18
19
  if rdkafka_response_string != FFI::Pointer::NULL
@@ -1,25 +1,26 @@
1
1
  module Rdkafka
2
2
  class Admin
3
+ # Handle for create partitions operation
3
4
  class CreatePartitionsHandle < AbstractHandle
4
5
  layout :pending, :bool,
5
- :response, :int,
6
- :error_string, :pointer,
7
- :result_name, :pointer
6
+ :response, :int
8
7
 
9
8
  # @return [String] the name of the operation
10
9
  def operation_name
11
10
  "create partitions"
12
11
  end
13
12
 
14
- # @return [Boolean] whether the create topic was successful
13
+ # @return [CreatePartitionsReport] report prepared by the background event callback
15
14
  def create_result
16
- CreatePartitionsReport.new(self[:error_string], self[:result_name])
15
+ prepared_result
17
16
  end
18
17
 
18
+ # Raises an error if the operation failed
19
+ # @raise [RdkafkaError]
19
20
  def raise_error
20
21
  raise RdkafkaError.new(
21
- self[:response],
22
- broker_message: CreateTopicReport.new(self[:error_string], self[:result_name]).error_string
22
+ self[:response],
23
+ broker_message: broker_message
23
24
  )
24
25
  end
25
26
  end
@@ -1,5 +1,6 @@
1
1
  module Rdkafka
2
2
  class Admin
3
+ # Report for create partitions operation result
3
4
  class CreatePartitionsReport < CreateTopicReport
4
5
  end
5
6
  end
@@ -2,26 +2,27 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for create topic operation
5
6
  class CreateTopicHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :error_string, :pointer,
9
- :result_name, :pointer
8
+ :response, :int
10
9
 
11
10
  # @return [String] the name of the operation
12
11
  def operation_name
13
12
  "create topic"
14
13
  end
15
14
 
16
- # @return [Boolean] whether the create topic was successful
15
+ # @return [CreateTopicReport] report prepared by the background event callback
17
16
  def create_result
18
- CreateTopicReport.new(self[:error_string], self[:result_name])
17
+ prepared_result
19
18
  end
20
19
 
20
+ # Raises an error if the operation failed
21
+ # @raise [RdkafkaError]
21
22
  def raise_error
22
23
  raise RdkafkaError.new(
23
- self[:response],
24
- broker_message: CreateTopicReport.new(self[:error_string], self[:result_name]).error_string
24
+ self[:response],
25
+ broker_message: broker_message
25
26
  )
26
27
  end
27
28
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for create topic operation result
5
6
  class CreateTopicReport
6
7
  # Any error message generated from the CreateTopic
7
8
  # @return [String]
@@ -11,6 +12,8 @@ module Rdkafka
11
12
  # @return [String]
12
13
  attr_reader :result_name
13
14
 
15
+ # @param error_string [FFI::Pointer] pointer to error string
16
+ # @param result_name [FFI::Pointer] pointer to topic name
14
17
  def initialize(error_string, result_name)
15
18
  if error_string != FFI::Pointer::NULL
16
19
  @error_string = error_string.read_string
@@ -2,27 +2,28 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for delete ACL operation
5
6
  class DeleteAclHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :response_string, :pointer,
9
- :matching_acls, :pointer,
10
- :matching_acls_count, :int
8
+ :response, :int
11
9
 
12
10
  # @return [String] the name of the operation
13
11
  def operation_name
14
12
  "delete acl"
15
13
  end
16
14
 
17
- # @return [DeleteAclReport] instance with an array of matching_acls
15
+ # @return [DeleteAclReport] report prepared by the background event callback, with an
16
+ # array of matching_acls
18
17
  def create_result
19
- DeleteAclReport.new(matching_acls: self[:matching_acls], matching_acls_count: self[:matching_acls_count])
18
+ prepared_result
20
19
  end
21
20
 
21
+ # Raises an error if the operation failed
22
+ # @raise [RdkafkaError]
22
23
  def raise_error
23
24
  raise RdkafkaError.new(
24
- self[:response],
25
- broker_message: self[:response_string].read_string
25
+ self[:response],
26
+ broker_message: broker_message
26
27
  )
27
28
  end
28
29
  end
@@ -2,16 +2,18 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for delete ACL operation result
5
6
  class DeleteAclReport
6
-
7
7
  # deleted acls
8
8
  # @return [Rdkafka::Bindings::AclBindingResult]
9
9
  attr_reader :deleted_acls
10
10
 
11
+ # @param matching_acls [FFI::Pointer] pointer to matching ACLs array
12
+ # @param matching_acls_count [Integer] number of matching ACLs
11
13
  def initialize(matching_acls:, matching_acls_count:)
12
- @deleted_acls=[]
14
+ @deleted_acls = []
13
15
  if matching_acls != FFI::Pointer::NULL
14
- acl_binding_result_pointers = matching_acls.read_array_of_pointer(matching_acls_count)
16
+ acl_binding_result_pointers = matching_acls.read_array_of_pointer(matching_acls_count)
15
17
  (1..matching_acls_count).map do |matching_acl_index|
16
18
  acl_binding_result = AclBindingResult.new(acl_binding_result_pointers[matching_acl_index - 1])
17
19
  @deleted_acls << acl_binding_result
@@ -2,25 +2,28 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for delete groups operation
5
6
  class DeleteGroupsHandle < AbstractHandle
6
- layout :pending, :bool, # TODO: ???
7
- :response, :int,
8
- :error_string, :pointer,
9
- :result_name, :pointer
7
+ layout :pending, :bool,
8
+ :response, :int
10
9
 
11
10
  # @return [String] the name of the operation
12
11
  def operation_name
13
12
  "delete groups"
14
13
  end
15
14
 
15
+ # Creates the result report
16
+ # @return [DeleteGroupsReport]
16
17
  def create_result
17
- DeleteGroupsReport.new(self[:error_string], self[:result_name])
18
+ prepared_result
18
19
  end
19
20
 
21
+ # Raises an error if the operation failed
22
+ # @raise [RdkafkaError]
20
23
  def raise_error
21
24
  raise RdkafkaError.new(
22
- self[:response],
23
- broker_message: create_result.error_string
25
+ self[:response],
26
+ broker_message: broker_message
24
27
  )
25
28
  end
26
29
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for delete groups operation result
5
6
  class DeleteGroupsReport
6
7
  # Any error message generated from the DeleteTopic
7
8
  # @return [String]
@@ -11,6 +12,8 @@ module Rdkafka
11
12
  # @return [String]
12
13
  attr_reader :result_name
13
14
 
15
+ # @param error_string [FFI::Pointer] pointer to error string
16
+ # @param result_name [FFI::Pointer] pointer to group name
14
17
  def initialize(error_string, result_name)
15
18
  if error_string != FFI::Pointer::NULL
16
19
  @error_string = error_string.read_string
@@ -2,26 +2,27 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for delete topic operation
5
6
  class DeleteTopicHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :error_string, :pointer,
9
- :result_name, :pointer
8
+ :response, :int
10
9
 
11
10
  # @return [String] the name of the operation
12
11
  def operation_name
13
12
  "delete topic"
14
13
  end
15
14
 
16
- # @return [Boolean] whether the delete topic was successful
15
+ # @return [DeleteTopicReport] report prepared by the background event callback
17
16
  def create_result
18
- DeleteTopicReport.new(self[:error_string], self[:result_name])
17
+ prepared_result
19
18
  end
20
19
 
20
+ # Raises an error if the operation failed
21
+ # @raise [RdkafkaError]
21
22
  def raise_error
22
23
  raise RdkafkaError.new(
23
- self[:response],
24
- broker_message: DeleteTopicReport.new(self[:error_string], self[:result_name]).error_string
24
+ self[:response],
25
+ broker_message: broker_message
25
26
  )
26
27
  end
27
28
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for delete topic operation result
5
6
  class DeleteTopicReport
6
7
  # Any error message generated from the DeleteTopic
7
8
  # @return [String]
@@ -11,6 +12,8 @@ module Rdkafka
11
12
  # @return [String]
12
13
  attr_reader :result_name
13
14
 
15
+ # @param error_string [FFI::Pointer] pointer to error string
16
+ # @param result_name [FFI::Pointer] pointer to topic name
14
17
  def initialize(error_string, result_name)
15
18
  if error_string != FFI::Pointer::NULL
16
19
  @error_string = error_string.read_string
@@ -2,27 +2,28 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for describe ACL operation
5
6
  class DescribeAclHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :response_string, :pointer,
9
- :acls, :pointer,
10
- :acls_count, :int
8
+ :response, :int
11
9
 
12
10
  # @return [String] the name of the operation.
13
11
  def operation_name
14
12
  "describe acl"
15
13
  end
16
14
 
17
- # @return [DescribeAclReport] instance with an array of acls that matches the request filters.
15
+ # @return [DescribeAclReport] report prepared by the background event callback, with an
16
+ # array of acls that matches the request filters.
18
17
  def create_result
19
- DescribeAclReport.new(acls: self[:acls], acls_count: self[:acls_count])
18
+ prepared_result
20
19
  end
21
20
 
21
+ # Raises an error if the operation failed
22
+ # @raise [RdkafkaError]
22
23
  def raise_error
23
24
  raise RdkafkaError.new(
24
- self[:response],
25
- broker_message: self[:response_string].read_string
25
+ self[:response],
26
+ broker_message: broker_message
26
27
  )
27
28
  end
28
29
  end
@@ -2,17 +2,19 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for describe ACL operation result
5
6
  class DescribeAclReport
6
-
7
7
  # acls that exists in the cluster for the resource_type, resource_name and pattern_type filters provided in the request.
8
8
  # @return [Rdkafka::Bindings::AclBindingResult] array of matching acls.
9
9
  attr_reader :acls
10
10
 
11
+ # @param acls [FFI::Pointer] pointer to ACLs array
12
+ # @param acls_count [Integer] number of ACLs
11
13
  def initialize(acls:, acls_count:)
12
- @acls=[]
14
+ @acls = []
13
15
 
14
16
  if acls != FFI::Pointer::NULL
15
- acl_binding_result_pointers = acls.read_array_of_pointer(acls_count)
17
+ acl_binding_result_pointers = acls.read_array_of_pointer(acls_count)
16
18
  (1..acls_count).map do |acl_index|
17
19
  acl_binding_result = AclBindingResult.new(acl_binding_result_pointers[acl_index - 1])
18
20
  @acls << acl_binding_result
@@ -2,30 +2,27 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for describe configs operation
5
6
  class DescribeConfigsHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :response_string, :pointer,
9
- :config_entries, :pointer,
10
- :entry_count, :int
8
+ :response, :int
11
9
 
12
10
  # @return [String] the name of the operation.
13
11
  def operation_name
14
12
  "describe configs"
15
13
  end
16
14
 
17
- # @return [DescribeAclReport] instance with an array of acls that matches the request filters.
15
+ # @return [DescribeConfigsReport] report prepared by the background event callback
18
16
  def create_result
19
- DescribeConfigsReport.new(
20
- config_entries: self[:config_entries],
21
- entry_count: self[:entry_count]
22
- )
17
+ prepared_result
23
18
  end
24
19
 
20
+ # Raises an error if the operation failed
21
+ # @raise [RdkafkaError]
25
22
  def raise_error
26
23
  raise RdkafkaError.new(
27
24
  self[:response],
28
- broker_message: self[:response_string].read_string
25
+ broker_message: broker_message
29
26
  )
30
27
  end
31
28
  end
@@ -2,11 +2,14 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Report for describe configs operation result
5
6
  class DescribeConfigsReport
6
7
  attr_reader :resources
7
8
 
9
+ # @param config_entries [FFI::Pointer] pointer to config entries array
10
+ # @param entry_count [Integer] number of config entries
8
11
  def initialize(config_entries:, entry_count:)
9
- @resources=[]
12
+ @resources = []
10
13
 
11
14
  return if config_entries == FFI::Pointer::NULL
12
15
 
@@ -16,7 +19,7 @@ module Rdkafka
16
19
  .each do |config_resource_result_ptr|
17
20
  config_resource_result = ConfigResourceBindingResult.new(config_resource_result_ptr)
18
21
 
19
- pointer_to_size_t = FFI::MemoryPointer.new(:int32)
22
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
20
23
  configs_ptr = Bindings.rd_kafka_ConfigResource_configs(
21
24
  config_resource_result_ptr,
22
25
  pointer_to_size_t
@@ -29,14 +32,13 @@ module Rdkafka
29
32
 
30
33
  @resources << config_resource_result
31
34
  end
32
- ensure
33
- return if config_entries == FFI::Pointer::NULL
34
-
35
- Bindings.rd_kafka_ConfigResource_destroy_array(config_entries, entry_count)
36
35
  end
37
36
 
38
37
  private
39
38
 
39
+ # Validates the config resource result and raises an error if invalid
40
+ # @param config_resource_result_ptr [FFI::Pointer] pointer to the config resource result
41
+ # @raise [RdkafkaError] when the config resource has an error
40
42
  def validate!(config_resource_result_ptr)
41
43
  code = Bindings.rd_kafka_ConfigResource_error(config_resource_result_ptr)
42
44
 
@@ -2,30 +2,27 @@
2
2
 
3
3
  module Rdkafka
4
4
  class Admin
5
+ # Handle for incremental alter configs operation
5
6
  class IncrementalAlterConfigsHandle < AbstractHandle
6
7
  layout :pending, :bool,
7
- :response, :int,
8
- :response_string, :pointer,
9
- :config_entries, :pointer,
10
- :entry_count, :int
8
+ :response, :int
11
9
 
12
10
  # @return [String] the name of the operation.
13
11
  def operation_name
14
12
  "incremental alter configs"
15
13
  end
16
14
 
17
- # @return [DescribeAclReport] instance with an array of acls that matches the request filters.
15
+ # @return [IncrementalAlterConfigsReport] report prepared by the background event callback
18
16
  def create_result
19
- IncrementalAlterConfigsReport.new(
20
- config_entries: self[:config_entries],
21
- entry_count: self[:entry_count]
22
- )
17
+ prepared_result
23
18
  end
24
19
 
20
+ # Raises an error if the operation failed
21
+ # @raise [RdkafkaError]
25
22
  def raise_error
26
23
  raise RdkafkaError.new(
27
24
  self[:response],
28
- broker_message: self[:response_string].read_string
25
+ broker_message: broker_message
29
26
  )
30
27
  end
31
28
  end