karafka 2.0.38 → 2.0.39

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +1 -1
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +28 -0
  6. data/Gemfile.lock +4 -4
  7. data/bin/integrations +1 -1
  8. data/config/locales/errors.yml +0 -7
  9. data/config/locales/pro_errors.yml +18 -0
  10. data/lib/karafka/base_consumer.rb +35 -55
  11. data/lib/karafka/connection/listener.rb +15 -10
  12. data/lib/karafka/errors.rb +0 -3
  13. data/lib/karafka/instrumentation/logger_listener.rb +44 -3
  14. data/lib/karafka/instrumentation/notifications.rb +4 -0
  15. data/lib/karafka/pro/active_job/consumer.rb +10 -1
  16. data/lib/karafka/pro/processing/coordinator.rb +13 -4
  17. data/lib/karafka/pro/processing/filters/base.rb +61 -0
  18. data/lib/karafka/pro/processing/filters/delayer.rb +70 -0
  19. data/lib/karafka/pro/processing/filters/expirer.rb +51 -0
  20. data/lib/karafka/pro/processing/filters/throttler.rb +84 -0
  21. data/lib/karafka/pro/processing/filters_applier.rb +100 -0
  22. data/lib/karafka/pro/processing/jobs_builder.rb +7 -3
  23. data/lib/karafka/pro/processing/scheduler.rb +24 -7
  24. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +68 -0
  25. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +74 -0
  26. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +72 -0
  27. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +76 -0
  28. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +62 -0
  29. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +68 -0
  30. data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +64 -0
  31. data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +69 -0
  32. data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +38 -0
  33. data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +64 -0
  34. data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +38 -0
  35. data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +58 -0
  36. data/lib/karafka/pro/processing/strategies/{dlq_lrj_vp.rb → aj/lrj_mom.rb} +14 -13
  37. data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +77 -0
  38. data/lib/karafka/pro/processing/strategies/aj/mom.rb +36 -0
  39. data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +52 -0
  40. data/lib/karafka/pro/processing/strategies/dlq/default.rb +131 -0
  41. data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +61 -0
  42. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +75 -0
  43. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +74 -0
  44. data/lib/karafka/pro/processing/strategies/{mom.rb → dlq/ftr_lrj_vp.rb} +16 -19
  45. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +73 -0
  46. data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +39 -0
  47. data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +63 -0
  48. data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +66 -0
  49. data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +38 -0
  50. data/lib/karafka/pro/processing/strategies/dlq/mom.rb +67 -0
  51. data/lib/karafka/pro/processing/strategies/dlq/vp.rb +39 -0
  52. data/lib/karafka/pro/processing/strategies/ftr/default.rb +104 -0
  53. data/lib/karafka/pro/processing/strategies/ftr/vp.rb +40 -0
  54. data/lib/karafka/pro/processing/strategies/lrj/default.rb +85 -0
  55. data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +69 -0
  56. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +67 -0
  57. data/lib/karafka/pro/processing/strategies/{vp.rb → lrj/ftr_vp.rb} +15 -13
  58. data/lib/karafka/pro/processing/strategies/lrj/mom.rb +78 -0
  59. data/lib/karafka/pro/processing/strategies/{aj_lrj_mom.rb → lrj/vp.rb} +13 -12
  60. data/lib/karafka/pro/processing/strategies/mom/default.rb +46 -0
  61. data/lib/karafka/pro/processing/strategies/mom/ftr.rb +53 -0
  62. data/lib/karafka/pro/processing/strategies/vp/default.rb +53 -0
  63. data/lib/karafka/pro/processing/{strategies/lrj_vp.rb → strategies.rb} +1 -13
  64. data/lib/karafka/pro/processing/strategy_selector.rb +44 -18
  65. data/lib/karafka/pro/{processing/strategies/aj_mom.rb → routing/features/delaying/config.rb} +7 -13
  66. data/lib/karafka/pro/routing/features/delaying/contract.rb +38 -0
  67. data/lib/karafka/pro/routing/features/delaying/topic.rb +59 -0
  68. data/lib/karafka/pro/routing/features/delaying.rb +29 -0
  69. data/lib/karafka/pro/routing/features/expiring/config.rb +27 -0
  70. data/lib/karafka/pro/routing/features/expiring/contract.rb +38 -0
  71. data/lib/karafka/pro/routing/features/expiring/topic.rb +59 -0
  72. data/lib/karafka/pro/routing/features/expiring.rb +27 -0
  73. data/lib/karafka/pro/routing/features/filtering/config.rb +40 -0
  74. data/lib/karafka/pro/routing/features/filtering/contract.rb +41 -0
  75. data/lib/karafka/pro/routing/features/filtering/topic.rb +51 -0
  76. data/lib/karafka/pro/routing/features/filtering.rb +27 -0
  77. data/lib/karafka/pro/routing/features/long_running_job/contract.rb +1 -1
  78. data/lib/karafka/pro/routing/features/throttling/config.rb +32 -0
  79. data/lib/karafka/pro/routing/features/throttling/contract.rb +41 -0
  80. data/lib/karafka/pro/routing/features/throttling/topic.rb +69 -0
  81. data/lib/karafka/pro/routing/features/throttling.rb +30 -0
  82. data/lib/karafka/processing/coordinator.rb +60 -30
  83. data/lib/karafka/processing/coordinators_buffer.rb +5 -1
  84. data/lib/karafka/processing/executor.rb +23 -16
  85. data/lib/karafka/processing/executors_buffer.rb +10 -26
  86. data/lib/karafka/processing/jobs/consume.rb +2 -4
  87. data/lib/karafka/processing/jobs/idle.rb +24 -0
  88. data/lib/karafka/processing/jobs_builder.rb +2 -3
  89. data/lib/karafka/processing/result.rb +5 -0
  90. data/lib/karafka/processing/strategies/aj_dlq_mom.rb +1 -1
  91. data/lib/karafka/processing/strategies/base.rb +5 -0
  92. data/lib/karafka/processing/strategies/default.rb +50 -0
  93. data/lib/karafka/processing/strategies/dlq.rb +13 -4
  94. data/lib/karafka/processing/strategies/dlq_mom.rb +8 -3
  95. data/lib/karafka/processing/strategy_selector.rb +27 -10
  96. data/lib/karafka/version.rb +1 -1
  97. data/renovate.json +6 -0
  98. data.tar.gz.sig +0 -0
  99. metadata +66 -22
  100. metadata.gz.sig +0 -0
  101. data/lib/karafka/pro/processing/strategies/aj_dlq_lrj_mom.rb +0 -42
  102. data/lib/karafka/pro/processing/strategies/aj_dlq_lrj_mom_vp.rb +0 -70
  103. data/lib/karafka/pro/processing/strategies/aj_dlq_mom.rb +0 -62
  104. data/lib/karafka/pro/processing/strategies/aj_dlq_mom_vp.rb +0 -68
  105. data/lib/karafka/pro/processing/strategies/aj_lrj_mom_vp.rb +0 -75
  106. data/lib/karafka/pro/processing/strategies/aj_mom_vp.rb +0 -62
  107. data/lib/karafka/pro/processing/strategies/dlq.rb +0 -120
  108. data/lib/karafka/pro/processing/strategies/dlq_lrj.rb +0 -65
  109. data/lib/karafka/pro/processing/strategies/dlq_lrj_mom.rb +0 -62
  110. data/lib/karafka/pro/processing/strategies/dlq_mom.rb +0 -62
  111. data/lib/karafka/pro/processing/strategies/dlq_vp.rb +0 -37
  112. data/lib/karafka/pro/processing/strategies/lrj.rb +0 -83
  113. data/lib/karafka/pro/processing/strategies/lrj_mom.rb +0 -73
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Processing
17
+ module Strategies
18
+ module Mom
19
+ # Filtering support for MoM
20
+ module Ftr
21
+ include Strategies::Ftr::Default
22
+ include Strategies::Mom::Default
23
+
24
+ # MoM + Ftr
25
+ FEATURES = %i[
26
+ filtering
27
+ manual_offset_management
28
+ ].freeze
29
+
30
+ # When mom is enabled, we do not mark messages as consumed after processing
31
+ # but we also need to keep in mind throttling here
32
+ def handle_after_consume
33
+ coordinator.on_finished do
34
+ return if revoked?
35
+
36
+ if coordinator.success?
37
+ coordinator.pause_tracker.reset
38
+
39
+ # Do not throttle if paused
40
+ return if coordinator.manual_pause?
41
+
42
+ handle_post_filtering
43
+ else
44
+ retry_after_pause
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Processing
17
+ module Strategies
18
+ # VP starting strategies
19
+ module Vp
20
+ # Just Virtual Partitions enabled
21
+ module Default
22
+ # This flow is exactly the same as the default one because the default one is wrapper
23
+ # with `coordinator#on_finished`
24
+ include Strategies::Default
25
+
26
+ # Features for this strategy
27
+ FEATURES = %i[
28
+ virtual_partitions
29
+ ].freeze
30
+
31
+ # @return [Boolean] is the virtual processing collapsed in the context of given
32
+ # consumer.
33
+ def collapsed?
34
+ coordinator.collapsed?
35
+ end
36
+
37
+ # @return [Boolean] true if any of virtual partition we're operating in the entangled
38
+ # mode has already failed and we know we are failing collectively.
39
+ # Useful for early stop to minimize number of things processed twice.
40
+ #
41
+ # @note We've named it `#failing?` instead of `#failure?` because it aims to be used
42
+ # from within virtual partitions where we want to have notion of collective failing
43
+ # not just "local" to our processing. We "are" failing with other virtual partitions
44
+ # raising an error, but locally we are still processing.
45
+ def failing?
46
+ coordinator.failure?
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -14,20 +14,8 @@
14
14
  module Karafka
