karafka 2.2.7 → 2.2.8

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 (36) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +12 -0
  4. data/Gemfile.lock +24 -14
  5. data/bin/karafka +2 -3
  6. data/docker-compose.yml +3 -1
  7. data/karafka.gemspec +1 -2
  8. data/lib/karafka/base_consumer.rb +1 -0
  9. data/lib/karafka/cli/base.rb +45 -34
  10. data/lib/karafka/cli/console.rb +5 -4
  11. data/lib/karafka/cli/help.rb +24 -0
  12. data/lib/karafka/cli/info.rb +2 -2
  13. data/lib/karafka/cli/install.rb +4 -4
  14. data/lib/karafka/cli/server.rb +68 -33
  15. data/lib/karafka/cli/topics.rb +1 -1
  16. data/lib/karafka/cli.rb +23 -19
  17. data/lib/karafka/connection/client.rb +9 -4
  18. data/lib/karafka/connection/rebalance_manager.rb +36 -21
  19. data/lib/karafka/errors.rb +3 -0
  20. data/lib/karafka/instrumentation/callbacks/rebalance.rb +64 -0
  21. data/lib/karafka/instrumentation/notifications.rb +5 -1
  22. data/lib/karafka/instrumentation/vendors/appsignal/base.rb +30 -0
  23. data/lib/karafka/instrumentation/vendors/appsignal/client.rb +122 -0
  24. data/lib/karafka/instrumentation/vendors/appsignal/dashboard.json +222 -0
  25. data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +30 -0
  26. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +331 -0
  27. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +2 -2
  28. data/lib/karafka/patches/rdkafka/bindings.rb +22 -39
  29. data/lib/karafka/patches/rdkafka/opaque.rb +36 -0
  30. data/lib/karafka/pro/processing/coordinator.rb +6 -7
  31. data/lib/karafka/pro/processing/strategies/vp/default.rb +20 -0
  32. data/lib/karafka/version.rb +1 -1
  33. data/lib/karafka.rb +1 -1
  34. data.tar.gz.sig +0 -0
  35. metadata +12 -18
  36. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6a42d67752052bcf8f29fb683ed8ffb5fce7675c155b73269c4654681913f7b
4
- data.tar.gz: b1bfc5bdad87c27111d8aee50302593133460f0eac47161f3c3872dc726d3b68
3
+ metadata.gz: e440e6a6a067d23095d6c0b60f4cd534080e2fd1cc3e528f1052a6368b60cab0
4
+ data.tar.gz: d5d1c98a0ac28677b860e74ae0c59b13bba68c07bd84964fb0ca7ac473454fcc
5
5
  SHA512:
6
- metadata.gz: b1e46475db36dc2fc837aa68b1639ad43b94a59afc72dd7287c60fac5f504f55c1ed68f9a1527a4eb1f6743801d38ba44ac6eef6c9d69a6b2ae4e4fbf3034b98
7
- data.tar.gz: 329fe59c9bbede3367c9bb3624c69652111f9387360d28b8d9e83bb0a184ea0e524d87d3f47afc400446f48993a57a41c4c171ae5e16c5413c7a496e88fc0421
6
+ metadata.gz: f5ea25e23361caba43073fb36c7cf91dacd105ed4a9595929c0e48b608e07701dbcf0be32f8982ae14809a1511f5ddc0cd2ae13fe5263f9ea9d8b2aed538fb16
7
+ data.tar.gz: 175c25bc43361facb9a7664fbe89fc48a7e7426be8ded047d5a1c549b1db67a0172ee3954972b07adeecf92c3dc4dc2c61e979d9905fa40967133d1872c6a46b
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Karafka framework changelog
2
2
 
3
+ ## 2.2.8 (2023-10-20)
4
+ - **[Feature]** Introduce Appsignal integration for errors and metrics tracking.
5
+ - [Improvement] Expose `#synchronize` for VPs to allow for locks when cross-VP consumers work is needed.
6
+ - [Improvement] Provide `#collapse_until!` direct consumer API to allow for collapsed virtual partitions consumer operations together with the Filtering API for advanced use-cases.
7
+ - [Refactor] Reorganize how rebalance events are propagated from `librdkafka` to Karafka. Replace `connection.client.rebalance_callback` with `rebalance.partitions_assigned` and `rebalance.partitions_revoked`. Introduce two extra events: `rebalance.partitions_assign` and `rebalance.partitions_revoke` to handle pre-rebalance future work.
8
+ - [Refactor] Remove `thor` as a CLI layer and rely on Ruby `OptParser`
9
+
10
+ ### Upgrade notes
11
+
12
+ 1. Unless you were using `connection.client.rebalance_callback` which was considered private, nothing.
13
+ 2. None of the CLI commands should change but `thor` has been removed so please report if you find any bugs.
14
+
3
15
  ## 2.2.7 (2023-10-07)
