karafka 2.0.29 → 2.0.30

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a258a78f3df80b4cda4f315f56ef4f7fb48003f63d0d58140c189b01b3f4875
4
- data.tar.gz: c267cb96bb8a972a2255f4a1298adde63678be4502b4ec8573af9c8a940435b4
3
+ metadata.gz: 2c983b3fbf07db3e91f3c051a8b4de4b2d88619877fbf66a4e434e38bf67c96b
4
+ data.tar.gz: babb3c513e6bb3fd0610363e3bbd9e7fcf07b1820f02fdd80ccacc8a109aab08
5
5
  SHA512:
6
- metadata.gz: beed9b0cbc83249d0bf227edb859142888d748dab6a972bf58c2d7e38ad578292544948bd9f2f25edbeebe6b37d1f0d20d47fc5e15d3d12420964447d414c54a
7
- data.tar.gz: 7da728f75e5540d339887d2fb3bee4787016bdcd16a56f29b4f9c0b3e9f4ff45f1d6f0e843d25bf3e7a31e05ea3a320e174a005a149f76156618dc70327e71de
6
+ metadata.gz: ea000c13a834ffba97c1837fa1f19dabbf78dbe8958354a8200bb5d2c0940852343521e6740113e07890f97a7e6edd108d8595a66688c4c14dbf313e86ec715f
7
+ data.tar.gz: 81ae980ef7950c6cae7d1bea2751d1826e5bbf4c1384be4736af895977fb7ff38f70c24a9b7b248cb18744e042ffb0ba0dc154171c29dcc73262733d87c31ea1
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Karafka framework changelog
2
2
 
3
+ ## 2.0.30 (2022-01-31)
4
+ - [Improvement] Alias `--consumer-groups` with `--include-consumer-groups`
5
+ - [Improvement] Alias `--subscription-groups` with `--include-subscription-groups`
6
+ - [Improvement] Alias `--topics` with `--include-topics`
7
+ - [Improvement] Introduce `--exclude-consumer-groups` for ability to exclude certain consumer groups from running
8
+ - [Improvement] Introduce `--exclude-subscription-groups` for ability to exclude certain subscription groups from running
9
+ - [Improvement] Introduce `--exclude-topics` for ability to exclude certain topics from running
10
+
3
11
  ## 2.0.29 (2023-01-30)
4
12
  - [Improvement] Make sure, that the `Karafka#producer` instance has the `LoggerListener` enabled in the install template, so Karafka by default prints both consumer and producer info.
5
13
  - [Improvement] Extract the code loading capabilities of Karafka console from the executable, so web can use it to provide CLI commands.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka (2.0.29)
4
+ karafka (2.0.30)
5
5
  karafka-core (>= 2.0.9, < 3.0.0)
6
6
  thor (>= 0.20)
7
7
  waterdrop (>= 2.4.10, < 3.0.0)
@@ -25,7 +25,7 @@ GEM
25
25
  factory_bot (6.2.1)
26
26
  activesupport (>= 5.0.0)
27
27
  ffi (1.15.5)
28
- globalid (1.0.1)
28
+ globalid (1.1.0)
29
29
  activesupport (>= 5.0)
30
30
  i18n (1.12.0)
31
31
  concurrent-ruby (~> 1.0)
@@ -59,7 +59,7 @@ GEM
59
59
  simplecov-html (0.12.3)
60
60
  simplecov_json_formatter (0.1.4)
61
61
  thor (1.2.1)
62
- tzinfo (2.0.5)
62
+ tzinfo (2.0.6)
63
63
  concurrent-ruby (~> 1.0)
64
64
  waterdrop (2.4.10)
65
65
  karafka-core (>= 2.0.9, < 3.0.0)
data/README.md CHANGED
@@ -10,6 +10,7 @@
10
10
 
11
11
  Karafka is a Ruby and Rails multi-threaded efficient Kafka processing framework that:
12
12
 