15
15
  module Pro
16
16
  module Processing
17
+ # Pro processing strategies namespace
17
18
  module Strategies
18
- # Long-Running Job enabled
19
- # Virtual Partitions enabled
20
- module LrjVp
21
- # Same flow as the standard Lrj
22
- include Vp
23
- include Lrj
24
-
25
- # Features for this strategy
26
- FEATURES = %i[
27
- long_running_job
28
- virtual_partitions
29
- ].freeze
30
- end
31
19
  end
32
20
  end
33
21
  end
@@ -18,39 +18,65 @@ module Karafka
18
18
  # When using Karafka Pro, there is a different set of strategies than for regular, as there
19
19
  # are different features.
20
20
  class StrategySelector
21
+ attr_reader :strategies
22
+
23
+ # Strategies that we support in the Pro offering
24
+ # They can be combined
25
+ SUPPORTED_FEATURES = %i[
26
+ active_job
27
+ long_running_job
28
+ manual_offset_management
29
+ virtual_partitions
30
+ dead_letter_queue
31
+ filtering
32
+ ].freeze
33
+
21
34
  def initialize
35
+ # Preload the strategies
22
36
  # We load them once for performance reasons not to do too many lookups
23
- @available_strategies = Strategies
24
- .constants
25
- .delete_if { |k| k == :Base }
26
- .map { |k| Strategies.const_get(k) }
37
+ @strategies = find_all
27
38
  end
