karafka-core 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.coditsu/ci.yml +3 -0
- data/.console_irbrc +11 -0
- data/.diffend.yml +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +74 -0
- data/.gitignore +69 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +4 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +57 -0
- data/MIT-LICENSE +18 -0
- data/README.md +21 -0
- data/certs/mensfeld.pem +25 -0
- data/config/errors.yml +10 -0
- data/karafka-core.gemspec +34 -0
- data/lib/karafka/core/configurable/leaf.rb +10 -0
- data/lib/karafka/core/configurable/node.rb +102 -0
- data/lib/karafka/core/configurable.rb +73 -0
- data/lib/karafka/core/contractable/contract.rb +185 -0
- data/lib/karafka/core/contractable/result.rb +59 -0
- data/lib/karafka/core/contractable/rule.rb +10 -0
- data/lib/karafka/core/contractable.rb +15 -0
- data/lib/karafka/core/monitoring/event.rb +26 -0
- data/lib/karafka/core/monitoring/monitor.rb +47 -0
- data/lib/karafka/core/monitoring/notifications.rb +121 -0
- data/lib/karafka/core/monitoring.rb +13 -0
- data/lib/karafka/core/version.rb +9 -0
- data/lib/karafka/core.rb +13 -0
- data/lib/karafka-core.rb +24 -0
- data/log/.gitkeep +0 -0
- data.tar.gz.sig +1 -0
- metadata +119 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
# A simple dry-configuration API compatible module for defining settings with defaults and a
|
6
|
+
# constructor.
|
7
|
+
module Configurable
|
8
|
+
# A simple settings layer that works similar to dry-configurable
|
9
|
+
# It allows us to define settings on a class and per instance level with templating on a class
|
10
|
+
# level. It handles inheritance and allows for nested settings.
|
11
|
+
#
|
12
|
+
# @note The core settings template needs to be defined on a class level
|
13
|
+
class << self
|
14
|
+
# Sets up all the class methods and inits the core root node.
|
15
|
+
# Useful when only per class settings are needed as does not include instance methods
|
16
|
+
# @param base [Class] class that we extend
|
17
|
+
def extended(base)
|
18
|
+
base.extend ClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets up all the class and instance methods and inits the core root node
|
22
|
+
#
|
23
|
+
# @param base [Class] class to which we want to add configuration
|
24
|
+
#
|
25
|
+
# Needs to be used when per instance configuration is needed
|
26
|
+
def included(base)
|
27
|
+
base.include InstanceMethods
|
28
|
+
base.extend self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Instance related methods
|
33
|
+
module InstanceMethods
|
34
|
+
# @return [Node] config root node
|
35
|
+
def config
|
36
|
+
@config ||= self.class.config.deep_dup
|
37
|
+
end
|
38
|
+
|
39
|
+
# Allows for a per instance configuration (if needed)
|
40
|
+
# @param block [Proc] block for configuration
|
41
|
+
def configure(&block)
|
42
|
+
config.configure(&block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Class related methods
|
47
|
+
module ClassMethods
|
48
|
+
# @return [Node] root node for the settings
|
49
|
+
def config
|
50
|
+
return @config if @config
|
51
|
+
|
52
|
+
# This will handle inheritance
|
53
|
+
@config = if superclass.respond_to?(:config)
|
54
|
+
superclass.config.deep_dup
|
55
|
+
else
|
56
|
+
Node.new(:root)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Allows for a per class configuration (if needed)
|
61
|
+
# @param block [Proc] block for configuration
|
62
|
+
def configure(&block)
|
63
|
+
config.configure(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Pipes the settings setup to the config root node
|
67
|
+
def setting(...)
|
68
|
+
config.setting(...)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
module Contractable
|
6
|
+
# Base contract for all the contracts that check data format
|
7
|
+
#
|
8
|
+
# @note This contract does NOT support rules inheritance as it was never needed in Karafka
|
9
|
+
class Contract
|
10
|
+
extend Core::Configurable
|
11
|
+
|
12
|
+
# Yaml based error messages data
|
13
|
+
setting(:error_messages)
|
14
|
+
|
15
|
+
# Class level API definitions
|
16
|
+
class << self
|
17
|
+
# @return [Array<Rule>] all the validation rules defined for a given contract
|
18
|
+
attr_reader :rules
|
19
|
+
|
20
|
+
# Allows for definition of a scope/namespace for nested validations
|
21
|
+
#
|
22
|
+
# @param path [Symbol] path in the hash for nesting
|
23
|
+
# @param block [Proc] nested rule code or more nestings inside
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# nested(:key) do
|
27
|
+
# required(:inside) { |inside| inside.is_a?(String) }
|
28
|
+
# end
|
29
|
+
def nested(path, &block)
|
30
|
+
init_accu
|
31
|
+
@nested << path
|
32
|
+
instance_eval(&block)
|
33
|
+
@nested.pop
|
34
|
+
end
|
35
|
+
|
36
|
+
# Defines a rule for a required field (required means, that will automatically create an
|
37
|
+
# error if missing)
|
38
|
+
#
|
39
|
+
# @param keys [Array<Symbol>] single or full path
|
40
|
+
# @param block [Proc] validation rule
|
41
|
+
def required(*keys, &block)
|
42
|
+
init_accu
|
43
|
+
@rules << Rule.new(@nested + keys, :required, block).freeze
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param keys [Array<Symbol>] single or full path
|
47
|
+
# @param block [Proc] validation rule
|
48
|
+
def optional(*keys, &block)
|
49
|
+
init_accu
|
50
|
+
@rules << Rule.new(@nested + keys, :optional, block).freeze
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param block [Proc] validation rule
|
54
|
+
#
|
55
|
+
# @note Virtual rules have different result expectations. Please see contracts or specs for
|
56
|
+
# details.
|
57
|
+
def virtual(&block)
|
58
|
+
init_accu
|
59
|
+
@rules << Rule.new([], :virtual, block).freeze
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Initializes nestings and rules building accumulator
|
65
|
+
def init_accu
|
66
|
+
@nested ||= []
|
67
|
+
@rules ||= []
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Runs the validation
|
72
|
+
#
|
73
|
+
# @param data [Hash] hash with data we want to validate
|
74
|
+
# @return [Result] validaton result
|
75
|
+
def call(data)
|
76
|
+
errors = []
|
77
|
+
|
78
|
+
self.class.rules.map do |rule|
|
79
|
+
case rule.type
|
80
|
+
when :required
|
81
|
+
validate_required(data, rule, errors)
|
82
|
+
when :optional
|
83
|
+
validate_optional(data, rule, errors)
|
84
|
+
when :virtual
|
85
|
+
validate_virtual(data, rule, errors)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Result.new(errors, self)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param data [Hash] data for validation
|
93
|
+
# @param error_class [Class] error class that should be used when validation fails
|
94
|
+
# @return [Boolean] true
|
95
|
+
# @raise [StandardError] any error provided in the error_class that inherits from the
|
96
|
+
# standard error
|
97
|
+
def validate!(data, error_class)
|
98
|
+
result = call(data)
|
99
|
+
|
100
|
+
return true if result.success?
|
101
|
+
|
102
|
+
raise error_class, result.errors
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# Runs validation for rules on fields that are required and adds errors (if any) to the
|
108
|
+
# errors array
|
109
|
+
#
|
110
|
+
# @param data [Hash] input hash
|
111
|
+
# @param rule [Rule] validation rule
|
112
|
+
# @param errors [Array] array with errors from previous rules (if any)
|
113
|
+
def validate_required(data, rule, errors)
|
114
|
+
for_checking = dig(data, rule.path)
|
115
|
+
|
116
|
+
if for_checking.first == :match
|
117
|
+
result = rule.validator.call(for_checking.last, data, errors, self)
|
118
|
+
|
119
|
+
return if result == true
|
120
|
+
|
121
|
+
errors << [rule.path, result || :format]
|
122
|
+
else
|
123
|
+
errors << [rule.path, :missing]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Runs validation for rules on fields that are optional and adds errors (if any) to the
|
128
|
+
# errors array
|
129
|
+
#
|
130
|
+
# @param data [Hash] input hash
|
131
|
+
# @param rule [Rule] validation rule
|
132
|
+
# @param errors [Array] array with errors from previous rules (if any)
|
133
|
+
def validate_optional(data, rule, errors)
|
134
|
+
for_checking = dig(data, rule.path)
|
135
|
+
|
136
|
+
return unless for_checking.first == :match
|
137
|
+
|
138
|
+
result = rule.validator.call(for_checking.last, data, errors, self)
|
139
|
+
|
140
|
+
return if result == true
|
141
|
+
|
142
|
+
errors << [rule.path, result || :format]
|
143
|
+
end
|
144
|
+
|
145
|
+
# Runs validation for rules on virtual fields (aggregates, etc) and adds errors (if any) to
|
146
|
+
# the errors array
|
147
|
+
#
|
148
|
+
# @param data [Hash] input hash
|
149
|
+
# @param rule [Rule] validation rule
|
150
|
+
# @param errors [Array] array with errors from previous rules (if any)
|
151
|
+
def validate_virtual(data, rule, errors)
|
152
|
+
result = rule.validator.call(data, errors, self)
|
153
|
+
|
154
|
+
return if result == true
|
155
|
+
|
156
|
+
errors.push(*result)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Tries to dig for a given key in a hash and returns it with indication whether or not it was
|
160
|
+
# possible to find it (dig returns nil and we don't know if it wasn't the digged key value)
|
161
|
+
#
|
162
|
+
# @param data [Hash]
|
163
|
+
# @param keys [Array<Symbol>]
|
164
|
+
# @return [Array<Symbol, Object>] array where the first element is `:match` or `:miss` and
|
165
|
+
# the digged value or nil if not found
|
166
|
+
def dig(data, keys)
|
167
|
+
current = data
|
168
|
+
result = :match
|
169
|
+
|
170
|
+
keys.each do |nesting|
|
171
|
+
unless current.key?(nesting)
|
172
|
+
result = :miss
|
173
|
+
|
174
|
+
break
|
175
|
+
end
|
176
|
+
|
177
|
+
current = current[nesting]
|
178
|
+
end
|
179
|
+
|
180
|
+
[result, current]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
module Contractable
|
6
|
+
# Representation of a validaton result with resolved error messages
|
7
|
+
class Result
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
# Builds a result object and remaps (if needed) error keys to proper error messages
|
11
|
+
#
|
12
|
+
# @param errors [Array<Array>] array with sub-arrays with paths and error keys
|
13
|
+
# @param contract [Object] contract that generated the error
|
14
|
+
def initialize(errors, contract)
|
15
|
+
# Short track to skip object allocation for the happy path
|
16
|
+
if errors.empty?
|
17
|
+
@errors = errors
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
hashed = {}
|
22
|
+
|
23
|
+
errors.each do |error|
|
24
|
+
scope = error.first.map(&:to_s).join('.').to_sym
|
25
|
+
|
26
|
+
# This will allow for usage of custom messages instead of yaml keys if needed
|
27
|
+
hashed[scope] = if error.last.is_a?(String)
|
28
|
+
error.last
|
29
|
+
else
|
30
|
+
build_message(contract, scope, error.last)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@errors = hashed
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Boolean] true if no errors
|
38
|
+
def success?
|
39
|
+
errors.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Builds message based on the error messages
|
45
|
+
# @param contract [Object] contract for which we build the result
|
46
|
+
# @param scope [Symbol] path to the key that has an error
|
47
|
+
# @param error_key [Symbol] error key for yaml errors lookup
|
48
|
+
# @return [String] error message
|
49
|
+
def build_message(contract, scope, error_key)
|
50
|
+
messages = contract.class.config.error_messages
|
51
|
+
|
52
|
+
messages.fetch(error_key.to_s) do
|
53
|
+
messages.fetch("#{scope}_#{error_key}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
# Contract layer for the Karafka ecosystem
|
6
|
+
# It aims to be "dry-validation" like but smaller and easier to handle + without dependencies
|
7
|
+
#
|
8
|
+
# It allows for nested validations, etc
|
9
|
+
#
|
10
|
+
# @note It is thread-safe to run but validations definitions should happen before threads are
|
11
|
+
# used.
|
12
|
+
module Contractable
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
module Monitoring
|
6
|
+
# Single notification event wrapping payload with id
|
7
|
+
class Event
|
8
|
+
attr_reader :id, :payload
|
9
|
+
|
10
|
+
# @param id [String, Symbol] id of the event
|
11
|
+
# @param payload [Hash] event payload
|
12
|
+
def initialize(id, payload)
|
13
|
+
@id = id
|
14
|
+
@payload = payload
|
15
|
+
end
|
16
|
+
|
17
|
+
# Hash access to the payload data (if present)
|
18
|
+
#
|
19
|
+
# @param [String, Symbol] name
|
20
|
+
def [](name)
|
21
|
+
@payload.fetch(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
module Monitoring
|
6
|
+
# Karafka monitor that can be used to pass through instrumentation calls to selected
|
7
|
+
# notifications bus.
|
8
|
+
#
|
9
|
+
# It provides abstraction layer that allows us to use both our internal notifications as well
|
10
|
+
# as `ActiveSupport::Notifications`.
|
11
|
+
class Monitor
|
12
|
+
# Empty has to save on objects allocation
|
13
|
+
EMPTY_HASH = {}.freeze
|
14
|
+
|
15
|
+
private_constant :EMPTY_HASH
|
16
|
+
|
17
|
+
# @param notifications_bus [Object] either our internal notifications bus or
|
18
|
+
# `ActiveSupport::Notifications`
|
19
|
+
# @param namespace [String, nil] namespace for events or nil if no namespace
|
20
|
+
def initialize(notifications_bus, namespace = nil)
|
21
|
+
@notifications_bus = notifications_bus
|
22
|
+
@namespace = namespace
|
23
|
+
@mapped_events = Concurrent::Map.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# Passes the instrumentation block (if any) into the notifications bus
|
27
|
+
#
|
28
|
+
# @param event_id [String, Symbol] event id
|
29
|
+
# @param payload [Hash]
|
30
|
+
# @param block [Proc] block we want to instrument (if any)
|
31
|
+
def instrument(event_id, payload = EMPTY_HASH, &block)
|
32
|
+
full_event_name = @mapped_events[event_id] ||= [event_id, @namespace].compact.join('.')
|
33
|
+
|
34
|
+
@notifications_bus.instrument(full_event_name, payload, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Allows us to subscribe to the notification bus
|
38
|
+
#
|
39
|
+
# @param args [Array] any arguments that the notification bus subscription layer accepts
|
40
|
+
# @param block [Proc] optional block for subscription
|
41
|
+
def subscribe(*args, &block)
|
42
|
+
@notifications_bus.subscribe(*args, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Core
|
5
|
+
module Monitoring
|
6
|
+
# A simple notifications layer for Karafka ecosystem that aims to provide API compatible
|
7
|
+
# with both `ActiveSupport::Notifications` and `dry-monitor`.
|
8
|
+
#
|
9
|
+
# We do not use any of them by default as our use-case is fairly simple and we do not want
|
10
|
+
# to have too many external dependencies.
|
11
|
+
class Notifications
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
# Raised when someone wants to publish event that was not registered
|
15
|
+
EventNotRegistered = Class.new(StandardError)
|
16
|
+
|
17
|
+
# Empty hash for internal referencing
|
18
|
+
EMPTY_HASH = {}.freeze
|
19
|
+
|
20
|
+
private_constant :EMPTY_HASH
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@listeners = Concurrent::Map.new { |k, v| k[v] = Concurrent::Array.new }
|
24
|
+
# This allows us to optimize the method calling lookups
|
25
|
+
@events_methods_map = Concurrent::Map.new
|
26
|
+
end
|
27
|
+
|
28
|
+
# Registers a new event on which we can publish
|
29
|
+
#
|
30
|
+
# @param event_id [String, Symbol] event id
|
31
|
+
def register_event(event_id)
|
32
|
+
@listeners[event_id]
|
33
|
+
@events_methods_map[event_id] = :"on_#{event_id.to_s.tr('.', '_')}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Clears all the subscribed listeners
|
37
|
+
def clear
|
38
|
+
@listeners.each_value(&:clear)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Allows for subscription to an event
|
42
|
+
# There are two ways you can subscribe: via block or via listener.
|
43
|
+
#
|
44
|
+
# @param event_id_or_listener [Object] event id when we want to subscribe to a particular
|
45
|
+
# event with a block or listener if we want to subscribe with general listener
|
46
|
+
# @param block [Proc] block of code if we want to subscribe with it
|
47
|
+
#
|
48
|
+
# @example Subscribe using listener
|
49
|
+
# subscribe(MyListener.new)
|
50
|
+
#
|
51
|
+
# @example Subscribe via block
|
52
|
+
# subscribe do |event|
|
53
|
+
# puts event
|
54
|
+
# end
|
55
|
+
def subscribe(event_id_or_listener, &block)
|
56
|
+
if block
|
57
|
+
event_id = event_id_or_listener
|
58
|
+
|
59
|
+
raise EventNotRegistered, event_id unless @listeners.key?(event_id)
|
60
|
+
|
61
|
+
@listeners[event_id] << block
|
62
|
+
else
|
63
|
+
listener = event_id_or_listener
|
64
|
+
|
65
|
+
@listeners.each_key do |reg_event_id|
|
66
|
+
next unless listener.respond_to?(@events_methods_map[reg_event_id])
|
67
|
+
|
68
|
+
@listeners[reg_event_id] << listener
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Allows for code instrumentation
|
74
|
+
# Runs the provided code and sends the instrumentation details to all registered listeners
|
75
|
+
#
|
76
|
+
# @param event_id [String, Symbol] id of the event
|
77
|
+
# @param payload [Hash] payload for the instrumentation
|
78
|
+
# @param block [Proc] instrumented code
|
79
|
+
# @return [Object] whatever the provided block (if any) returns
|
80
|
+
#
|
81
|
+
# @example Instrument some code
|
82
|
+
# instrument('sleeping') do
|
83
|
+
# sleep(1)
|
84
|
+
# end
|
85
|
+
def instrument(event_id, payload = EMPTY_HASH, &block)
|
86
|
+
result, time = measure_time_taken(&block) if block_given?
|
87
|
+
|
88
|
+
event = Event.new(
|
89
|
+
event_id,
|
90
|
+
time ? payload.merge(time: time) : payload
|
91
|
+
)
|
92
|
+
|
93
|
+
@listeners[event_id].each do |listener|
|
94
|
+
if listener.is_a?(Proc)
|
95
|
+
listener.call(event)
|
96
|
+
else
|
97
|
+
listener.send(@events_methods_map[event_id], event)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Measures time taken to execute a given block and returns it together with the result of
|
107
|
+
# the block execution
|
108
|
+
def measure_time_taken
|
109
|
+
start = current_time
|
110
|
+
result = yield
|
111
|
+
[result, current_time - start]
|
112
|
+
end
|
113
|
+
|
114
|
+
# @return [Integer] current monotonic time
|
115
|
+
def current_time
|
116
|
+
::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Main module namespace
|
4
|
+
module Karafka
|
5
|
+
module Core
|
6
|
+
# Monitoring for Karafka and WaterDrop
|
7
|
+
# It allows us to have a layer that can work with `dry-monitor` as well as
|
8
|
+
# `ActiveSupport::Notifications` or standalone depending on the case. Thanks to that we do not
|
9
|
+
# have to rely on third party tools that could break.
|
10
|
+
module Monitoring
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/karafka/core.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
# Namespace for small support modules used throughout the Karafka ecosystem
|
5
|
+
module Core
|
6
|
+
class << self
|
7
|
+
# @return [String] root path of this gem
|
8
|
+
def gem_root
|
9
|
+
Pathname.new(File.expand_path('../..', __dir__))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/karafka-core.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
%w[
|
4
|
+
yaml
|
5
|
+
concurrent/map
|
6
|
+
concurrent/hash
|
7
|
+
concurrent/array
|
8
|
+
karafka/core
|
9
|
+
karafka/core/version
|
10
|
+
karafka/core/monitoring
|
11
|
+
karafka/core/monitoring/event
|
12
|
+
karafka/core/monitoring/monitor
|
13
|
+
karafka/core/monitoring/notifications
|
14
|
+
karafka/core/configurable
|
15
|
+
karafka/core/configurable/leaf
|
16
|
+
karafka/core/configurable/node
|
17
|
+
karafka/core/contractable/contract
|
18
|
+
karafka/core/contractable/result
|
19
|
+
karafka/core/contractable/rule
|
20
|
+
].each { |dependency| require dependency }
|
21
|
+
|
22
|
+
# Karafka framework main namespace
|
23
|
+
module Karafka
|
24
|
+
end
|
data/log/.gitkeep
ADDED
File without changes
|
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
�nnDV��c�"TP��Wo�5���"��T3��ѕ��������U���ye��)�Pt�
|