4
16
  - **[Feature]** Introduce Inline Insights to both OSS and Pro. Inline Insights allow you to get the Kafka insights/metrics from the consumer instance and use them to alter the processing flow. In Pro, there's an extra filter flow allowing to ensure, that the insights exist during consumption.
5
17
  - [Enhancement] Make sure, that subscription groups ids are unique by including their consumer group id in them similar to how topics ids are handled (not a breaking change).
data/Gemfile.lock CHANGED
@@ -1,53 +1,63 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka (2.2.7)
4
+ karafka (2.2.8)
5
5
  karafka-core (>= 2.2.2, < 2.3.0)
6
- thor (>= 0.20)
7
6
  waterdrop (>= 2.6.6, < 3.0.0)
8
7
  zeitwerk (~> 2.3)
9
8
 
10
9
  GEM
11
10
  remote: https://rubygems.org/
12
11
  specs:
13
- activejob (7.0.8)
14
- activesupport (= 7.0.8)
12
+ activejob (7.1.1)
13
+ activesupport (= 7.1.1)
15
14
  globalid (>= 0.3.6)
16
- activesupport (7.0.8)
15
+ activesupport (7.1.1)
16
+ base64
17
+ bigdecimal
17
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ connection_pool (>= 2.2.5)
20
+ drb
18
21
  i18n (>= 1.6, < 2)
19
22
  minitest (>= 5.1)
23
+ mutex_m
20
24
  tzinfo (~> 2.0)
25
+ base64 (0.1.1)
26
+ bigdecimal (3.1.4)
21
27
  byebug (11.1.3)
22
28
  concurrent-ruby (1.2.2)
29
+ connection_pool (2.4.1)
23
30
  diff-lcs (1.5.0)
24
31
  docile (1.4.0)
32
+ drb (2.1.1)
33
+ ruby2_keywords
25
34
  erubi (1.12.0)
26
35
  factory_bot (6.3.0)
27
36
  activesupport (>= 5.0.0)
28
- ffi (1.15.5)
37
+ ffi (1.16.3)
29
38
  globalid (1.2.1)
30
39
  activesupport (>= 6.1)
31
40
  i18n (1.14.1)
32
41
  concurrent-ruby (~> 1.0)
33
- karafka-core (2.2.2)
42
+ karafka-core (2.2.3)
34
43
  concurrent-ruby (>= 1.1)
35
- karafka-rdkafka (>= 0.13.1, < 0.14.0)
36
- karafka-rdkafka (0.13.5)
44
+ karafka-rdkafka (>= 0.13.6, < 0.14.0)
45
+ karafka-rdkafka (0.13.6)
37
46
  ffi (~> 1.15)
38
47
  mini_portile2 (~> 2.6)
39
48
  rake (> 12)
40
- karafka-web (0.7.5)
49
+ karafka-web (0.7.7)
41
50
  erubi (~> 1.4)
42
- karafka (>= 2.2.6, < 3.0.0)
51
+ karafka (>= 2.2.8.beta1, < 3.0.0)
43
52
  karafka-core (>= 2.2.2, < 3.0.0)
44
53
  roda (~> 3.68, >= 3.69)
45
54
  tilt (~> 2.0)
46
55
  mini_portile2 (2.8.4)
47
56
  minitest (5.20.0)
57
+ mutex_m (0.1.2)
48
58
  rack (3.0.8)
49
59
  rake (13.0.6)
50
- roda (3.72.0)
60
+ roda (3.73.0)
51
61
  rack
52
62
  rspec (3.12.0)
53
63
  rspec-core (~> 3.12.0)
@@ -62,14 +72,14 @@ GEM
62
72
  diff-lcs (>= 1.2.0, < 2.0)
63
73
  rspec-support (~> 3.12.0)
64
74
  rspec-support (3.12.1)
75
+ ruby2_keywords (0.0.5)
65
76
  simplecov (0.22.0)
66
77
  docile (~> 1.1)
67
78
  simplecov-html (~> 0.11)
68
79
  simplecov_json_formatter (~> 0.1)
69
80
  simplecov-html (0.12.3)
