karafka 0.5.0.3 → 0.6.0.rc1
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.
- checksums.yaml +4 -4
- data/.console_irbrc +13 -0
- data/.github/ISSUE_TEMPLATE.md +2 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +59 -1
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +67 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +46 -147
- data/README.md +51 -952
- data/Rakefile +5 -14
- data/karafka.gemspec +19 -13
- data/lib/karafka.rb +7 -4
- data/lib/karafka/app.rb +10 -6
- data/lib/karafka/attributes_map.rb +67 -0
- data/lib/karafka/base_controller.rb +42 -52
- data/lib/karafka/base_responder.rb +30 -14
- data/lib/karafka/base_worker.rb +11 -26
- data/lib/karafka/cli.rb +2 -0
- data/lib/karafka/cli/base.rb +2 -0
- data/lib/karafka/cli/console.rb +7 -1
- data/lib/karafka/cli/flow.rb +13 -13
- data/lib/karafka/cli/info.rb +7 -4
- data/lib/karafka/cli/install.rb +4 -3
- data/lib/karafka/cli/server.rb +3 -1
- data/lib/karafka/cli/worker.rb +2 -0
- data/lib/karafka/connection/config_adapter.rb +103 -0
- data/lib/karafka/connection/listener.rb +16 -12
- data/lib/karafka/connection/messages_consumer.rb +86 -0
- data/lib/karafka/connection/messages_processor.rb +74 -0
- data/lib/karafka/errors.rb +15 -29
- data/lib/karafka/fetcher.rb +10 -8
- data/lib/karafka/helpers/class_matcher.rb +2 -0
- data/lib/karafka/helpers/config_retriever.rb +46 -0
- data/lib/karafka/helpers/multi_delegator.rb +2 -0
- data/lib/karafka/loader.rb +4 -2
- data/lib/karafka/logger.rb +37 -36
- data/lib/karafka/monitor.rb +3 -1
- data/lib/karafka/params/interchanger.rb +2 -0
- data/lib/karafka/params/params.rb +34 -41
- data/lib/karafka/params/params_batch.rb +46 -0
- data/lib/karafka/parsers/json.rb +4 -2
- data/lib/karafka/patches/dry_configurable.rb +2 -0
- data/lib/karafka/process.rb +4 -2
- data/lib/karafka/responders/builder.rb +2 -0
- data/lib/karafka/responders/topic.rb +14 -6
- data/lib/karafka/routing/builder.rb +22 -59
- data/lib/karafka/routing/consumer_group.rb +54 -0
- data/lib/karafka/routing/mapper.rb +2 -0
- data/lib/karafka/routing/proxy.rb +37 -0
- data/lib/karafka/routing/router.rb +18 -16
- data/lib/karafka/routing/topic.rb +78 -0
- data/lib/karafka/schemas/config.rb +36 -0
- data/lib/karafka/schemas/consumer_group.rb +56 -0
- data/lib/karafka/schemas/responder_usage.rb +38 -0
- data/lib/karafka/server.rb +5 -3
- data/lib/karafka/setup/config.rb +79 -32
- data/lib/karafka/setup/configurators/base.rb +2 -0
- data/lib/karafka/setup/configurators/celluloid.rb +2 -0
- data/lib/karafka/setup/configurators/sidekiq.rb +2 -0
- data/lib/karafka/setup/configurators/water_drop.rb +15 -3
- data/lib/karafka/status.rb +2 -0
- data/lib/karafka/templates/app.rb.example +15 -5
- data/lib/karafka/templates/application_worker.rb.example +0 -6
- data/lib/karafka/version.rb +2 -1
- data/lib/karafka/workers/builder.rb +2 -0
- metadata +109 -60
- data/lib/karafka/cli/routes.rb +0 -36
- data/lib/karafka/connection/consumer.rb +0 -33
- data/lib/karafka/connection/message.rb +0 -17
- data/lib/karafka/connection/topic_consumer.rb +0 -94
- data/lib/karafka/responders/usage_validator.rb +0 -60
- data/lib/karafka/routing/route.rb +0 -113
- data/lib/karafka/setup/config_schema.rb +0 -44
- data/lib/karafka/setup/configurators/worker_glass.rb +0 -13
- data/lib/karafka/templates/config.ru.example +0 -13
data/lib/karafka/cli/routes.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
# Karafka framework Cli
|
3
|
-
class Cli
|
4
|
-
# Routes Karafka Cli action
|
5
|
-
class Routes < Base
|
6
|
-
desc 'Print out all defined routes in alphabetical order'
|
7
|
-
option aliases: 'r'
|
8
|
-
|
9
|
-
# Print out all defined routes in alphabetical order
|
10
|
-
def call
|
11
|
-
routes.each do |route|
|
12
|
-
puts "#{route.topic}:"
|
13
|
-
Karafka::Routing::Route::ATTRIBUTES.each do |attr|
|
14
|
-
print(attr.to_s.capitalize, route.public_send(attr))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# @return [Array<Karafka::Routing::Route>] all routes sorted in alphabetical order
|
22
|
-
def routes
|
23
|
-
Karafka::App.routes.sort do |route1, route2|
|
24
|
-
route1.topic <=> route2.topic
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Prints a given value with label in a nice way
|
29
|
-
# @param label [String] label describing value
|
30
|
-
# @param value [String] value that should be printed
|
31
|
-
def print(label, value)
|
32
|
-
printf "%-18s %s\n", " - #{label}:", value
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Connection
|
3
|
-
# Class that consumes messages for which we listen
|
4
|
-
class Consumer
|
5
|
-
# Consumes a message (does something with it)
|
6
|
-
# It will execute a scheduling task from a proper controller based on a message topic
|
7
|
-
# @note This should be looped to obtain a constant listening
|
8
|
-
# @note We catch all the errors here, to make sure that none failures
|
9
|
-
# for a given consumption will affect other consumed messages
|
10
|
-
# If we would't catch it, it would propagate up until killing the Celluloid actor
|
11
|
-
# @param message [Kafka::FetchedMessage] message that was fetched by kafka
|
12
|
-
def consume(message)
|
13
|
-
# We map from incoming topic name, as it might be namespaced, etc.
|
14
|
-
# @see topic_mapper internal docs
|
15
|
-
mapped_topic = Karafka::App.config.topic_mapper.incoming(message.topic)
|
16
|
-
|
17
|
-
controller = Karafka::Routing::Router.new(mapped_topic).build
|
18
|
-
# We wrap it around with our internal message format, so we don't pass around
|
19
|
-
# a raw Kafka message
|
20
|
-
controller.params = Message.new(mapped_topic, message.value)
|
21
|
-
|
22
|
-
Karafka.monitor.notice(self.class, controller.to_h)
|
23
|
-
|
24
|
-
controller.schedule
|
25
|
-
# This is on purpose - see the notes for this method
|
26
|
-
# rubocop:disable RescueException
|
27
|
-
rescue Exception => e
|
28
|
-
# rubocop:enable RescueException
|
29
|
-
Karafka.monitor.notice_error(self.class, e)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
# Namespace that encapsulates everything related to connections
|
3
|
-
module Connection
|
4
|
-
# Single incoming Kafka message instance wrapper
|
5
|
-
class Message
|
6
|
-
attr_reader :topic, :content
|
7
|
-
|
8
|
-
# @param topic [String] topic from which this message comes
|
9
|
-
# @param content [String] raw message content (not deserialized or anything) from Kafka
|
10
|
-
# @return [Karafka::Connection::Message] incoming message instance
|
11
|
-
def initialize(topic, content)
|
12
|
-
@topic = topic
|
13
|
-
@content = content
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,94 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Connection
|
3
|
-
# Class used as a wrapper around Ruby-Kafka to simplify additional
|
4
|
-
# features that we provide/might provide in future
|
5
|
-
class TopicConsumer
|
6
|
-
# How long should we wait before trying to reconnect to Kafka cluster
|
7
|
-
# that went down (in seconds)
|
8
|
-
RECONNECT_TIMEOUT = 5
|
9
|
-
|
10
|
-
# Creates a queue consumer that will pull the data from Kafka
|
11
|
-
# @param [Karafka::Routing::Route] route details that will be used to build up a
|
12
|
-
# queue consumer instance
|
13
|
-
# @return [Karafka::Connection::QueueConsumer] queue consumer instance
|
14
|
-
def initialize(route)
|
15
|
-
@route = route
|
16
|
-
end
|
17
|
-
|
18
|
-
# Opens connection, gets messages and calls a block for each of the incoming messages
|
19
|
-
# @yieldparam [Kafka::FetchedMessage] kafka fetched message
|
20
|
-
# @note This will yield with a raw message - no preprocessing or reformatting
|
21
|
-
def fetch_loop
|
22
|
-
send(
|
23
|
-
@route.batch_mode ? :consume_each_batch : :consume_each_message
|
24
|
-
) do |message|
|
25
|
-
yield(message)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Gracefuly stops topic consumption
|
30
|
-
def stop
|
31
|
-
@kafka_consumer&.stop
|
32
|
-
@kafka_consumer = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# Consumes messages from Kafka in batches
|
38
|
-
# @yieldparam [Kafka::FetchedMessage] kafka fetched message
|
39
|
-
def consume_each_batch
|
40
|
-
kafka_consumer.each_batch do |batch|
|
41
|
-
batch.messages.each do |message|
|
42
|
-
yield(message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Consumes messages from Kafka one by one
|
48
|
-
# @yieldparam [Kafka::FetchedMessage] kafka fetched message
|
49
|
-
def consume_each_message
|
50
|
-
kafka_consumer.each_message do |message|
|
51
|
-
yield(message)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [Kafka::Consumer] returns a ready to consume Kafka consumer
|
56
|
-
# that is set up to consume a given routes topic
|
57
|
-
def kafka_consumer
|
58
|
-
@kafka_consumer ||= kafka.consumer(
|
59
|
-
group_id: @route.group,
|
60
|
-
session_timeout: ::Karafka::App.config.kafka.session_timeout,
|
61
|
-
offset_commit_interval: ::Karafka::App.config.kafka.offset_commit_interval,
|
62
|
-
offset_commit_threshold: ::Karafka::App.config.kafka.offset_commit_threshold,
|
63
|
-
heartbeat_interval: ::Karafka::App.config.kafka.heartbeat_interval
|
64
|
-
).tap do |consumer|
|
65
|
-
consumer.subscribe(
|
66
|
-
@route.topic,
|
67
|
-
start_from_beginning: @route.start_from_beginning
|
68
|
-
)
|
69
|
-
end
|
70
|
-
rescue Kafka::ConnectionError
|
71
|
-
# If we would not wait it would totally spam log file with failed
|
72
|
-
# attempts if Kafka is down
|
73
|
-
sleep(RECONNECT_TIMEOUT)
|
74
|
-
# We don't log and just reraise - this will be logged
|
75
|
-
# down the road
|
76
|
-
raise
|
77
|
-
end
|
78
|
-
|
79
|
-
# @return [Kafka] returns a Kafka
|
80
|
-
# @note We don't cache it internally because we cache kafka_consumer that uses kafka
|
81
|
-
# object instance
|
82
|
-
def kafka
|
83
|
-
Kafka.new(
|
84
|
-
seed_brokers: ::Karafka::App.config.kafka.hosts,
|
85
|
-
logger: ::Karafka.logger,
|
86
|
-
client_id: ::Karafka::App.config.name,
|
87
|
-
ssl_ca_cert: ::Karafka::App.config.kafka.ssl.ca_cert,
|
88
|
-
ssl_client_cert: ::Karafka::App.config.kafka.ssl.client_cert,
|
89
|
-
ssl_client_cert_key: ::Karafka::App.config.kafka.ssl.client_cert_key
|
90
|
-
)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Responders
|
3
|
-
# Usage validator checks if all the requirements related to responders topics were met
|
4
|
-
class UsageValidator
|
5
|
-
# @param registered_topics [Hash] Hash with registered topics objects from
|
6
|
-
# a given responder class under it's name key
|
7
|
-
# @param used_topics [Array<String>] Array with names of topics that we used in this
|
8
|
-
# responding process
|
9
|
-
# @return [Karafka::Responders::UsageValidator] responding flow usage validator
|
10
|
-
def initialize(registered_topics, used_topics)
|
11
|
-
@registered_topics = registered_topics
|
12
|
-
@used_topics = used_topics
|
13
|
-
end
|
14
|
-
|
15
|
-
# Validates the whole flow
|
16
|
-
# @raise [Karafka::Errors::UnregisteredTopic] raised when we used a topic that we didn't
|
17
|
-
# register using #topic method
|
18
|
-
# @raise [Karafka::Errors::TopicMultipleUsage] raised when we used a non multipleusage topic
|
19
|
-
# multiple times
|
20
|
-
# @raise [Karafka::Errors::UnusedResponderRequiredTopic] raised when we didn't use a topic
|
21
|
-
# that was defined as required to be used
|
22
|
-
def validate!
|
23
|
-
@used_topics.each do |used_topic|
|
24
|
-
validate_usage_of!(used_topic)
|
25
|
-
end
|
26
|
-
|
27
|
-
@registered_topics.each do |_name, registered_topic|
|
28
|
-
validate_requirements_of!(registered_topic)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
# Checks if a given used topic were used in a proper way
|
35
|
-
# @raise [Karafka::Errors::UnregisteredTopic] raised when we used a topic that we didn't
|
36
|
-
# register using #topic method
|
37
|
-
# @raise [Karafka::Errors::TopicMultipleUsage] raised when we used a non multipleusage topic
|
38
|
-
# multiple times
|
39
|
-
# @param used_topic [String] topic to which we've sent a message
|
40
|
-
def validate_usage_of!(used_topic)
|
41
|
-
raise(Errors::UnregisteredTopic, used_topic) unless @registered_topics[used_topic]
|
42
|
-
return if @registered_topics[used_topic].multiple_usage?
|
43
|
-
return unless @registered_topics[used_topic].required?
|
44
|
-
return if @used_topics.count(used_topic) < 2
|
45
|
-
raise(Errors::TopicMultipleUsage, used_topic)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Checks if we met all the requirements for all the registered topics
|
49
|
-
# @raise [Karafka::Errors::UnusedResponderRequiredTopic] raised when we didn't use a topic
|
50
|
-
# that was defined as required to be used
|
51
|
-
# @param registered_topic [::Karafka::Responders::Topic] registered topic object
|
52
|
-
def validate_requirements_of!(registered_topic)
|
53
|
-
return unless registered_topic.required?
|
54
|
-
return if @used_topics.include?(registered_topic.name)
|
55
|
-
|
56
|
-
raise(Errors::UnusedResponderRequiredTopic, registered_topic.name)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Routing
|
3
|
-
# Class representing a single route (from topic to worker) with all additional features
|
4
|
-
# and elements. Single route contains descriptions of:
|
5
|
-
# - topic - Kafka topic name (required)
|
6
|
-
# - controller - Class of a controller that will handle messages from a given topic (required)
|
7
|
-
# - group - Kafka group that we want to use (optional)
|
8
|
-
# - worker - Which worker should handle the backend task (optional)
|
9
|
-
# - parser - What parsed do we want to use to unparse the data (optional)
|
10
|
-
# - interchanger - What interchanger to encode/decode data do we want to use (optional)
|
11
|
-
class Route
|
12
|
-
# Only ASCII alphanumeric characters, underscore, dash and dots
|
13
|
-
# are allowed in topics and groups
|
14
|
-
NAME_FORMAT = /\A(\w|\-|\.)+\z/
|
15
|
-
|
16
|
-
# Options that we can set per each route
|
17
|
-
ATTRIBUTES = %i(
|
18
|
-
group
|
19
|
-
topic
|
20
|
-
worker
|
21
|
-
parser
|
22
|
-
interchanger
|
23
|
-
responder
|
24
|
-
inline_mode
|
25
|
-
batch_mode
|
26
|
-
start_from_beginning
|
27
|
-
).freeze
|
28
|
-
|
29
|
-
ATTRIBUTES.each { |attr| attr_writer(attr) }
|
30
|
-
|
31
|
-
# This we can get "directly" because it does not have any details, etc
|
32
|
-
attr_accessor :controller
|
33
|
-
|
34
|
-
# Initializes default values for all the options that support defaults if their values are
|
35
|
-
# not yet specified. This is need to be done (cannot be lazy loaded on first use) because
|
36
|
-
# everywhere except Karafka server command, those would not be initialized on time - for
|
37
|
-
# example for Sidekiq
|
38
|
-
def build
|
39
|
-
ATTRIBUTES.each { |attr| send(attr) }
|
40
|
-
self
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [String] Kafka group name
|
44
|
-
# @note If group is not provided in a route, will build one based on the app name
|
45
|
-
# and the route topic (that is required)
|
46
|
-
def group
|
47
|
-
(@group ||= "#{Karafka::App.config.name.underscore}_#{topic}").to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [String] route topic - this is the core esence of Kafka
|
51
|
-
def topic
|
52
|
-
@topic.to_s
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [Class] Class (not an instance) of a worker that should be used to schedule the
|
56
|
-
# background job
|
57
|
-
# @note If not provided - will be built based on the provided controller
|
58
|
-
def worker
|
59
|
-
@worker ||= inline_mode ? nil : Karafka::Workers::Builder.new(controller).build
|
60
|
-
end
|
61
|
-
|
62
|
-
# @return [Class, nil] Class (not an instance) of a responder that should respond from
|
63
|
-
# controller back to Kafka (usefull for piping dataflows)
|
64
|
-
def responder
|
65
|
-
@responder ||= Karafka::Responders::Builder.new(controller).build
|
66
|
-
end
|
67
|
-
|
68
|
-
# @return [Class] Parser class (not instance) that we want to use to unparse Kafka messages
|
69
|
-
# @note If not provided - will use Json as default
|
70
|
-
def parser
|
71
|
-
@parser ||= Karafka::Parsers::Json
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [Class] Interchanger class (not an instance) that we want to use to interchange
|
75
|
-
# params between Karafka server and Karafka background job
|
76
|
-
def interchanger
|
77
|
-
@interchanger ||= Karafka::Params::Interchanger
|
78
|
-
end
|
79
|
-
|
80
|
-
# @return [Boolean] Should we perform execution in the background (default) or
|
81
|
-
# inline. This can be set globally and overwritten by a per route setting
|
82
|
-
# @note This method can be set to false, so direct assigment ||= would not work
|
83
|
-
def inline_mode
|
84
|
-
return @inline_mode unless @inline_mode.nil?
|
85
|
-
@inline_mode = Karafka::App.config.inline_mode
|
86
|
-
end
|
87
|
-
|
88
|
-
# @return [Boolean] Should the consumer handle incoming events one at a time, or in batch
|
89
|
-
def batch_mode
|
90
|
-
return @batch_mode unless @batch_mode.nil?
|
91
|
-
@batch_mode = Karafka::App.config.batch_mode
|
92
|
-
end
|
93
|
-
|
94
|
-
# For each topic subscription it's possible to decide whether to consume messages starting
|
95
|
-
# at the beginning of the topic or to just consume new messages that are produced to
|
96
|
-
# the topic.
|
97
|
-
# @return [Boolean] Should we consume from the beggining or from new incoming messages on
|
98
|
-
# the first run
|
99
|
-
def start_from_beginning
|
100
|
-
return @start_from_beginning unless @start_from_beginning.nil?
|
101
|
-
@start_from_beginning = Karafka::App.config.start_from_beginning
|
102
|
-
end
|
103
|
-
|
104
|
-
# Checks if topic and group have proper format (acceptable by Kafka)
|
105
|
-
# @raise [Karafka::Errors::InvalidTopicName] raised when topic name is invalid
|
106
|
-
# @raise [Karafka::Errors::InvalidGroupName] raised when group name is invalid
|
107
|
-
def validate!
|
108
|
-
raise Errors::InvalidTopicName, topic if NAME_FORMAT !~ topic
|
109
|
-
raise Errors::InvalidGroupName, group if NAME_FORMAT !~ group
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Setup
|
3
|
-
# Schema with validation rules for all configuration
|
4
|
-
ConfigSchema = Dry::Validation.Schema do
|
5
|
-
required(:name).filled(:str?)
|
6
|
-
required(:topic_mapper).filled
|
7
|
-
optional(:inline_mode).filled(:bool?)
|
8
|
-
|
9
|
-
required(:redis).maybe do
|
10
|
-
schema do
|
11
|
-
required(:url).filled(:str?)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# If inline_mode is true, redis should be filled
|
16
|
-
rule(redis_presence: [:redis, :inline_mode]) do |redis, inline_mode|
|
17
|
-
inline_mode.false?.then(redis.filled?)
|
18
|
-
end
|
19
|
-
|
20
|
-
optional(:batch_mode).filled(:bool?)
|
21
|
-
optional(:start_from_beginning).filled(:bool?)
|
22
|
-
|
23
|
-
optional(:connection_pool).schema do
|
24
|
-
required(:size).filled
|
25
|
-
optional(:timeout).filled(:int?)
|
26
|
-
end
|
27
|
-
|
28
|
-
required(:kafka).schema do
|
29
|
-
required(:hosts).filled(:array?)
|
30
|
-
|
31
|
-
required(:session_timeout).filled(:int?)
|
32
|
-
required(:offset_commit_interval).filled(:int?)
|
33
|
-
required(:offset_commit_threshold).filled(:int?)
|
34
|
-
required(:heartbeat_interval).filled(:int?)
|
35
|
-
|
36
|
-
optional(:ssl).schema do
|
37
|
-
required(:ca_cert).maybe(:str?)
|
38
|
-
required(:client_cert).maybe(:str?)
|
39
|
-
required(:client_cert_key).maybe(:str?)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Karafka
|
2
|
-
module Setup
|
3
|
-
class Configurators
|
4
|
-
# Class responsible for setting up WorkerGlass settings
|
5
|
-
class WorkerGlass < Base
|
6
|
-
# Sets up a Karafka logger as celluloid logger
|
7
|
-
def setup
|
8
|
-
::WorkerGlass.logger = ::Karafka.logger
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|