28
39
 
29
40
  # @param topic [Karafka::Routing::Topic] topic with settings based on which we find
30
41
  # the strategy
31
42
  # @return [Module] module with proper strategy
32
43
  def find(topic)
33
- feature_set = features_map(topic)
44
+ feature_set = SUPPORTED_FEATURES.map do |feature_name|
45
+ topic.public_send("#{feature_name}?") ? feature_name : nil
46
+ end
34
47
 
35
- @available_strategies.find do |strategy|
48
+ feature_set.compact!
49
+ feature_set.sort!
50
+
51
+ @strategies.find do |strategy|
36
52
  strategy::FEATURES.sort == feature_set
37
53
  end || raise(Errors::StrategyNotFoundError, topic.name)
38
54
  end
39
55
 
40
56
  private
41
57
 
42
- # Builds features map used to find matching processing strategy
43
- #
44
- # @param topic [Karafka::Routing::Topic]
45
- # @return [Array<Symbol>]
46
- def features_map(topic)
47
- [
48
- topic.active_job? ? :active_job : nil,
49
- topic.long_running_job? ? :long_running_job : nil,
50
- topic.manual_offset_management? ? :manual_offset_management : nil,
51
- topic.virtual_partitions? ? :virtual_partitions : nil,
52
- topic.dead_letter_queue? ? :dead_letter_queue : nil
53
- ].compact.sort
58
+ # @return [Array<Module>] all available strategies
59
+ def find_all
60
+ scopes = [Strategies]
61
+ modules = Strategies.constants
62
+
63
+ modules.each do |const|
64
+ scopes << Strategies.const_get(const)
65
+ modules += scopes.last.constants
66
+ end
67
+
68
+ scopes.flat_map do |scope|
69
+ modules.map do |const|
70
+ next if const == :FEATURES
71
+ next unless scope.const_defined?(const)
72
+
73
+ candidate = scope.const_get(const)
74
+
75
+ next unless candidate.const_defined?(:FEATURES)
76
+
77
+ candidate
78
+ end
79
+ end.uniq.compact
54
80
  end