70
81
  simplecov_json_formatter (0.1.4)
71
- thor (1.2.2)
72
- tilt (2.2.0)
82
+ tilt (2.3.0)
73
83
  tzinfo (2.0.6)
74
84
  concurrent-ruby (~> 1.0)
75
85
  waterdrop (2.6.7)
data/bin/karafka CHANGED
@@ -6,6 +6,5 @@ require 'karafka'
6
6
  # our bin/karafka cli
7
7
  ENV['KARAFKA_CLI'] = 'true'
8
8
 
9
- Karafka::Cli::Base.load
10
- Karafka::Cli.prepare
11
- Karafka::Cli.start
9
+ ::Karafka::Cli::Base.load
10
+ ::Karafka::Cli.start
data/docker-compose.yml CHANGED
@@ -3,7 +3,7 @@ version: '2'
3
3
  services:
4
4
  kafka:
5
5
  container_name: kafka
6
- image: confluentinc/cp-kafka:7.5.0
6
+ image: confluentinc/cp-kafka:7.5.1
7
7
 
8
8
  ports:
9
9
  - 9092:9092
@@ -21,3 +21,5 @@ services:
21
21
  KAFKA_CONTROLLER_QUORUM_VOTERS: 1@127.0.0.1:9093
22
22
  ALLOW_PLAINTEXT_LISTENER: 'yes'
23
23
  KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
24
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
25
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
data/karafka.gemspec CHANGED
@@ -22,7 +22,6 @@ Gem::Specification.new do |spec|
22
22
  DESC
23
23
 
24
24
  spec.add_dependency 'karafka-core', '>= 2.2.2', '< 2.3.0'
25
- spec.add_dependency 'thor', '>= 0.20'
26
25
  spec.add_dependency 'waterdrop', '>= 2.6.6', '< 3.0.0'
27
26
  spec.add_dependency 'zeitwerk', '~> 2.3'
28
27
 