13
+ - Has a built-in [Web UI](https://karafka.io/docs/Web-UI-Features/) providing a convenient way to monitor and manage Karafka-based applications.
13
14
  - Supports parallel processing in [multiple threads](https://karafka.io/docs/Concurrency-and-multithreading) (also for a [single topic partition](https://karafka.io/docs/Pro-Virtual-Partitions) work)
14
15
  - [Automatically integrates](https://karafka.io/docs/Integrating-with-Ruby-on-Rails-and-other-frameworks#integrating-with-ruby-on-rails) with Ruby on Rails
15
16
  - Has [ActiveJob backend](https://karafka.io/docs/Active-Job) support (including [ordered jobs](https://karafka.io/docs/Pro-Enhanced-Active-Job#ordered-jobs))
@@ -83,7 +84,7 @@ bundle exec karafka server
83
84
 
84
85
  ## Want to Upgrade? LGPL is not for you? Want to help?
85
86
 
86
- I also sell Karafka Pro subscriptions. It includes a commercial-friendly license, priority support, architecture consultations, and high throughput data processing-related features (virtual partitions, long-running jobs, and more).
87
+ I also sell Karafka Pro subscriptions. It includes a commercial-friendly license, priority support, architecture consultations, enhanced Web UI and high throughput data processing-related features (virtual partitions, long-running jobs, and more).
87
88
 
88
89
  **20%** of the income will be distributed back to other OSS projects that Karafka uses under the hood.
89
90
 
@@ -7,27 +7,73 @@ module Karafka
7
7
  class Server < Base
8
8
  include Helpers::Colorize
9
9
 
10
+ # Types of things we can include / exclude from the routing via the CLI options
11
+ SUPPORTED_TYPES = ::Karafka::Routing::ActivityManager::SUPPORTED_TYPES
12
+
13
+ private_constant :SUPPORTED_TYPES
14
+
10
15
  desc 'Start the Karafka server (short-cut alias: "s")'
16
+
11
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
12
21
  option :consumer_groups, type: :array, default: [], aliases: :g
13
22
  option :subscription_groups, type: :array, default: []
14
23
  option :topics, type: :array, default: []
15
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
37
+
16
38
  # Start the Karafka server
17
39
  def call
18
40
  # Print our banner and info in the dev mode
19
41
  print_marketing_info if Karafka::App.env.development?
20
42
 
21
- active_routing_config = Karafka::App.config.internal.routing.active
22
- active_routing_config.consumer_groups = cli.options[:consumer_groups]
23
- active_routing_config.subscription_groups = cli.options[:subscription_groups]
24
- active_routing_config.topics = cli.options[:topics]
43
+ register_inclusions(cli)
44
+ register_exclusions(cli)
25
45
 
26
46
  Karafka::Server.run
27
47
  end
28
48
 
29
49
  private
30
50
 
51
+ # Registers things we want to include (if defined)
52
+ # @param cli [Karafka::Cli] Thor cli handler
53
+ def register_inclusions(cli)
54
+ activities = ::Karafka::App.config.internal.routing.activity_manager
55
+
56
+ SUPPORTED_TYPES.each do |type|
57
+ v1 = cli.options[type] || []
58
+ v2 = cli.options[:"include_#{type}"] || []
59
+ names = v1 + v2
60
+
61
+ names.each { |name| activities.include(type, name) }
62
+ end
63
+ end
64
+
65
+ # Registers things we want to exclude (if defined)
66
+ # @param cli [Karafka::Cli] Thor cli handler
67
+ def register_exclusions(cli)
68
+ activities = ::Karafka::App.config.internal.routing.activity_manager
69
+
70
+ activities.class::SUPPORTED_TYPES.each do |type|
71
+ names = cli.options[:"exclude_#{type}"] || []
72
+
73
+ names.each { |name| activities.exclude(type, name) }
74
+ end
75
+ end
76
+
31
77
  # Prints marketing info
32
78
  def print_marketing_info
33
79
  Karafka.logger.info Info::BANNER
@@ -12,69 +12,71 @@ module Karafka
12
12
  ).fetch('en').fetch('validations').fetch('server_cli_options')
13
13
  end
14
14
 
15
- optional(:consumer_groups) { |cg| cg.is_a?(Array) }
16
- optional(:subscription_groups) { |sg| sg.is_a?(Array) }
17
- optional(:topics) { |topics| topics.is_a?(Array) }
15
+ %i[
16
+ include
17
+ exclude
18
+ ].each do |action|
19
+ optional(:"#{action}_consumer_groups") { |cg| cg.is_a?(Array) }
20
+ optional(:"#{action}_subscription_groups") { |sg| sg.is_a?(Array) }
21
+ optional(:"#{action}_topics") { |topics| topics.is_a?(Array) }
18
22
 
19
- virtual do |data, errors|
20
- next unless errors.empty?
21
- next unless data.key?(:consumer_groups)
23
+ virtual do |data, errors|
24
+ next unless errors.empty?
22
25
 
23
- value = data.fetch(:consumer_groups)
26
+ value = data.fetch(:"#{action}_consumer_groups")
24
27
 
25
- # If there were no consumer_groups declared in the server cli, it means that we will
26
- # run all of them and no need to validate them here at all
27
- next if value.empty?
28
- next if (value - Karafka::App.consumer_groups.map(&:name)).empty?
28
+ # If there were no consumer_groups declared in the server cli, it means that we will
29
+ # run all of them and no need to validate them here at all
30
+ next if value.empty?
31
+ next if (value - Karafka::App.consumer_groups.map(&:name)).empty?
29
32
 
30
- # Found unknown consumer groups
31
- [[%i[consumer_groups], :consumer_groups_inclusion]]
32
- end
33
+ # Found unknown consumer groups
34
+ [[[:"#{action}_consumer_groups"], :consumer_groups_inclusion]]
35
+ end
33
36
 
34
- virtual do |data, errors|
35
- next unless errors.empty?
36
- next unless data.key?(:subscription_groups)
37
+ virtual do |data, errors|
38
+ next unless errors.empty?
37
39
 
38
- value = data.fetch(:subscription_groups)
40
+ value = data.fetch(:"#{action}_subscription_groups")
39
41
 
40
- # If there were no subscription_groups declared in the server cli, it means that we will
41
- # run all of them and no need to validate them here at all
42
- next if value.empty?
42
+ # If there were no subscription_groups declared in the server cli, it means that we will
43
+ # run all of them and no need to validate them here at all
44
+ next if value.empty?
43
45
 
44
- subscription_groups = Karafka::App
45
- .consumer_groups
46
- .map(&:subscription_groups)
47
- .flatten
48
- .map(&:name)
46
+ subscription_groups = Karafka::App
47
+ .consumer_groups
48
+ .map(&:subscription_groups)
49
+ .flatten
50
+ .map(&:name)
49
51
 
50
- next if (value - subscription_groups).empty?
52
+ next if (value - subscription_groups).empty?
51
53
 
52
- # Found unknown subscription groups
53
- [[%i[subscription_groups], :subscription_groups_inclusion]]
54
- end
54
+ # Found unknown subscription groups
55
+ [[[:"#{action}_subscription_groups"], :subscription_groups_inclusion]]
56
+ end
55
57
 
56
- virtual do |data, errors|
57
- next unless errors.empty?
58
- next unless data.key?(:topics)
58
+ virtual do |data, errors|
59
+ next unless errors.empty?
59
60
 
60
- value = data.fetch(:topics)
61
+ value = data.fetch(:"#{action}_topics")
61
62
 
62
- # If there were no topics declared in the server cli, it means that we will
63
- # run all of them and no need to validate them here at all
64
- next if value.empty?
63
+ # If there were no topics declared in the server cli, it means that we will
64
+ # run all of them and no need to validate them here at all
65
+ next if value.empty?
65
66
 
66
- topics = Karafka::App
67
- .consumer_groups
68
- .map(&:subscription_groups)
69
- .flatten
70
- .map(&:topics)
71
- .map { |gtopics| gtopics.map(&:name) }
72
- .flatten
67
+ topics = Karafka::App
68
+ .consumer_groups
69
+ .map(&:subscription_groups)
70
+ .flatten
71
+ .map(&:topics)
72
+ .map { |gtopics| gtopics.map(&:name) }
73
+ .flatten
73
74
 
74
- next if (value - topics).empty?
75
+ next if (value - topics).empty?
75
76
 
76
- # Found unknown topics
77
- [[%i[topics], :topics_inclusion]]
77
+ # Found unknown topics
78
+ [[[:"#{action}_topics"], :topics_inclusion]]
79
+ end
78
80
  end
79
81
 
80
82
  # Makes sure we have anything to subscribe to when we start the server
@@ -83,7 +85,7 @@ module Karafka
83
85
 
84
86
  next unless Karafka::App.subscription_groups.empty?
85
87
 
86
- [[%i[topics], :topics_missing]]
88
+ [[%i[include_topics], :topics_missing]]
87
89
  end
88
90
  end
89
91
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Routing
5
+ # Allows us to get track of which consumer groups, subscription groups and topics are enabled
6
+ # or disabled via CLI
7
+ class ActivityManager
8
+ # Supported types of inclusions and exclusions
9
+ SUPPORTED_TYPES = %i[
10
+ consumer_groups
11
+ subscription_groups
12
+ topics
13
+ ].freeze
14
+
15
+ def initialize
16
+ @included = Hash.new { |h, k| h[k] = [] }
17
+ @excluded = Hash.new { |h, k| h[k] = [] }
18
+ end
19
+
20
+ # Adds resource to included/active
21
+ # @param type [Symbol] type for inclusion
22
+ # @param name [String] name of the element
23
+ def include(type, name)
24
+ validate!(type)
25
+
26
+ @included[type] << name
27
+ end
28
+
29
+ # Adds resource to excluded
30
+ # @param type [Symbol] type for inclusion
31
+ # @param name [String] name of the element
32
+ def exclude(type, name)
33
+ validate!(type)
34
+
35
+ @excluded[type] << name
36
+ end
37
+
38
+ # @param type [Symbol] type for inclusion
39
+ # @param name [String] name of the element
40
+ # @return [Boolean] is the given resource active or not
41
+ def active?(type, name)
42
+ validate!(type)
43
+
44
+ included = @included[type]
45
+ excluded = @excluded[type]
46
+
47
+ # If nothing defined, all active by default
48
+ return true if included.empty? && excluded.empty?
49
+ # Inclusion supersedes exclusion in case someone wrote both
50
+ return true if !included.empty? && included.include?(name)
51
+
52
+ # If there are exclusions but our is not excluded and no inclusions or included, it's ok
53
+ !excluded.empty? &&
54
+ !excluded.include?(name) &&
55
+ (included.empty? || included.include?(name))
56
+ end
57
+
58
+ # @return [Hash] accumulated data in a hash for validations
59
+ def to_h
60
+ (
61
+ SUPPORTED_TYPES.map { |type| ["include_#{type}".to_sym, @included[type]] } +
62
+ SUPPORTED_TYPES.map { |type| ["exclude_#{type}".to_sym, @excluded[type]] }
63
+ ).to_h
64
+ end
65
+
66
+ # Clears the manager
67
+ def clear
68
+ @included.clear
69
+ @excluded.clear
70
+ end
71
+
72
+ private
73
+
74
+ # Checks if the type we want to register is supported
75
+ #
76
+ # @param type [Symbol] type for inclusion
77
+ def validate!(type)
78
+ return if SUPPORTED_TYPES.include?(type)
79
+
80
+ raise(::Karafka::Errors::UnsupportedCaseError, type)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -31,10 +31,7 @@ module Karafka
31
31
 
32
32
  # @return [Boolean] true if this consumer group should be active in our current process
33
33
  def active?
34
- cgs = Karafka::App.config.internal.routing.active.consumer_groups
35
-
36
- # When empty it means no groups were specified, hence all should be used
37
- cgs.empty? || cgs.include?(name)
34
+ Karafka::App.config.internal.routing.activity_manager.active?(:consumer_groups, name)
38
35
  end
39
36
 
40
37
  # Builds a topic representation inside of a current consumer group route
@@ -58,10 +58,7 @@ module Karafka
58
58
 
59
59
  # @return [Boolean] is this subscription group one of active once
60
60
  def active?
61
- sgs = Karafka::App.config.internal.routing.active.subscription_groups
62
-
63
- # When empty it means no groups were specified, hence all should be used
64
- sgs.empty? || sgs.include?(name)
61
+ Karafka::App.config.internal.routing.activity_manager.active?(:subscription_groups, name)
65
62
  end
66
63
 
67
64
  private
@@ -87,10 +87,7 @@ module Karafka
87
87
  # Never active if disabled via routing
88
88
  return false unless @active
89
89
 
90
- topics = Karafka::App.config.internal.routing.active.topics
91
-
92
- # When empty it means no topics were specified, hence all should be used
93
- topics.empty? || topics.include?(name)
90
+ Karafka::App.config.internal.routing.activity_manager.active?(:topics, name)
94
91
  end
95
92
 
96
93
  # @return [Hash] hash with all the topic attributes
@@ -33,7 +33,7 @@ module Karafka
33
33
  # We cannot validate this during the start because config needs to be populated and routes
34
34
  # need to be defined.
35
35
  Contracts::ServerCliOptions.new.validate!(
36
- Karafka::App.config.internal.routing.active.to_h
36
+ Karafka::App.config.internal.routing.activity_manager.to_h
37
37
  )
38
38
 
39
39
  process.on_sigint { stop }
@@ -111,12 +111,8 @@ module Karafka
111
111
  setting :subscription_groups_builder, default: Routing::SubscriptionGroupsBuilder.new
112
112
 
113
113
  # Internally assigned list of limits on routings active for the current process
114
- # This should be overwritten by the CLI command
115
- setting :active do
116
- setting :consumer_groups, default: [].freeze
117
- setting :subscription_groups, default: [].freeze
118
- setting :topics, default: [].freeze
119
- end
114
+ # This can be altered by the CLI command
115
+ setting :activity_manager, default: Routing::ActivityManager.new
120
116
  end
121
117
 
122
118
  setting :processing do
@@ -3,5 +3,5 @@
3
3
  # Main module namespace
4
4
  module Karafka
5
5
  # Current Karafka version
6
- VERSION = '2.0.29'
6
+ VERSION = '2.0.30'
7
7
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: karafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.29
4
+ version: 2.0.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld
@@ -35,7 +35,7 @@ cert_chain:
35
35
  Qf04B9ceLUaC4fPVEz10FyobjaFoY4i32xRto3XnrzeAgfEe4swLq8bQsR3w/EF3
36
36
  MGU0FeSV2Yj7Xc2x/7BzLK8xQn5l7Yy75iPF+KP3vVmDHnNl
37
37
  -----END CERTIFICATE-----
38
- date: 2023-01-30 00:00:00.000000000 Z
38
+ date: 2023-01-31 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: karafka-core
@@ -289,6 +289,7 @@ files:
289
289
  - lib/karafka/processing/worker.rb
290
290
  - lib/karafka/processing/workers_batch.rb
291
291
  - lib/karafka/railtie.rb
292
+ - lib/karafka/routing/activity_manager.rb
292
293
  - lib/karafka/routing/builder.rb
293
294
  - lib/karafka/routing/consumer_group.rb
294
295
  - lib/karafka/routing/consumer_mapper.rb
metadata.gz.sig CHANGED
Binary file