karafka 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +68 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +202 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +216 -0
- data/MIT-LICENCE +18 -0
- data/README.md +831 -0
- data/Rakefile +17 -0
- data/bin/karafka +7 -0
- data/karafka.gemspec +34 -0
- data/lib/karafka.rb +73 -0
- data/lib/karafka/app.rb +45 -0
- data/lib/karafka/base_controller.rb +162 -0
- data/lib/karafka/base_responder.rb +118 -0
- data/lib/karafka/base_worker.rb +41 -0
- data/lib/karafka/capistrano.rb +2 -0
- data/lib/karafka/capistrano/karafka.cap +84 -0
- data/lib/karafka/cli.rb +52 -0
- data/lib/karafka/cli/base.rb +74 -0
- data/lib/karafka/cli/console.rb +23 -0
- data/lib/karafka/cli/flow.rb +46 -0
- data/lib/karafka/cli/info.rb +26 -0
- data/lib/karafka/cli/install.rb +45 -0
- data/lib/karafka/cli/routes.rb +39 -0
- data/lib/karafka/cli/server.rb +59 -0
- data/lib/karafka/cli/worker.rb +26 -0
- data/lib/karafka/connection/consumer.rb +29 -0
- data/lib/karafka/connection/listener.rb +54 -0
- data/lib/karafka/connection/message.rb +17 -0
- data/lib/karafka/connection/topic_consumer.rb +48 -0
- data/lib/karafka/errors.rb +50 -0
- data/lib/karafka/fetcher.rb +40 -0
- data/lib/karafka/helpers/class_matcher.rb +77 -0
- data/lib/karafka/helpers/multi_delegator.rb +31 -0
- data/lib/karafka/loader.rb +77 -0
- data/lib/karafka/logger.rb +52 -0
- data/lib/karafka/monitor.rb +82 -0
- data/lib/karafka/params/interchanger.rb +33 -0
- data/lib/karafka/params/params.rb +102 -0
- data/lib/karafka/patches/dry/configurable/config.rb +37 -0
- data/lib/karafka/process.rb +61 -0
- data/lib/karafka/responders/builder.rb +33 -0
- data/lib/karafka/responders/topic.rb +43 -0
- data/lib/karafka/responders/usage_validator.rb +59 -0
- data/lib/karafka/routing/builder.rb +89 -0
- data/lib/karafka/routing/route.rb +80 -0
- data/lib/karafka/routing/router.rb +38 -0
- data/lib/karafka/server.rb +53 -0
- data/lib/karafka/setup/config.rb +57 -0
- data/lib/karafka/setup/configurators/base.rb +33 -0
- data/lib/karafka/setup/configurators/celluloid.rb +20 -0
- data/lib/karafka/setup/configurators/sidekiq.rb +34 -0
- data/lib/karafka/setup/configurators/water_drop.rb +19 -0
- data/lib/karafka/setup/configurators/worker_glass.rb +13 -0
- data/lib/karafka/status.rb +23 -0
- data/lib/karafka/templates/app.rb.example +26 -0
- data/lib/karafka/templates/application_controller.rb.example +5 -0
- data/lib/karafka/templates/application_responder.rb.example +9 -0
- data/lib/karafka/templates/application_worker.rb.example +12 -0
- data/lib/karafka/templates/config.ru.example +13 -0
- data/lib/karafka/templates/sidekiq.yml.example +26 -0
- data/lib/karafka/version.rb +6 -0
- data/lib/karafka/workers/builder.rb +49 -0
- data/log/.gitkeep +0 -0
- metadata +267 -0
@@ -0,0 +1,59 @@
|
|
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 if @used_topics.count(used_topic) < 2
|
44
|
+
raise(Errors::TopicMultipleUsage, used_topic)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Checks if we met all the requirements for all the registered topics
|
48
|
+
# @raise [Karafka::Errors::UnusedResponderRequiredTopic] raised when we didn't use a topic
|
49
|
+
# that was defined as required to be used
|
50
|
+
# @param registered_topic [::Karafka::Responders::Topic] registered topic object
|
51
|
+
def validate_requirements_of!(registered_topic)
|
52
|
+
return unless registered_topic.required?
|
53
|
+
return if @used_topics.include?(registered_topic.name)
|
54
|
+
|
55
|
+
raise(Errors::UnusedResponderRequiredTopic, registered_topic.name)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Karafka
|
2
|
+
module Routing
|
3
|
+
# Routes builder used as a DSL layer for drawing and describing routes
|
4
|
+
# @example Build a simple (most common) route
|
5
|
+
# draw do
|
6
|
+
# topic :new_videos do
|
7
|
+
# controller NewVideosController
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
class Builder < Array
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
# Options that are being set on the route level
|
14
|
+
ROUTE_OPTIONS = %i(
|
15
|
+
group
|
16
|
+
worker
|
17
|
+
controller
|
18
|
+
parser
|
19
|
+
interchanger
|
20
|
+
responder
|
21
|
+
).freeze
|
22
|
+
|
23
|
+
# All those options should be set on the route level
|
24
|
+
ROUTE_OPTIONS.each do |option|
|
25
|
+
define_method option do |value|
|
26
|
+
@current_route.public_send :"#{option}=", value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates a new route for a given topic and evalues provided block in builder context
|
31
|
+
# @param topic [String, Symbol] Kafka topic name
|
32
|
+
# @param block [Proc] block that will be evaluated in current context
|
33
|
+
# @note Creating new topic means creating a new route
|
34
|
+
# @example Define controller for a topic
|
35
|
+
# topic :xyz do
|
36
|
+
# controller XyzController
|
37
|
+
# end
|
38
|
+
def topic(topic, &block)
|
39
|
+
@current_route = Route.new
|
40
|
+
@current_route.topic = topic
|
41
|
+
|
42
|
+
instance_eval(&block)
|
43
|
+
|
44
|
+
store!
|
45
|
+
end
|
46
|
+
|
47
|
+
# Used to draw routes for Karafka
|
48
|
+
# @note After it is done drawing it will store and validate all the routes to make sure that
|
49
|
+
# they are correct and that there are no topic/group duplications (this is forbidden)
|
50
|
+
# @yield Evaluates provided block in a builder context so we can describe routes
|
51
|
+
# @example
|
52
|
+
# draw do
|
53
|
+
# topic :xyz do
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
def draw(&block)
|
57
|
+
instance_eval(&block)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Stores current route locally after it was built and validated
|
63
|
+
def store!
|
64
|
+
@current_route.build
|
65
|
+
@current_route.validate!
|
66
|
+
|
67
|
+
self << @current_route
|
68
|
+
|
69
|
+
validate! :topic, Errors::DuplicatedTopicError
|
70
|
+
validate! :group, Errors::DuplicatedGroupError
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks that among all routes a given attribute value is unique
|
74
|
+
# @param attribute [Symbol] what routes attribute we want to check for uniqueness
|
75
|
+
# @param error [Class] error class that should be raised when something is wrong
|
76
|
+
def validate!(attribute, error)
|
77
|
+
map = each_with_object({}) do |route, amounts|
|
78
|
+
key = route.public_send(attribute)
|
79
|
+
amounts[key] = amounts[key].to_i + 1
|
80
|
+
amounts
|
81
|
+
end
|
82
|
+
|
83
|
+
wrong = map.find { |_, amount| amount > 1 }
|
84
|
+
|
85
|
+
raise error, wrong if wrong
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,80 @@
|
|
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 and underscore and dash are allowed in topics and groups
|
13
|
+
NAME_FORMAT = /\A(\w|\-)+\z/
|
14
|
+
|
15
|
+
# Options that we can set per each route
|
16
|
+
attr_writer :group, :topic, :worker, :parser, :interchanger, :responder
|
17
|
+
|
18
|
+
# This we can get "directly" because it does not have any details, etc
|
19
|
+
attr_accessor :controller
|
20
|
+
|
21
|
+
# Initializes default values for all the options that support defaults if their values are
|
22
|
+
# not yet specified. This is need to be done (cannot be lazy loaded on first use) because
|
23
|
+
# everywhere except Karafka server command, those would not be initialized on time - for
|
24
|
+
# example for Sidekiq
|
25
|
+
def build
|
26
|
+
group
|
27
|
+
worker
|
28
|
+
parser
|
29
|
+
interchanger
|
30
|
+
responder
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] Kafka group name
|
35
|
+
# @note If group is not provided in a route, will build one based on the app name
|
36
|
+
# and the route topic (that is required)
|
37
|
+
def group
|
38
|
+
(@group ||= "#{Karafka::App.config.name.underscore}_#{topic}").to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [String] route topic - this is the core esence of Kafka
|
42
|
+
def topic
|
43
|
+
@topic.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Class] Class (not an instance) of a worker that should be used to schedule the
|
47
|
+
# background job
|
48
|
+
# @note If not provided - will be built based on the provided controller
|
49
|
+
def worker
|
50
|
+
@worker ||= Karafka::Workers::Builder.new(controller).build
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Class, nil] Class (not an instance) of a responder that should respond from
|
54
|
+
# controller back to Kafka (usefull for piping dataflows)
|
55
|
+
def responder
|
56
|
+
@responder ||= Karafka::Responders::Builder.new(controller).build
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Class] Parser class (not instance) that we want to use to unparse Kafka messages
|
60
|
+
# @note If not provided - will use JSON as default
|
61
|
+
def parser
|
62
|
+
@parser ||= JSON
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Class] Interchanger class (not an instance) that we want to use to interchange
|
66
|
+
# params between Karafka server and Karafka background job
|
67
|
+
def interchanger
|
68
|
+
@interchanger ||= Karafka::Params::Interchanger
|
69
|
+
end
|
70
|
+
|
71
|
+
# Checks if topic and group have proper format (acceptable by Kafka)
|
72
|
+
# @raise [Karafka::Errors::InvalidTopicName] raised when topic name is invalid
|
73
|
+
# @raise [Karafka::Errors::InvalidGroupName] raised when group name is invalid
|
74
|
+
def validate!
|
75
|
+
raise Errors::InvalidTopicName, topic if NAME_FORMAT !~ topic
|
76
|
+
raise Errors::InvalidGroupName, group if NAME_FORMAT !~ group
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Karafka
|
2
|
+
# Namespace for all elements related to requests routing
|
3
|
+
module Routing
|
4
|
+
# Karafka framework Router for routing incoming messages to proper controllers
|
5
|
+
# @note Since Kafka does not provide namespaces or modules for topics, they all have "flat"
|
6
|
+
# structure so all the routes are being stored in a single level array
|
7
|
+
class Router
|
8
|
+
# @param topic [String] topic based on which we find a proper route
|
9
|
+
# @return [Karafka::Router] router instance
|
10
|
+
def initialize(topic)
|
11
|
+
@topic = topic
|
12
|
+
end
|
13
|
+
|
14
|
+
# Builds a controller instance that should handle message from a given topic
|
15
|
+
# @return [Karafka::BaseController] base controller descendant instance object
|
16
|
+
def build
|
17
|
+
controller = route.controller.new
|
18
|
+
controller.topic = route.topic
|
19
|
+
controller.parser = route.parser
|
20
|
+
controller.worker = route.worker
|
21
|
+
controller.interchanger = route.interchanger
|
22
|
+
controller.responder = route.responder
|
23
|
+
|
24
|
+
controller
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# @return [Karafka::Routing::Route] proper route details
|
30
|
+
# @raise [Karafka::Topic::NonMatchingTopicError] raised if topic name does not match
|
31
|
+
# any route defined by user using routes.draw
|
32
|
+
def route
|
33
|
+
App.routes.find { |route| route.topic == @topic } ||
|
34
|
+
raise(Errors::NonMatchingRouteError, @topic)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Karafka
|
2
|
+
# Karafka consuming server class
|
3
|
+
class Server
|
4
|
+
class << self
|
5
|
+
# We need to store reference to all the consumers in the main server thread,
|
6
|
+
# So we can have access to them later on and be able to stop them on exit
|
7
|
+
attr_reader :consumers
|
8
|
+
|
9
|
+
# Method which runs app
|
10
|
+
def run
|
11
|
+
@consumers = Concurrent::Array.new
|
12
|
+
bind_on_sigint
|
13
|
+
bind_on_sigquit
|
14
|
+
start_supervised
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# @return [Karafka::Process] process wrapper instance used to catch system signal calls
|
20
|
+
def process
|
21
|
+
Karafka::Process.instance
|
22
|
+
end
|
23
|
+
|
24
|
+
# What should happen when we decide to quit with sigint
|
25
|
+
def bind_on_sigint
|
26
|
+
process.on_sigint do
|
27
|
+
Karafka::App.stop!
|
28
|
+
consumers.map(&:stop) if Karafka::App.running?
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# What should happen when we decide to quit with sigquit
|
34
|
+
def bind_on_sigquit
|
35
|
+
process.on_sigquit do
|
36
|
+
Karafka::App.stop!
|
37
|
+
consumers.map(&:stop) if Karafka::App.running?
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Starts Karafka with a supervision
|
43
|
+
# @note We don't need to sleep because Karafka::Fetcher is locking and waiting to
|
44
|
+
# finish loop (and it won't happen until we explicitily want to stop)
|
45
|
+
def start_supervised
|
46
|
+
process.supervise do
|
47
|
+
Karafka::App.run!
|
48
|
+
Karafka::Fetcher.new.fetch_loop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Karafka
|
2
|
+
# Module containing all Karafka setup related elements like configuration settings,
|
3
|
+
# config validations and configurators for external gems integration
|
4
|
+
module Setup
|
5
|
+
# Configurator for setting up all the framework details that are required to make it work
|
6
|
+
# @note If you want to do some configurations after all of this is done, please add to
|
7
|
+
# karafka/config a proper file (needs to inherit from Karafka::Setup::Configurators::Base
|
8
|
+
# and implement setup method) after that everything will happen automatically
|
9
|
+
# @note This config object allows to create a 1 level nestings (nodes) only. This should be
|
10
|
+
# enough and will still keep the code simple
|
11
|
+
# @see Karafka::Setup::Configurators::Base for more details about configurators api
|
12
|
+
class Config
|
13
|
+
extend Dry::Configurable
|
14
|
+
|
15
|
+
# Available settings
|
16
|
+
# option name [String] current app name - used to provide default Kafka groups namespaces
|
17
|
+
setting :name
|
18
|
+
# option logger [Instance] logger that we want to use
|
19
|
+
setting :logger, ::Karafka::Logger.instance
|
20
|
+
# option monitor [Instance] monitor that we will to use (defaults to Karafka::Monitor)
|
21
|
+
setting :monitor, ::Karafka::Monitor.instance
|
22
|
+
# option redis [Hash] redis options hash (url and optional parameters)
|
23
|
+
# Note that redis could be rewriten using nested options, but it is a sidekiq specific
|
24
|
+
# stuff and we don't want to touch it
|
25
|
+
setting :redis
|
26
|
+
# option kafka [Hash] - optional - kafka configuration options (hosts)
|
27
|
+
setting :kafka do
|
28
|
+
setting :hosts
|
29
|
+
end
|
30
|
+
|
31
|
+
# This is configured automatically, don't overwrite it!
|
32
|
+
# Each route requires separate thread, so number of threads should be equal to number
|
33
|
+
# of routes
|
34
|
+
setting :concurrency, -> { ::Karafka::App.routes.count }
|
35
|
+
|
36
|
+
class << self
|
37
|
+
# Configurating method
|
38
|
+
# @yield Runs a block of code providing a config singleton instance to it
|
39
|
+
# @yieldparam [Karafka::Setup::Config] Karafka config instance
|
40
|
+
def setup
|
41
|
+
configure do |config|
|
42
|
+
yield(config)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Everything that should be initialized after the setup
|
47
|
+
# Components are in karafka/config directory and are all loaded one by one
|
48
|
+
# If you want to configure a next component, please add a proper file to config dir
|
49
|
+
def setup_components
|
50
|
+
Configurators::Base.descendants.each do |klass|
|
51
|
+
klass.new(config).setup
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Karafka
|
2
|
+
module Setup
|
3
|
+
# Configurators module is used to enclose all the external dependencies configurations
|
4
|
+
class Configurators
|
5
|
+
# Karafka has come components that it relies on (like Celluloid or Sidekiq)
|
6
|
+
# We need to configure all of them only when the framework was set up.
|
7
|
+
# Any class that descends from this one will be automatically invoked upon setup (after it)
|
8
|
+
# @example Configure an Example class
|
9
|
+
# class ExampleConfigurator < Base
|
10
|
+
# def setup
|
11
|
+
# ExampleClass.logger = Karafka.logger
|
12
|
+
# ExampleClass.redis = config.redis
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
class Base
|
16
|
+
extend ActiveSupport::DescendantsTracker
|
17
|
+
|
18
|
+
attr_reader :config
|
19
|
+
|
20
|
+
# @param config [Karafka::Config] config instance
|
21
|
+
# @return [Karafka::Config::Base] configurator for a given component
|
22
|
+
def initialize(config)
|
23
|
+
@config = config
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method needs to be implemented in a subclass
|
27
|
+
def setup
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Karafka
|
2
|
+
module Setup
|
3
|
+
class Configurators
|
4
|
+
# Class responsible for setting up Celluloid settings
|
5
|
+
class Celluloid < Base
|
6
|
+
# How many seconds should we wait for actors (listeners) before forcefully shutting them
|
7
|
+
SHUTDOWN_TIME = 30
|
8
|
+
|
9
|
+
# Sets up a Karafka logger as celluloid logger
|
10
|
+
def setup
|
11
|
+
::Celluloid.logger = ::Karafka.logger
|
12
|
+
# This is just a precaution - it should automatically close the current
|
13
|
+
# connection and shutdown actor - but in case it didn't (hanged, etc)
|
14
|
+
# we will kill it after waiting for some time
|
15
|
+
::Celluloid.shutdown_timeout = SHUTDOWN_TIME
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Karafka
|
2
|
+
module Setup
|
3
|
+
class Configurators
|
4
|
+
# Class to configure all the Sidekiq settings based on Karafka settings
|
5
|
+
class Sidekiq < Base
|
6
|
+
# Sets up sidekiq client and server
|
7
|
+
def setup
|
8
|
+
setup_sidekiq_client
|
9
|
+
setup_sidekiq_server
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# Configure sidekiq client
|
15
|
+
def setup_sidekiq_client
|
16
|
+
::Sidekiq.configure_client do |sidekiq_config|
|
17
|
+
sidekiq_config.redis = config.redis.to_h.merge(
|
18
|
+
size: config.concurrency
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configure sidekiq setorrver
|
24
|
+
def setup_sidekiq_server
|
25
|
+
::Sidekiq.configure_server do |sidekiq_config|
|
26
|
+
# We don't set size for the server - this will be set automatically based
|
27
|
+
# on the Sidekiq concurrency level (Sidekiq not Karafkas)
|
28
|
+
sidekiq_config.redis = config.redis.to_h
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|