@@ -38,7 +37,7 @@ Gem::Specification.new do |spec|
38
37
  spec.metadata = {
39
38
  'funding_uri' => 'https://karafka.io/#become-pro',
40
39
  'homepage_uri' => 'https://karafka.io',
41
- 'changelog_uri' => 'https://github.com/karafka/karafka/blob/master/CHANGELOG.md',
40
+ 'changelog_uri' => 'https://karafka.io/docs/Changelog-Karafka',
42
41
  'bug_tracker_uri' => 'https://github.com/karafka/karafka/issues',
43
42
  'source_code_uri' => 'https://github.com/karafka/karafka',
44
43
  'documentation_uri' => 'https://karafka.io/docs',
@@ -73,6 +73,7 @@ module Karafka
73
73
  # @private
74
74
  #
75
75
  # @return [Boolean] true if there was no exception, otherwise false.
76
+ #
76
77
  # @note We keep the seek offset tracking, and use it to compensate for async offset flushing
77
78
  # that may not yet kick in when error occurs. That way we pause always on the last processed
78
79
  # message.
@@ -1,31 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Karafka
4
- class Cli < Thor
4
+ class Cli
5
5
  # Base class for all the command that we want to define
6
- # This base class provides a nicer interface to Thor and allows to easier separate single
7
- # independent commands
8
- # In order to define a new command you need to:
9
- # - specify its desc
10
- # - implement call method
11
- #
12
- # @example Create a dummy command
13
- # class Dummy < Base
14
- # self.desc = 'Dummy command'
15
- #
16
- # def call
17
- # puts 'I'm doing nothing!
18
- # end
19
- # end
6
+ # This base class provides an interface to easier separate single independent commands
20
7
  class Base
21
- include Thor::Shell
8
+ # @return [Hash] given command cli options
9
+ attr_reader :options
22
10
 
23
- # We can use it to call other cli methods via this object
24
- attr_reader :cli
25
-
26
- # @param cli [Karafka::Cli] current Karafka Cli instance
27
- def initialize(cli)
28
- @cli = cli
11
+ # Creates new CLI command instance
12
+ def initialize
13
+ # Parses the given command CLI options
14
+ @options = self.class.parse_options
29
15
  end
30
16
 
31
17
  # This method should implement proper cli action
@@ -64,26 +50,46 @@ module Karafka
64
50
 
65
51
  # Allows to set description of a given cli command
66
52
  # @param desc [String] Description of a given cli command
67
- def desc(desc)
53
+ def desc(desc = nil)
68
54
  @desc ||= desc
69
55
  end
70
56
 
71
- # This method will bind a given Cli command into Karafka Cli
72
- # This method is a wrapper to way Thor defines its commands
73
- # @param cli_class [Karafka::Cli] Karafka cli_class
74
- def bind_to(cli_class)
75
- cli_class.desc name, @desc
57
+ # Allows to set aliases for a given cli command
58
+ # @param args [Array] list of aliases that we can use to run given cli command
59
+ def aliases(*args)
60
+ @aliases ||= []
61
+ @aliases << args.map(&:to_s)
62
+ end
63
+
64
+ # Parses the CLI options
65
+ # @return [Hash] hash with parsed values
66
+ def parse_options
67
+ options = {}
76
68
 
77
- (@options || []).each { |option| cli_class.option(*option) }
69
+ OptionParser.new do |opts|
70
+ (@options || []).each do |option|
71
+ # Creates aliases for backwards compatibility
72
+ names = option[3].flat_map { |name| [name, name.tr('_', '-')] }
73
+ names.map! { |name| "#{name} value1,value2,valueN" } if option[2] == Array
74
+ names.uniq!
78
75
 
79
- context = self
76
+ opts.on(
77
+ *[names, option[2], option[1]].flatten
78
+ ) { |value| options[option[0]] = value }
79
+ end
80
+ end.parse!
80
81
 
81
- cli_class.send :define_method, name do |*args|
82
- context.new(self).call(*args)
83
- end
82
+ options
84
83
  end
85
84
 
86
- private
85
+ # @return [Array<Class>] available commands
86
+ def commands
87
+ ObjectSpace
88
+ .each_object(Class)
89
+ .select { |klass| klass.superclass == Karafka::Cli::Base }
90
+ .reject { |klass| klass.to_s.end_with?('::Base') }
91
+ .sort_by(&:name)
92
+ end
87
93
 
88
94
  # @return [String] downcased current class name that we use to define name for
89
95
  # given Cli command
@@ -92,6 +98,11 @@ module Karafka
92
98
  def name
93
99
  to_s.split('::').last.downcase
94
100
  end
101
+
102
+ # @return [Array<String>] names and aliases for command matching
103
+ def names
104
+ ((@aliases || []) << name).flatten.map(&:to_s)
105
+ end
95
106
  end
96
107
  end
97
108
  end
@@ -2,11 +2,12 @@
2
2
 
3
3
  module Karafka
4
4
  # Karafka framework Cli
5
- class Cli < Thor
5
+ class Cli
6
6
  # Console Karafka Cli action
7
7
  class Console < Base
8
- desc 'Start the Karafka console (short-cut alias: "c")'
9
- option aliases: 'c'
8
+ desc 'Starts the Karafka console (short-cut alias: "c")'
9
+
10
+ aliases :c
10
11
 
11
12
  class << self
12
13
  # @return [String] Console executing command for non-Rails setup
@@ -25,7 +26,7 @@ module Karafka
25
26
 
26
27
  # Start the Karafka console
27
28
  def call
28
- cli.info
29
+ Info.new.call
29
30
 
30
31
  command = ::Karafka.rails? ? self.class.rails_console : self.class.console
31
32
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ # Karafka framework Cli
5
+ class Cli
6
+ # Prints info with list of commands available
7
+ class Help < Base
8
+ desc 'Describes available commands'
9
+
10
+ # Print available commands
11
+ def call
12
+ # Find the longest command for alignment purposes
13
+ max_command_length = self.class.commands.map(&:name).map(&:size).max
14
+
15
+ puts 'Karafka commands:'
16
+
17
+ # Print each command formatted with its description
18
+ self.class.commands.each do |command|
19
+ puts " #{command.name.ljust(max_command_length)} # #{command.desc}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Karafka
4
4
  # Karafka framework Cli
5
- class Cli < Thor
5
+ class Cli
6
6
  # Info Karafka Cli action
7
7
  class Info < Base
8
- desc 'Print configuration details and other options of your application'
8
+ desc 'Prints configuration details and other options of your application'
9
9
 
10
10
  # Nice karafka banner
11
11
  BANNER = <<~BANNER
@@ -4,12 +4,12 @@ require 'erb'
4
4
 
5
5
  module Karafka
6
6
  # Karafka framework Cli
7
- class Cli < Thor
7
+ class Cli
8
8
  # Install Karafka Cli action
9
9
  class Install < Base
10
10
  include Helpers::Colorize
11
11
 
12
- desc 'Install all required things for Karafka application in current directory'
12
+ desc 'Installs all required things for Karafka application in current directory'
13
13
 
14
14
  # Directories created by default
15
15
  INSTALL_DIRS = %w[
@@ -26,9 +26,9 @@ module Karafka
26
26
  'example_consumer.rb.erb' => 'app/consumers/example_consumer.rb'
27
27
  }.freeze
28
28
 
29
- # @param args [Array] all the things that Thor CLI accepts
30
- def initialize(*args)
29
+ def initialize
31
30
  super
31
+
32
32
  dependencies = Bundler::LockfileParser.new(
33
33
  Bundler.read_file(
34
34
  Bundler.default_lockfile
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Karafka
4
4
  # Karafka framework Cli
5
- class Cli < Thor
5
+ class Cli
6
6
  # Server Karafka Cli action
7
7
  class Server < Base
8
8
  include Helpers::Colorize
@@ -12,36 +12,75 @@ module Karafka
12
12
 
13
13
  private_constant :SUPPORTED_TYPES
14
14
 
15
- desc 'Start the Karafka server (short-cut alias: "s")'
16
-
17
- option aliases: 's'
18
-
19
- # Thor does not work well with many aliases combinations, hence we remap the aliases
20
- # by ourselves in the code
21
- option :consumer_groups, type: :array, default: [], aliases: :g
22
- option :subscription_groups, type: :array, default: []
23
- option :topics, type: :array, default: []
24
-
25
- %i[
26
- include
27
- exclude
28
- ].each do |action|
29
- SUPPORTED_TYPES.each do |type|
30
- option(
31
- "#{action}_#{type}",
32
- type: :array,
33
- default: []
34
- )
35
- end
36
- end
15
+ desc 'Starts the Karafka server (short-cut alias: "s")'
16
+
17
+ aliases :s
18
+
19
+ option(
20
+ :consumer_groups,
21
+ 'Runs server only with specified consumer groups',
22
+ Array,
23
+ %w[
24
+ -g
25
+ --consumer_groups
26
+ --include_consumer_groups
27
+ ]
28
+ )
29
+
30
+ option(
31
+ :subscription_groups,
32
+ 'Runs server only with specified subscription groups',
33
+ Array,
34
+ %w[
35
+ --subscription_groups
36
+ --include_subscription_groups
37
+ ]
38
+ )
39
+
40
+ option(
41
+ :topics,
42
+ 'Runs server only with specified topics',
43
+ Array,
44
+ %w[
45
+ --topics
46
+ --include_topics
47
+ ]
48
+ )
49
+
50
+ option(
51
+ :exclude_consumer_groups,
52
+ 'Runs server without specified consumer groups',
53
+ Array,
54
+ %w[
55
+ --exclude_consumer_groups
56
+ ]
57
+ )
58
+
59
+ option(
60
+ :exclude_subscription_groups,
61
+ 'Runs server without specified subscription groups',
62
+ Array,
63
+ %w[
64
+ --exclude_subscription_groups
65
+ ]
66
+ )
67
+
68
+ option(
69
+ :exclude_topics,
70
+ 'Runs server without specified topics',
71
+ Array,
72
+ %w[
73
+ --exclude_topics
74
+ ]
75
+ )
37
76
 
38
77
  # Start the Karafka server
39
78
  def call
40
79
  # Print our banner and info in the dev mode
41
80
  print_marketing_info if Karafka::App.env.development?
42
81
 
43
- register_inclusions(cli)
44
- register_exclusions(cli)
82
+ register_inclusions
83
+ register_exclusions
45
84
 
46
85
  Karafka::Server.run
47
86
  end
@@ -49,26 +88,22 @@ module Karafka
49
88
  private
50
89
 
51
90
  # Registers things we want to include (if defined)
52
- # @param cli [Karafka::Cli] Thor cli handler
53
- def register_inclusions(cli)
91
+ def register_inclusions
54
92
  activities = ::Karafka::App.config.internal.routing.activity_manager
55
93
 
56
94
  SUPPORTED_TYPES.each do |type|
57
- v1 = cli.options[type] || []
58
- v2 = cli.options[:"include_#{type}"] || []
59
- names = v1 + v2
95
+ names = options[type] || []
60
96
 
61
97
  names.each { |name| activities.include(type, name) }
62
98
  end
63
99
  end
64
100
 
65
101
  # Registers things we want to exclude (if defined)
66
- # @param cli [Karafka::Cli] Thor cli handler
67
- def register_exclusions(cli)
102
+ def register_exclusions
68
103
  activities = ::Karafka::App.config.internal.routing.activity_manager
69
104
 
70
105
  activities.class::SUPPORTED_TYPES.each do |type|
71
- names = cli.options[:"exclude_#{type}"] || []
106
+ names = options[:"exclude_#{type}"] || []
72
107
 
73
108
  names.each { |name| activities.exclude(type, name) }
74
109
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Karafka
4
- class Cli < Thor
4
+ class Cli
5
5
  # CLI actions related to Kafka cluster topics management
6
6
  class Topics < Base
7
7
  include Helpers::Colorize
data/lib/karafka/cli.rb CHANGED
@@ -5,31 +5,35 @@ module Karafka
5
5
  #
6
6
  # If you want to add/modify command that belongs to CLI, please review all commands
7
7
  # available in cli/ directory inside Karafka source code.
8
- #
9
- # @note Whole Cli is built using Thor
10
- # @see https://github.com/erikhuda/thor
11
- class Cli < Thor
12
- package_name 'Karafka'
13
-
8
+ class Cli
14
9
  class << self
15
- # Loads all Cli commands into Thor framework.
16
- # This method should be executed before we run Karafka::Cli.start, otherwise we won't
17
- # have any Cli commands available.
18
- def prepare
19
- cli_commands.each do |action|
20
- action.bind_to(self)
10
+ # Starts the CLI
11
+ def start
12
+ # Command we want to run, like install, server, etc
13
+ command_name = ARGV[0]
14
+ # Action for action-based commands like topics migrate
15
+ action = ARGV[1].to_s.start_with?('-') ? false : ARGV[1]
16
+
17
+ command = commands.find { |cmd| cmd.names.include?(command_name) }
18
+
19
+ if command
20
+ # Only actionable commands require command as an argument
21
+ args = action ? [action] : []
22
+
23
+ command.new.call(*args)
24
+ else
25
+ raise(
26
+ Karafka::Errors::UnrecognizedCommandError,
27
+ "Unrecognized command \"#{command_name}\""
28
+ )
21
29
  end
22
30
  end
23
31
 
24
32
  private
25
33
 
26
- # @return [Array<Class>] Array with Cli action classes that can be used as commands
27
- def cli_commands
28
- constants
29
- .map! { |object| const_get(object) }
30
- .keep_if do |object|
31
- object.instance_of?(Class) && (object < Cli::Base)
32
- end
34
+ # @return [Array<Class>] command classes
35
+ def commands
36
+ Base.commands
33
37
  end
34
38
  end
35
39
  end
@@ -43,7 +43,11 @@ module Karafka
43
43
  @closed = false
44
44
  @subscription_group = subscription_group
45
45
  @buffer = RawMessagesBuffer.new
46
- @rebalance_manager = RebalanceManager.new
46
+ @rebalance_manager = RebalanceManager.new(@subscription_group.id)
47
+ @rebalance_callback = Instrumentation::Callbacks::Rebalance.new(
48
+ @subscription_group.id,
49
+ @subscription_group.consumer_group.id
50
+ )
47
51
  @kafka = build_consumer
48
52
  # There are few operations that can happen in parallel from the listener threads as well
49
53
  # as from the workers. They are not fully thread-safe because they may be composed out of
@@ -498,7 +502,8 @@ module Karafka
498
502
  def build_consumer
499
503
  ::Rdkafka::Config.logger = ::Karafka::App.config.logger
500
504
  config = ::Rdkafka::Config.new(@subscription_group.kafka)
501
- config.consumer_rebalance_listener = @rebalance_manager
505
+ config.consumer_rebalance_listener = @rebalance_callback
506
+
502
507
  consumer = config.consumer
503
508
  @name = consumer.name
504
509
 
@@ -507,7 +512,7 @@ module Karafka
507
512
  @subscription_group.id,
508
513
  Instrumentation::Callbacks::Statistics.new(
509
514
  @subscription_group.id,
510
- @subscription_group.consumer_group_id,
515
+ @subscription_group.consumer_group.id,
511
516
  @name
512
517
  )
513
518
  )
@@ -517,7 +522,7 @@ module Karafka
517
522
  @subscription_group.id,
518
523
  Instrumentation::Callbacks::Error.new(
519
524
  @subscription_group.id,
520
- @subscription_group.consumer_group_id,
525
+ @subscription_group.consumer_group.id,
521
526
  @name
522
527
  )
523
528
  )