rabbitek 0.1.1
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 +7 -0
- data/.codeclimate.yml +4 -0
- data/.gitignore +58 -0
- data/.rspec +1 -0
- data/.rubocop.yml +19 -0
- data/.travis.yml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +76 -0
- data/LICENSE.txt +20 -0
- data/README.md +97 -0
- data/Rakefile +4 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/boostcom-logo.png +0 -0
- data/exe/rabbitek +13 -0
- data/lib/rabbitek/bunny_connection.rb +13 -0
- data/lib/rabbitek/cli/signal_handlers.rb +24 -0
- data/lib/rabbitek/cli.rb +88 -0
- data/lib/rabbitek/client/client_hook.rb +11 -0
- data/lib/rabbitek/client/hooks/opentracing.rb +37 -0
- data/lib/rabbitek/client/publisher.rb +27 -0
- data/lib/rabbitek/config.rb +45 -0
- data/lib/rabbitek/loggable.rb +49 -0
- data/lib/rabbitek/server/consumer.rb +91 -0
- data/lib/rabbitek/server/hooks/opentracing.rb +34 -0
- data/lib/rabbitek/server/hooks/retry.rb +70 -0
- data/lib/rabbitek/server/hooks/time_tracker.rb +30 -0
- data/lib/rabbitek/server/server_hook.rb +11 -0
- data/lib/rabbitek/server/starter.rb +92 -0
- data/lib/rabbitek/utils/common.rb +30 -0
- data/lib/rabbitek/utils/hook_walker.rb +36 -0
- data/lib/rabbitek/utils/oj.rb +17 -0
- data/lib/rabbitek/utils/open_tracing.rb +67 -0
- data/lib/rabbitek/utils/rabbit_object_names.rb +19 -0
- data/lib/rabbitek/version.rb +5 -0
- data/lib/rabbitek.rb +45 -0
- data/rabbitek.gemspec +36 -0
- metadata +206 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
##
|
5
|
+
# Consumer helpers
|
6
|
+
module Consumer
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :channel, :queue, :retry_or_delayed_queue, :retry_or_delayed_exchange
|
12
|
+
|
13
|
+
def initialize(channel, queue, retry_or_delayed_queue, retry_or_delayed_exchange)
|
14
|
+
@channel = channel
|
15
|
+
@queue = queue
|
16
|
+
@retry_or_delayed_queue = retry_or_delayed_queue
|
17
|
+
@retry_or_delayed_exchange = retry_or_delayed_exchange
|
18
|
+
end
|
19
|
+
|
20
|
+
def ack!(delivery_info, multiple = false)
|
21
|
+
channel.ack(delivery_info.delivery_tag, multiple)
|
22
|
+
end
|
23
|
+
|
24
|
+
def logger
|
25
|
+
Rabbitek.logger
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_message(message)
|
29
|
+
Utils::Oj.load(message)
|
30
|
+
end
|
31
|
+
|
32
|
+
def perform(*_args)
|
33
|
+
raise NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_context
|
37
|
+
Thread.current[:rabbit_context] = { consumer: self.class.name, queue: @queue.name, job_id: SecureRandom.uuid }
|
38
|
+
end
|
39
|
+
|
40
|
+
def jid
|
41
|
+
Thread.current[:rabbit_context][:job_id]
|
42
|
+
end
|
43
|
+
|
44
|
+
module ClassMethods # rubocop:disable Style/Documentation
|
45
|
+
attr_accessor :rabbit_options_hash
|
46
|
+
|
47
|
+
def rabbit_options(opts)
|
48
|
+
self.rabbit_options_hash = default_rabbit_options(opts).with_indifferent_access.merge(opts)
|
49
|
+
end
|
50
|
+
|
51
|
+
def perform_async(payload, opts: {}, channel: nil)
|
52
|
+
publisher = Publisher.new(
|
53
|
+
rabbit_options_hash[:bind_exchange],
|
54
|
+
exchange_type: rabbit_options_hash[:bind_exchange_type],
|
55
|
+
channel: channel
|
56
|
+
)
|
57
|
+
publish_with_publisher(publisher, payload, opts)
|
58
|
+
ensure
|
59
|
+
publisher&.close unless channel
|
60
|
+
end
|
61
|
+
|
62
|
+
def perform_in(time, payload, opts: {}, channel: nil)
|
63
|
+
publisher = Publisher.new(
|
64
|
+
Utils::RabbitObjectNames.retry_or_delayed_bind_exchange(rabbit_options_hash[:bind_exchange]),
|
65
|
+
exchange_type: :fanout,
|
66
|
+
channel: channel
|
67
|
+
)
|
68
|
+
publish_with_publisher(publisher, payload, {
|
69
|
+
expiration: time.to_i * 1000, # in milliseconds
|
70
|
+
headers: { 'x-dead-letter-routing-key': to_s }
|
71
|
+
}.merge(opts))
|
72
|
+
ensure
|
73
|
+
publisher&.close unless channel
|
74
|
+
end
|
75
|
+
|
76
|
+
def perform_at(at_time, payload, opts: {}, channel: nil)
|
77
|
+
perform_in(at_time - Time.current, payload, opts: opts, channel: channel)
|
78
|
+
end
|
79
|
+
|
80
|
+
def publish_with_publisher(publisher, payload, opts)
|
81
|
+
publisher.publish(payload, { routing_key: to_s }.merge(opts))
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def default_rabbit_options(opts)
|
87
|
+
YAML.load_file(opts[:config_file]).with_indifferent_access[:parameters]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../server_hook'
|
4
|
+
|
5
|
+
module Rabbitek
|
6
|
+
module Server
|
7
|
+
module Hooks
|
8
|
+
##
|
9
|
+
# OpenTracing server hook
|
10
|
+
class OpenTracing < Rabbitek::ServerHook
|
11
|
+
def call(consumer, delivery_info, properties, payload)
|
12
|
+
response = nil
|
13
|
+
|
14
|
+
::OpenTracing.start_active_span(delivery_info.routing_key, opts(delivery_info, properties)) do |scope|
|
15
|
+
begin
|
16
|
+
response = super
|
17
|
+
rescue StandardError => e
|
18
|
+
Utils::OpenTracing.log_error(scope.span, e)
|
19
|
+
raise
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
response
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def opts(delivery_info, properties)
|
29
|
+
Utils::OpenTracing.server_options(delivery_info, properties)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../server_hook'
|
4
|
+
|
5
|
+
module Rabbitek
|
6
|
+
module Server
|
7
|
+
module Hooks
|
8
|
+
##
|
9
|
+
# Hook to retry failed jobs
|
10
|
+
class Retry < Rabbitek::ServerHook
|
11
|
+
include Loggable
|
12
|
+
|
13
|
+
def call(consumer, delivery_info, properties, payload)
|
14
|
+
super
|
15
|
+
rescue StandardError
|
16
|
+
retry_message(consumer, payload, delivery_info, properties)
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def retry_message(consumer, payload, delivery_info, properties)
|
23
|
+
headers = properties.headers || {}
|
24
|
+
dead_headers = headers.fetch('x-death', []).last || {}
|
25
|
+
|
26
|
+
retry_count = headers.fetch('x-retry-count', 0)
|
27
|
+
expiration = dead_headers.fetch('original-expiration', 1000).to_i
|
28
|
+
|
29
|
+
warn_log(retry_count, expiration, consumer)
|
30
|
+
|
31
|
+
# acknowledge existing message
|
32
|
+
consumer.ack!(delivery_info)
|
33
|
+
|
34
|
+
if retry_count <= 25
|
35
|
+
# Set the new expiration with an increasing factor
|
36
|
+
new_expiration = expiration * 1.5
|
37
|
+
|
38
|
+
# Publish to retry queue with new expiration
|
39
|
+
publish_to_retry_queue(consumer, new_expiration, delivery_info, payload, retry_count)
|
40
|
+
else
|
41
|
+
publish_to_dead_queue
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def warn_log(retry_count, expiration, consumer)
|
46
|
+
warn(
|
47
|
+
message: 'Failure!',
|
48
|
+
retry_count: retry_count,
|
49
|
+
expiration: expiration,
|
50
|
+
consumer: consumer.class.to_s,
|
51
|
+
jid: consumer.jid
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def publish_to_retry_queue(consumer, new_expiration, delivery_info, payload, retry_count)
|
56
|
+
consumer.retry_or_delayed_exchange.publish(
|
57
|
+
payload,
|
58
|
+
expiration: new_expiration.to_i,
|
59
|
+
routing_key: delivery_info.routing_key,
|
60
|
+
headers: { 'x-retry-count': retry_count + 1, 'x-dead-letter-routing-key': delivery_info.routing_key }
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def publish_to_dead_queue
|
65
|
+
# TODO: implement dead queue
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../server_hook'
|
4
|
+
|
5
|
+
module Rabbitek
|
6
|
+
module Server
|
7
|
+
module Hooks
|
8
|
+
##
|
9
|
+
# Hook to keep track of time used for processing single job
|
10
|
+
class TimeTracker < Rabbitek::ServerHook
|
11
|
+
include Loggable
|
12
|
+
|
13
|
+
def call(consumer, delivery_info, properties, payload)
|
14
|
+
info(message: 'Starting', consumer: delivery_info.routing_key, jid: consumer.jid)
|
15
|
+
|
16
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
17
|
+
|
18
|
+
super
|
19
|
+
ensure
|
20
|
+
info(
|
21
|
+
message: 'Finished',
|
22
|
+
consumer: delivery_info.routing_key,
|
23
|
+
time: Process.clock_gettime(Process::CLOCK_MONOTONIC) - start,
|
24
|
+
jid: consumer.jid
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
##
|
5
|
+
# Main server startup
|
6
|
+
class Starter
|
7
|
+
include Loggable
|
8
|
+
|
9
|
+
def initialize(connection, configuration)
|
10
|
+
@connection = connection
|
11
|
+
@queue_name = configuration[:parameters][:queue]
|
12
|
+
@consumers = configuration[:consumers]
|
13
|
+
@opts = configuration[:parameters]
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
setup_bindings!
|
18
|
+
|
19
|
+
work_queue.subscribe(manual_ack: true) do |delivery_info, properties, payload|
|
20
|
+
on_message_received(delivery_info, properties, payload)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :connection, :queue_name, :consumers, :opts
|
27
|
+
|
28
|
+
def setup_bindings!
|
29
|
+
consumers.each do |worker_class|
|
30
|
+
work_queue.bind(work_exchange, routing_key: worker_class.to_s)
|
31
|
+
end
|
32
|
+
retry_or_delayed_queue.bind(retry_or_delayed_exchange)
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_message_received(delivery_info, properties, payload)
|
36
|
+
consumer = consumer_instance(delivery_info.routing_key)
|
37
|
+
consumer.set_context
|
38
|
+
|
39
|
+
hook_walker = Utils::HookWalker.new(Rabbitek.config.server_hooks)
|
40
|
+
|
41
|
+
hook_walker.call!(consumer, delivery_info, properties, payload) do |*args|
|
42
|
+
run_job(*args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def run_job(consumer, delivery_info, properties, payload)
|
47
|
+
consumer.perform(consumer.parse_message(payload), delivery_info, properties)
|
48
|
+
rescue StandardError => e
|
49
|
+
error(message: e.inspect, backtrace: e.backtrace, consumer: consumer.class, jid: consumer.jid)
|
50
|
+
end
|
51
|
+
|
52
|
+
def consumer_instance(routing_key)
|
53
|
+
Thread.current[:worker_classes] ||= {}
|
54
|
+
klass = Thread.current[:worker_classes][routing_key] ||= routing_key.constantize
|
55
|
+
klass.new(channel, work_queue, retry_or_delayed_queue, retry_or_delayed_exchange)
|
56
|
+
rescue NameError
|
57
|
+
nil # TODO: to dead queue
|
58
|
+
end
|
59
|
+
|
60
|
+
def channel
|
61
|
+
@channel ||= begin
|
62
|
+
channel = connection.create_channel
|
63
|
+
channel.basic_qos(opts[:basic_qos]) if opts[:basic_qos].present?
|
64
|
+
channel
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def work_exchange
|
69
|
+
@work_exchange ||= Utils::Common.exchange(channel, 'direct', opts[:bind_exchange])
|
70
|
+
end
|
71
|
+
|
72
|
+
def work_queue
|
73
|
+
@work_queue ||= Utils::Common.queue(channel, queue_name, opts[:queue_attributes])
|
74
|
+
end
|
75
|
+
|
76
|
+
def retry_or_delayed_queue
|
77
|
+
@retry_or_delayed_queue ||= Utils::Common.queue(
|
78
|
+
channel,
|
79
|
+
Utils::RabbitObjectNames.retry_or_delayed_queue(opts[:queue]),
|
80
|
+
arguments: { 'x-dead-letter-exchange': opts[:bind_exchange] }
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def retry_or_delayed_exchange
|
85
|
+
@retry_or_delayed_exchange ||= Utils::Common.exchange(
|
86
|
+
channel,
|
87
|
+
:fanout,
|
88
|
+
Utils::RabbitObjectNames.retry_or_delayed_bind_exchange(opts[:bind_exchange])
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
module Utils
|
5
|
+
##
|
6
|
+
# Common utilities to create/use RabbitMQ exchange or queue
|
7
|
+
class Common
|
8
|
+
class << self
|
9
|
+
def exchange(channel, exchange_type, exchange_name)
|
10
|
+
channel.public_send(exchange_type || 'direct', exchange_name, durable: true, auto_delete: false)
|
11
|
+
end
|
12
|
+
|
13
|
+
def queue(channel, name, opts)
|
14
|
+
opts ||= {}
|
15
|
+
opts = symbolize_keys(opts.to_hash)
|
16
|
+
opts[:durable] = true
|
17
|
+
opts[:auto_delete] = false
|
18
|
+
|
19
|
+
channel.queue(name, opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def symbolize_keys(hash)
|
25
|
+
hash.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v; }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
module Utils
|
5
|
+
##
|
6
|
+
# Utility to work down the hooks setup
|
7
|
+
class HookWalker
|
8
|
+
include Loggable
|
9
|
+
|
10
|
+
def initialize(hooks = [])
|
11
|
+
@hooks = hooks.clone
|
12
|
+
end
|
13
|
+
|
14
|
+
def call!(*args)
|
15
|
+
return yield(*args) unless hooks.any?
|
16
|
+
hook = hooks.pop
|
17
|
+
|
18
|
+
debug "Calling hook: #{hook.class}"
|
19
|
+
|
20
|
+
begin
|
21
|
+
return_args = hook.call(*args) do |*new_args|
|
22
|
+
hooks.any? ? call!(*new_args) { |*next_args| yield(*next_args) } : yield(*new_args)
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
debug "Finishing hook: #{hook.class}"
|
26
|
+
end
|
27
|
+
|
28
|
+
return_args
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :hooks
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
module Utils
|
5
|
+
##
|
6
|
+
# Oj methods wrapper
|
7
|
+
class Oj
|
8
|
+
def self.dump(obj)
|
9
|
+
::Oj.dump(obj, mode: :compat)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.load(string)
|
13
|
+
::Oj.load(string, mode: :compat)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
module Utils
|
5
|
+
##
|
6
|
+
# OpenTracing helpers
|
7
|
+
class OpenTracing
|
8
|
+
OPENTRACING_COMPONENT = 'rabbitek'
|
9
|
+
OPENTRACING_KIND_SERVER = 'server'
|
10
|
+
OPENTRACING_KIND_CLIENT = 'client'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def inject!(span, carrier)
|
14
|
+
::OpenTracing.inject(span.context, ::OpenTracing::FORMAT_TEXT_MAP, carrier)
|
15
|
+
end
|
16
|
+
|
17
|
+
def client_options(params)
|
18
|
+
{
|
19
|
+
tags: {
|
20
|
+
'component' => OPENTRACING_COMPONENT,
|
21
|
+
'span.kind' => OPENTRACING_KIND_CLIENT,
|
22
|
+
'rabbitmq.routing_key' => params[:routing_key]
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def server_options(delivery_info, properties)
|
28
|
+
references = server_references(properties)
|
29
|
+
|
30
|
+
options = {
|
31
|
+
tags: {
|
32
|
+
'component' => OPENTRACING_COMPONENT,
|
33
|
+
'span.kind' => OPENTRACING_KIND_SERVER,
|
34
|
+
'rabbitmq.routing_key' => delivery_info.routing_key,
|
35
|
+
'rabbitmq.jid' => Thread.current[:rabbit_context][:jid],
|
36
|
+
'rabbitmq.queue' => Thread.current[:rabbit_context][:queue],
|
37
|
+
'rabbitmq.worker' => Thread.current[:rabbit_context][:consumer]
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
options[:references] = [references] if references
|
42
|
+
options
|
43
|
+
end
|
44
|
+
|
45
|
+
def log_error(span, err)
|
46
|
+
span.set_tag('error', true)
|
47
|
+
span.log_kv(
|
48
|
+
event: 'error',
|
49
|
+
'error.kind': err.class.to_s,
|
50
|
+
'error.object': err,
|
51
|
+
message: err.message
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def server_references(message_properties)
|
58
|
+
::OpenTracing::Reference.follows_from(extract(message_properties))
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract(message_properties)
|
62
|
+
::OpenTracing.extract(::OpenTracing::FORMAT_TEXT_MAP, message_properties.headers)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rabbitek
|
4
|
+
module Utils
|
5
|
+
##
|
6
|
+
# Names builder for exchanges, queues, etc.
|
7
|
+
class RabbitObjectNames
|
8
|
+
class << self
|
9
|
+
def retry_or_delayed_bind_exchange(bind_exchange)
|
10
|
+
"#{bind_exchange}.rabbitek.__rod__"
|
11
|
+
end
|
12
|
+
|
13
|
+
def retry_or_delayed_queue(queue_name)
|
14
|
+
"#{queue_name}.rabbitek.__rod__"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rabbitek.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rabbitek/version'
|
4
|
+
|
5
|
+
require 'bunny'
|
6
|
+
require 'oj'
|
7
|
+
require 'opentracing'
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
# active_support
|
11
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
12
|
+
require 'active_support/core_ext/string/inflections'
|
13
|
+
|
14
|
+
current_dir = File.dirname(__FILE__)
|
15
|
+
|
16
|
+
Dir.glob("#{current_dir}/rabbitek/*.rb").each { |file| require file }
|
17
|
+
Dir.glob("#{current_dir}/rabbitek/**/*.rb").each { |file| require file }
|
18
|
+
|
19
|
+
##
|
20
|
+
# High performance background job processing using RabbitMQ
|
21
|
+
module Rabbitek
|
22
|
+
def self.config
|
23
|
+
@config ||= Config.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
yield(config)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.logger
|
31
|
+
@logger ||= Logger.new(STDOUT)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create_channel
|
35
|
+
bunny_connection.create_channel
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.close_bunny_connection
|
39
|
+
bunny_connection.close
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.bunny_connection
|
43
|
+
@bunny_connection ||= BunnyConnection.initialize_connection
|
44
|
+
end
|
45
|
+
end
|
data/rabbitek.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rabbitek/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'rabbitek'
|
9
|
+
spec.version = Rabbitek::VERSION
|
10
|
+
spec.authors = ['Boostcom']
|
11
|
+
spec.email = ['jakub.kruczek@boostcom.no']
|
12
|
+
|
13
|
+
spec.summary = 'High performance background job processing'
|
14
|
+
spec.description = 'High performance background job processing'
|
15
|
+
spec.homepage = 'http://boostcom.no'
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
spec.bindir = 'exe'
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_dependency 'activesupport', '> 3.0'
|
27
|
+
spec.add_dependency 'bunny', '~> 2.11.0'
|
28
|
+
spec.add_dependency 'oj', '~> 3.6'
|
29
|
+
spec.add_dependency 'opentracing', '~> 0.4'
|
30
|
+
spec.add_dependency 'slop', '~> 4.0'
|
31
|
+
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
33
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.58.0'
|
36
|
+
end
|