55
81
  end
56
82
  end
@@ -13,19 +13,13 @@
13
13
 
14
14
  module Karafka
15
15
  module Pro
16
- module Processing
17
- module Strategies
18
- # ActiveJob enabled
19
- # Manual Offset management enabled
20
- module AjMom
21
- # Standard ActiveJob strategy is the same one we use for Mom
22
- include Mom
23
-
24
- # Features for this strategy
25
- FEATURES = %i[
26
- active_job
27
- manual_offset_management
28
- ].freeze
16
+ module Routing
17
+ module Features
18
+ class Delaying < Base
19
+ # Delaying feature configuration
20
+ Config = Struct.new(:active, :delay, keyword_init: true) do
21
+ alias_method :active?, :active
22
+ end
29
23
  end
30
24
  end
31
25
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Delaying < Base
19
+ # Contract to validate configuration of the expiring feature
20
+ class Contract < Contracts::Base
21
+ configure do |config|
22
+ config.error_messages = YAML.safe_load(
23
+ File.read(
24
+ File.join(Karafka.gem_root, 'config', 'locales', 'pro_errors.yml')
25
+ )
26
+ ).fetch('en').fetch('validations').fetch('topic')
27
+ end
28
+
29
+ nested(:delaying) do
30
+ required(:active) { |val| [true, false].include?(val) }
31
+ required(:delay) { |val| val.nil? || (val.is_a?(Integer) && val.positive?) }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Delaying < Base
19
+ # Topic delaying API extensions
20
+ module Topic
21
+ # @param delay [Integer, nil] minimum age of a message we want to process
22
+ def delaying(delay = nil)
23
+ # Those settings are used for validation
24
+ @delaying ||= begin
25
+ config = Config.new(active: !delay.nil?, delay: delay)
26
+
27
+ if config.active?
28
+ factory = ->(*) { Pro::Processing::Filters::Delayer.new(delay) }
29
+ filter(factory)
30
+ end
31
+
32
+ config
33
+ end
34
+ end
35
+
36
+ # Just an alias for nice API
37
+ #
38
+ # @param args [Array] Anything `#delaying` accepts
39
+ def delay_by(*args)
40
+ delaying(*args)
41
+ end
42
+
43
+ # @return [Boolean] is a given job delaying
44
+ def delaying?
45
+ delaying.active?
46
+ end
47
+
48
+ # @return [Hash] topic with all its native configuration options plus delaying
49
+ def to_h
50
+ super.merge(
51
+ delaying: delaying.to_h
52
+ ).freeze
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ # Delaying allows us to delay processing of certain topics. This is useful when we want
19
+ # to for any reason to wait until processing data from a topic. It does not sleep and
20
+ # instead uses pausing to manage delays. This allows us to free up processing resources
21
+ # and not block the polling thread.
22
+ #
23
+ # Delaying is a virtual feature realized via the filters
24
+ class Delaying < Base
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Expiring < Base
19
+ # Expiring feature configuration
20
+ Config = Struct.new(:active, :ttl, keyword_init: true) do
21
+ alias_method :active?, :active
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Expiring < Base
19
+ # Contract to validate configuration of the expiring feature
20
+ class Contract < Contracts::Base
21
+ configure do |config|
22
+ config.error_messages = YAML.safe_load(
23
+ File.read(
24
+ File.join(Karafka.gem_root, 'config', 'locales', 'pro_errors.yml')
25
+ )
26
+ ).fetch('en').fetch('validations').fetch('topic')
27
+ end
28
+
29
+ nested(:expiring) do
30
+ required(:active) { |val| [true, false].include?(val) }
31
+ required(:ttl) { |val| val.nil? || (val.is_a?(Integer) && val.positive?) }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Expiring < Base
19
+ # Topic expiring API extensions
20
+ module Topic
21
+ # @param ttl [Integer, nil] maximum time in ms a message is considered alive
22
+ def expiring(ttl = nil)
23
+ # Those settings are used for validation
24
+ @expiring ||= begin
25
+ config = Config.new(active: !ttl.nil?, ttl: ttl)
26
+
27
+ if config.active?
28
+ factory = ->(*) { Pro::Processing::Filters::Expirer.new(ttl) }
29
+ filter(factory)
30
+ end
31
+
32
+ config
33
+ end
34
+ end
35
+
36
+ # Just an alias for nice API
37
+ #
38
+ # @param args [Array] Anything `#expiring` accepts
39
+ def expire_in(*args)
40
+ expiring(*args)
41
+ end
42
+
43
+ # @return [Boolean] is a given job expiring
44
+ def expiring?
45
+ expiring.active?
46
+ end
47
+
48
+ # @return [Hash] topic with all its native configuration options plus expiring
49
+ def to_h
50
+ super.merge(
51
+ expiring: expiring.to_h
52
+ ).freeze
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ # Expiring allows us to filter out messages that are older than our expectation.
19
+ # This can also be done in a consumer, but applying the filtering prior to the jobs
20
+ # enqueuing allows us to improve operations with virtual partitions and limit the number of
21
+ # not necessary messages being ever seen
22
+ class Expiring < Base
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Filtering < Base
19
+ # Filtering feature configuration
20
+ Config = Struct.new(:factories, keyword_init: true) do
21
+ # @return [Boolean] is this feature in use. Are any filters defined
22
+ def active?
23
+ !factories.empty?
24
+ end
25
+
26
+ # @return [Array<Object>] array of filters applicable to a topic partition
27
+ def filters
28
+ factories.map(&:call)
29
+ end
30
+
31
+ # @return [Hash] this config hash
32
+ def to_h
33
+ super.merge(active: active?)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Filtering < Base
19
+ # Contract to validate configuration of the filtering feature
20
+ class Contract < Contracts::Base
21
+ configure do |config|
22
+ config.error_messages = YAML.safe_load(
23
+ File.read(
24
+ File.join(Karafka.gem_root, 'config', 'locales', 'pro_errors.yml')
25
+ )
26
+ ).fetch('en').fetch('validations').fetch('topic')
27
+ end
28
+
29
+ nested(:filtering) do
30
+ required(:active) { |val| [true, false].include?(val) }
31
+
32
+ required(:factories) do |val|
33
+ val.is_a?(Array) && val.all? { |factory| factory.respond_to?(:call) }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ module Routing
17
+ module Features
18
+ class Filtering < Base
19
+ # Filtering feature topic extensions
20
+ module Topic
21
+ # @param factory [#call, nil] Callable that can produce new filters instances per
22
+ # assigned topic partition. nil as default so this feature is disabled
23
+ def filter(factory = nil)
24
+ @filtering ||= Config.new(factories: [])
25
+ @filtering.factories << factory if factory
26
+ @filtering
27
+ end
28
+
29
+ # @param args [Array] Anything `#filter` accepts
30
+ # @return [Filtering::Config] alias to match the naming API for features
31
+ def filtering(*args)
32
+ filter(*args)
33
+ end
34
+
35
+ # @return [Boolean] is a given job throttled
36
+ def filtering?
37
+ filtering.active?
38
+ end
39
+
40
+ # @return [Hash] topic with all its native configuration options plus throttling
41
+ def to_h
42
+ super.merge(
43
+ filtering: filtering.to_h
44
+ ).freeze
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end