rabbitmq-actors 2.0.0
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/.gitignore +101 -0
- data/.rspec +5 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/README.md +602 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rabbitmq/actors.rb +13 -0
- data/lib/rabbitmq/actors/base/agent.rb +108 -0
- data/lib/rabbitmq/actors/base/consumer.rb +105 -0
- data/lib/rabbitmq/actors/base/producer.rb +83 -0
- data/lib/rabbitmq/actors/patterns.rb +10 -0
- data/lib/rabbitmq/actors/patterns/headers/headers_consumer.rb +106 -0
- data/lib/rabbitmq/actors/patterns/headers/headers_producer.rb +64 -0
- data/lib/rabbitmq/actors/patterns/master_workers/master_producer.rb +61 -0
- data/lib/rabbitmq/actors/patterns/master_workers/worker.rb +63 -0
- data/lib/rabbitmq/actors/patterns/publish_subscribe/publisher.rb +72 -0
- data/lib/rabbitmq/actors/patterns/publish_subscribe/subscriber.rb +70 -0
- data/lib/rabbitmq/actors/patterns/routing/routing_consumer.rb +99 -0
- data/lib/rabbitmq/actors/patterns/routing/routing_producer.rb +75 -0
- data/lib/rabbitmq/actors/patterns/topics/topic_consumer.rb +105 -0
- data/lib/rabbitmq/actors/patterns/topics/topic_producer.rb +64 -0
- data/lib/rabbitmq/actors/testing.rb +8 -0
- data/lib/rabbitmq/actors/testing/rspec.rb +8 -0
- data/lib/rabbitmq/actors/testing/rspec/stub.rb +52 -0
- data/lib/rabbitmq/actors/version.rb +5 -0
- data/lib/rabbitmq/server.rb +18 -0
- data/rabbitmq-actors.gemspec +32 -0
- metadata +185 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative '../../base/consumer'
|
2
|
+
|
3
|
+
module RabbitMQ
|
4
|
+
module Actors
|
5
|
+
# A consumer of messages from RabbitMQ based on exchange and routing key matching patterns.
|
6
|
+
# @abstract Subclass and override #perform to define your customized topic worker class.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class SpainTennisListener < RabbitMQ::Actors::TopicConsumer
|
10
|
+
# def initialize
|
11
|
+
# super(topic_name: 'sports',
|
12
|
+
# binding_keys: '#.tennis.#.spain.#',
|
13
|
+
# logger: Rails.logger,
|
14
|
+
# on_cancellation: ->{ ActiveRecord::Base.connection.close })
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# private
|
18
|
+
#
|
19
|
+
# def perform(**task)
|
20
|
+
# match_data = JSON.parse(task[:body])
|
21
|
+
# process_tennis_match(match_data)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def process_tennis_match(data)
|
25
|
+
# ...
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# class AmericaSoccerListener < RabbitMQ::Actors::TopicConsumer
|
30
|
+
# def initialize
|
31
|
+
# super(exchange_name: 'sports',
|
32
|
+
# binding_keys: '#.soccer.#.america.#',
|
33
|
+
# logger: Rails.logger,
|
34
|
+
# on_cancellation: ->{ ActiveRecord::Base.connection.close })
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# private
|
38
|
+
#
|
39
|
+
# def perform(**task)
|
40
|
+
# match_data = JSON.parse(task[:body])
|
41
|
+
# process_soccer_match(match_data)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# def process_soccer_match(data)
|
45
|
+
# ...
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# RabbitMQ::Server.url = 'amqp://localhost'
|
50
|
+
#
|
51
|
+
# SpainTennisListener.new.start!
|
52
|
+
# AmericaSoccerListener.new.start!
|
53
|
+
#
|
54
|
+
class TopicConsumer < Base::Consumer
|
55
|
+
# @!attribute [r] topic_name
|
56
|
+
# @return [Bunny::Exchange] the topic exchange where to get messages from.
|
57
|
+
attr_reader :topic_name
|
58
|
+
|
59
|
+
# @!attribute [r] binding_keys
|
60
|
+
# @return [String, Array] the routing key patterns this worker is interested in.
|
61
|
+
attr_reader :binding_keys
|
62
|
+
|
63
|
+
# @param :topic_name [String] name of the topic exchange this worker will receive messages.
|
64
|
+
# @param :binding_keys [String, Array] routing key patterns this worker is interested in.
|
65
|
+
# Default to all: '#'
|
66
|
+
# @option opts [Proc] :on_cancellation to be executed before the worker is terminated
|
67
|
+
# @option opts [Logger] :logger the logger where to output info about this agent's activity.
|
68
|
+
# Rest of options required by your subclass.
|
69
|
+
def initialize(topic_name:, binding_keys: '#', **opts)
|
70
|
+
super(opts.merge(topic_name: topic_name, binding_keys: binding_keys))
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Set topic exchange_name and binding_keys this worker is bound to.
|
76
|
+
# @see #initialize for the list of options that can be received.
|
77
|
+
def pre_initialize(**opts)
|
78
|
+
@topic_name = opts[:topic_name]
|
79
|
+
@binding_keys = Array(opts[:binding_keys])
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
# Bind this worker's queue to the topic exchange and to the given binding_key patterns
|
84
|
+
# @see #initialize for the list of options that can be received.
|
85
|
+
def post_initialize(**opts)
|
86
|
+
bind_queue_to_exchange_routing_keys
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
# The durable RabbitMQ topic exchange from where messages are received
|
91
|
+
# @return [Bunny::Exchange]
|
92
|
+
def exchange
|
93
|
+
@exchange ||= channel.topic(topic_name, durable: true)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Bind this worker's listening queue to the topic exchange and receive only messages with routing key
|
97
|
+
# matching the patterns in binding_keys.
|
98
|
+
def bind_queue_to_exchange_routing_keys
|
99
|
+
binding_keys.each do |key|
|
100
|
+
queue.bind(exchange, routing_key: key)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative '../../base/producer'
|
2
|
+
|
3
|
+
module RabbitMQ
|
4
|
+
module Actors
|
5
|
+
# A producer of messages routed to all the queues bound to the message's routing_key via matching patterns
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# RabbitMQ::Server.url = 'amqp://localhost'
|
9
|
+
#
|
10
|
+
# publisher = RabbitMQ::Actors::TopicProducer.new(topic_name: 'weather', logger: Rails.logger)
|
11
|
+
# message = { temperature: 20, rain: 30%, wind: 'NorthEast' }.to_json
|
12
|
+
# publisher.publish(message, message_id: '1234837633', content_type: "application/json", routing_key: 'Europe.Spain.Madrid')
|
13
|
+
#
|
14
|
+
class TopicProducer < Base::Producer
|
15
|
+
# @!attribute [r] topic_name
|
16
|
+
# @return [Bunny::Exchange] the topic exchange where to publish messages.
|
17
|
+
attr_reader :topic_name
|
18
|
+
|
19
|
+
# @param :topic_name [String] name of the topic exchange where to send messages to.
|
20
|
+
# @option opts [String] :reply_queue_name the name of the queue where a consumer should reply.
|
21
|
+
# @option opts [Logger] :logger the logger where to output info about this agent's activity.
|
22
|
+
def initialize(topic_name:, **opts)
|
23
|
+
super(opts.merge(topic_name: topic_name))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Send a message to the RabbitMQ server.
|
27
|
+
# @param message [String] the message body to be sent.
|
28
|
+
# @param :message_id [String] user-defined id for replies to refer to this message using :correlation_id
|
29
|
+
# @param :routing_key [String] send the message only to queues bound to this exchange and matching this routing_key
|
30
|
+
# @see Bunny::Exchange#publish for extra options:
|
31
|
+
# @option opts [Boolean] :persistent Should the message be persisted to disk?. Default true.
|
32
|
+
# @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
|
33
|
+
# @option opts [Integer] :timestamp A timestamp associated with this message
|
34
|
+
# @option opts [Integer] :expiration Expiration time after which the message will be deleted
|
35
|
+
# @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
|
36
|
+
# @option opts [String] :reply_to Queue name other apps should send the response to. Default to
|
37
|
+
# replay_queue_name if it was defined at creation time.
|
38
|
+
# @option opts [String] :content_type Message content type (e.g. application/json)
|
39
|
+
# @option opts [String] :content_encoding Message content encoding (e.g. gzip)
|
40
|
+
# @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
|
41
|
+
# @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
|
42
|
+
# @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
|
43
|
+
# @option opts [String] :app_id Optional application ID
|
44
|
+
def publish(message, message_id:, routing_key:, **opts)
|
45
|
+
super(message, opts.merge(message_id: message_id, routing_key: routing_key))
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Sets the exchange name to connect to.
|
51
|
+
# @see #initialize for the list of options that can be received.
|
52
|
+
def pre_initialize(**opts)
|
53
|
+
@topic_name = opts[:topic_name]
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
# The durable RabbitMQ topic exchange where to publish messages.
|
58
|
+
# @return [Bunny::Exchange]
|
59
|
+
def exchange
|
60
|
+
@exchange ||= channel.topic(topic_name, durable: true)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module RabbitMQ
|
2
|
+
module Actors
|
3
|
+
module Testing
|
4
|
+
module Rspec
|
5
|
+
|
6
|
+
module Stub
|
7
|
+
# This is a macro available in your rspec tests to stub the RabbitMQ server
|
8
|
+
# and Bunny objects associated to it.
|
9
|
+
#
|
10
|
+
# describe MyListener do
|
11
|
+
# stub_rabbitmq!
|
12
|
+
#
|
13
|
+
# context "..." do
|
14
|
+
# ...
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
def stub_rabbitmq!
|
18
|
+
let(:default_exchange) { double(publish: :published, on_return: :on_returned, type: :direct) }
|
19
|
+
let(:channel) { double(prefetch: true, ack: true, default_exchange: default_exchange, close: true) }
|
20
|
+
let(:connection) { double(create_channel: channel).as_null_object }
|
21
|
+
|
22
|
+
before do
|
23
|
+
allow(channel).to receive(:queue) do |name, durable:, auto_delete:, exclusive:|
|
24
|
+
double(name: name, durable: durable.present?, durable?: durable.present?,
|
25
|
+
auto_delete: auto_delete.present?, auto_delete?: auto_delete.present?,
|
26
|
+
exclusive: exclusive.present?, exclusive?: exclusive.present?, bind: :bound)
|
27
|
+
end
|
28
|
+
|
29
|
+
allow(channel).to receive(:direct) do |name|
|
30
|
+
double(name: name, publish: :published, type: :direct)
|
31
|
+
end
|
32
|
+
|
33
|
+
allow(channel).to receive(:fanout) do |name|
|
34
|
+
double(name: name, publish: :published, type: :fanout)
|
35
|
+
end
|
36
|
+
|
37
|
+
allow(channel).to receive(:topic) do |name|
|
38
|
+
double(name: name, publish: :published, type: :topic)
|
39
|
+
end
|
40
|
+
|
41
|
+
allow(channel).to receive(:headers) do |name|
|
42
|
+
double(name: name, publish: :published, type: :headers)
|
43
|
+
end
|
44
|
+
|
45
|
+
allow(RabbitMQ::Server).to receive(:connection) { connection }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RabbitMQ
|
2
|
+
module Server
|
3
|
+
|
4
|
+
# The url to the server
|
5
|
+
mattr_reader :url, instance_accessor: false
|
6
|
+
|
7
|
+
# The bunny connection object to the server
|
8
|
+
mattr_reader :connection, instance_accessor: false
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Set the url to the server and open a new connection
|
12
|
+
def url=(url)
|
13
|
+
@@url = url
|
14
|
+
@@connection = Bunny.new(url).start
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rabbitmq/actors/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rabbitmq-actors"
|
8
|
+
spec.version = RabbitMQ::Actors::VERSION
|
9
|
+
spec.authors = ["Lorenzo Tello"]
|
10
|
+
spec.email = ["ltello8a@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Ruby client agents implementing different RabbitMQ producer/consumer patterns."
|
13
|
+
spec.description = "High level classes (consumers, producers, publishers...) for a Ruby application to use RabbitMQ."
|
14
|
+
spec.homepage = "https://github.com/ltello/rabbitmq-actors"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
24
|
+
spec.add_development_dependency "rake" # Run scripted tasks
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.4" # Test framework
|
26
|
+
spec.add_development_dependency "factory_girl", "~> 4.5" # Data factories to be used in tests
|
27
|
+
spec.add_development_dependency "byebug", "~> 5.0" # Debugger
|
28
|
+
spec.add_development_dependency "simplecov" # Code coverage analyzer
|
29
|
+
|
30
|
+
spec.add_runtime_dependency "activesupport", "~> 4.2" # Rails ActiveSupport
|
31
|
+
spec.add_runtime_dependency "bunny", "~> 2.0" # Ruby RabbitMQ client.
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbitmq-actors
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lorenzo Tello
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: factory_girl
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '4.2'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: bunny
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
125
|
+
description: High level classes (consumers, producers, publishers...) for a Ruby application
|
126
|
+
to use RabbitMQ.
|
127
|
+
email:
|
128
|
+
- ltello8a@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
|
+
- Gemfile
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/console
|
140
|
+
- bin/setup
|
141
|
+
- lib/rabbitmq/actors.rb
|
142
|
+
- lib/rabbitmq/actors/base/agent.rb
|
143
|
+
- lib/rabbitmq/actors/base/consumer.rb
|
144
|
+
- lib/rabbitmq/actors/base/producer.rb
|
145
|
+
- lib/rabbitmq/actors/patterns.rb
|
146
|
+
- lib/rabbitmq/actors/patterns/headers/headers_consumer.rb
|
147
|
+
- lib/rabbitmq/actors/patterns/headers/headers_producer.rb
|
148
|
+
- lib/rabbitmq/actors/patterns/master_workers/master_producer.rb
|
149
|
+
- lib/rabbitmq/actors/patterns/master_workers/worker.rb
|
150
|
+
- lib/rabbitmq/actors/patterns/publish_subscribe/publisher.rb
|
151
|
+
- lib/rabbitmq/actors/patterns/publish_subscribe/subscriber.rb
|
152
|
+
- lib/rabbitmq/actors/patterns/routing/routing_consumer.rb
|
153
|
+
- lib/rabbitmq/actors/patterns/routing/routing_producer.rb
|
154
|
+
- lib/rabbitmq/actors/patterns/topics/topic_consumer.rb
|
155
|
+
- lib/rabbitmq/actors/patterns/topics/topic_producer.rb
|
156
|
+
- lib/rabbitmq/actors/testing.rb
|
157
|
+
- lib/rabbitmq/actors/testing/rspec.rb
|
158
|
+
- lib/rabbitmq/actors/testing/rspec/stub.rb
|
159
|
+
- lib/rabbitmq/actors/version.rb
|
160
|
+
- lib/rabbitmq/server.rb
|
161
|
+
- rabbitmq-actors.gemspec
|
162
|
+
homepage: https://github.com/ltello/rabbitmq-actors
|
163
|
+
licenses: []
|
164
|
+
metadata: {}
|
165
|
+
post_install_message:
|
166
|
+
rdoc_options: []
|
167
|
+
require_paths:
|
168
|
+
- lib
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
requirements: []
|
180
|
+
rubyforge_project:
|
181
|
+
rubygems_version: 2.6.8
|
182
|
+
signing_key:
|
183
|
+
specification_version: 4
|
184
|
+
summary: Ruby client agents implementing different RabbitMQ producer/consumer patterns.
|
185
|
+
test_files: []
|