lagomorph 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6cff4cf7c784a64394cd23dd70849e382667df5f
4
+ data.tar.gz: 21739a5e5f83a0be0ea5f4179f6f2dad7e4682d0
5
+ SHA512:
6
+ metadata.gz: 3057276adb863de048a1b80a54f059b2359a326fbfe9d01f64b05c14caeb2349968c2fbe8ad2e186fc0104be3c69e70e9647620c2858766929bcc1c77b9c44ee
7
+ data.tar.gz: 79fc5bf8130caa38e2343e0a9f235bb7d1e5ddea4a3a2d20e28b36684ac39e02b260f6b0758cdfabd839756fbf62ed98d4dcb549c923ec28e4438b05ed3fdb6e
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /vendor/
2
+ /.idea/
3
+ /.bundle/
4
+ /.yardoc
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+ *.bundle
13
+ *.so
14
+ *.o
15
+ *.a
16
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby-1.7.16
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lagomorph.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alessandro Berardi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Lagomorph
2
+
3
+ RPC Messaging pattern using RabbitMQ
4
+
5
+ Lagomorph is a mammal of the order Lagomorpha, which comprises the hares, rabbits, and pikas.
6
+
7
+ It's also a gem that implements the RPC pattern over AMPQ using RabbitMQ.
8
+ In this case, it can work with either MRI (through the bunny gem) or jRuby
9
+ (via the march_hare gem).
10
+
11
+ ## Installation
12
+
13
+ Add this to your application's Gemfile if you're on jruby:
14
+
15
+ ```ruby
16
+ gem 'march_hare'
17
+ gem 'lagomorph'
18
+ ```
19
+
20
+ ...and if you're on MRI, or rubinius:
21
+
22
+ ```ruby
23
+ gem 'bunny'
24
+ gem 'lagomorph'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install lagomorph
34
+
35
+ ## Usage
36
+
37
+ Lagomorph tries to maintain a healthy distance from your code. It wants
38
+ you to be in control.
39
+
40
+ Let's say you have a complicated bit of work, that looks like this:
41
+
42
+ ```ruby
43
+ class PongWorker
44
+ def ponger
45
+ 'pong'
46
+ end
47
+ end
48
+ ```
49
+
50
+ Then, you could set it going in a super micro-service type of way with
51
+ this bootup:
52
+
53
+ ```ruby
54
+ connection_params = {} # passed along to RabbitMQ connect
55
+ session = Lagomorph::Session.connect(connection_params)
56
+ supervisor = Lagomorph::Supervisor.new(session)
57
+ supervisor.route 'ping', PongWorker
58
+
59
+ trap("SIGINT") { puts "Bye!"; exit! }
60
+
61
+ # Let the supervisor run in the background,
62
+ # while the main thread does nothing
63
+ sleep
64
+ ```
65
+
66
+ Now to utilise this amazing service, we would use the rpc call client:
67
+
68
+ ```ruby
69
+ connection_params = {} # passed along to RabbitMQ connect
70
+ session = Lagomorph::Session.connect(connection_params)
71
+
72
+ rpc_call = Lagomorph::RpcCall.new(session)
73
+ result = rpc_call.dispatch(queue, 'ponger')
74
+
75
+ puts "The result should be 'pong'. Is it: #{result}?"
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it ( https://github.com/[my-github-username]/lagomorph/fork )
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
data/lagomorph.gemspec ADDED
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lagomorph/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lagomorph"
8
+ spec.version = Lagomorph::VERSION
9
+ spec.authors = ["Alessandro Berardi", "Adam Davies"]
10
+ spec.email = ["berardialessandro@gmail.com", "adzdavies@gmail.com"]
11
+ spec.summary = %q{RPC Messaging pattern using RabbitMQ}
12
+ spec.description = %q{
13
+ Lagomorph is a mammal of the order Lagomorpha, which comprises the hares, rabbits, and pikas.
14
+
15
+ It's also a gem that implements the RPC pattern over AMPQ using RabbitMQ.
16
+ In this case, it can work with either MRI (through the bunny gem) or jRuby
17
+ (via the march_hare gem).
18
+ }
19
+ spec.homepage = ""
20
+ spec.license = "MIT"
21
+
22
+ spec.files = `git ls-files -z`.split("\x0")
23
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
+ spec.require_paths = ["lib"]
26
+
27
+ # You'll have to include one of these when you use it
28
+ # since gem-build will include one or both...
29
+ # if RUBY_PLATFORM == 'java' # jruby
30
+ # spec.add_dependency 'march_hare'
31
+ # else # mri
32
+ # spec.add_dependency 'bunny'
33
+ # end
34
+ spec.add_dependency 'json'
35
+
36
+ spec.add_development_dependency "bundler", "~> 1.7"
37
+
38
+ # Switch your platform when spec'ing...
39
+ if RUBY_PLATFORM == 'java' # jruby
40
+ spec.add_development_dependency 'march_hare'
41
+ else # mri
42
+ spec.add_development_dependency 'bunny'
43
+ end
44
+ spec.add_development_dependency "rake", "~> 10.0"
45
+ spec.add_development_dependency "rspec"
46
+
47
+ end
data/lib/lagomorph.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'lagomorph/version'
2
+
3
+ module Lagomorph
4
+
5
+ def self.using_march_hare?
6
+ using? 'march_hare'
7
+ end
8
+
9
+
10
+ def self.using_bunny?
11
+ using? 'bunny'
12
+ end
13
+
14
+
15
+ private
16
+
17
+ def self.using?(gem_name)
18
+ !Gem.loaded_specs[gem_name].nil?
19
+ end
20
+
21
+ end
22
+
23
+ if Lagomorph.using_bunny?
24
+ require 'bunny'
25
+ else
26
+ require 'march_hare'
27
+ end
28
+
29
+ require 'lagomorph/session'
30
+ require 'lagomorph/subscriber'
31
+ require 'lagomorph/supervisor'
32
+ require 'lagomorph/rpc_call'
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+
3
+ module Lagomorph
4
+ class JsonParser
5
+
6
+ def parse_request(payload)
7
+ request_message = JSON.parse(payload)
8
+ method = request_message.fetch('method')
9
+ params = request_message.fetch('params', [])
10
+ return method, params
11
+ end
12
+
13
+ def parse_response(response)
14
+ JSON.parse(response)
15
+ end
16
+
17
+ def build_request(method, *params)
18
+ JSON.generate('method' => method, 'params' => params)
19
+ end
20
+
21
+ def build_response(result)
22
+ JSON.generate('result' => result)
23
+ end
24
+
25
+ def build_error(error)
26
+ JSON.generate('error' => error)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ module Lagomorph
2
+ MetadataAdapter = Struct.new(:delivery_info, :properties) do
3
+
4
+ def delivery_tag
5
+ delivery_info.delivery_tag
6
+ end
7
+
8
+ def reply_to
9
+ properties.reply_to
10
+ end
11
+
12
+ def correlation_id
13
+ properties.correlation_id
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require 'lagomorph/metadata_adapter'
2
+
3
+ module Lagomorph
4
+ QueueAdapter = Struct.new(:queue) do
5
+
6
+ def subscribe(options = {}, &block)
7
+ if Lagomorph.using_bunny?
8
+ queue.subscribe(options) do |delivery_info, properties, payload|
9
+ metadata = MetadataAdapter.new(delivery_info, properties)
10
+ block.call(metadata, payload)
11
+ end
12
+ else
13
+ queue.subscribe(options, &block)
14
+ end
15
+ end
16
+
17
+ def name
18
+ queue.name
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ require 'lagomorph/queue_adapter'
2
+ require 'lagomorph/metadata_adapter'
3
+
4
+ module Lagomorph
5
+ QueueBuilder = Struct.new(:channel) do
6
+ def queue(name, opts={})
7
+ QueueAdapter.new(channel.queue(name, opts))
8
+ end
9
+
10
+ # Build a reply queue
11
+ def reply_queue
12
+ queue('', exclusive: true)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,84 @@
1
+ require 'lagomorph/queue_adapter'
2
+ require 'lagomorph/json_parser'
3
+ require 'securerandom'
4
+
5
+ module Lagomorph
6
+ class RpcCall
7
+
8
+ def initialize(session)
9
+ @session = session
10
+ @results = {}
11
+ @mutex = Monitor.new
12
+ end
13
+
14
+ def dispatch(queue_name, method, *params)
15
+ @queue_name = queue_name
16
+
17
+ correlation_id = calculate_correlation_id
18
+ @mutex.synchronize do
19
+ @results[correlation_id] = ::Queue.new
20
+ end
21
+
22
+ prepare_channel
23
+ payload = prepare_payload(method, *params)
24
+ publish_rpc_call(payload, correlation_id)
25
+ response = block_till_receive_response(correlation_id)
26
+
27
+ response['result'] || (fail response.fetch('error'))
28
+ end
29
+
30
+ def close_channel
31
+ @channel.close
32
+ @prepared_channel = false
33
+ end
34
+
35
+ private
36
+
37
+ def prepare_channel
38
+ return if @prepared_channel
39
+
40
+ @channel = @session.create_channel(1)
41
+
42
+ @exchange = @channel.default_exchange
43
+ @reply_queue = QueueBuilder.new(@channel).reply_queue
44
+
45
+ listen_for_responses
46
+
47
+ @prepared_channel = true
48
+ end
49
+
50
+ def publish_rpc_call(request, correlation_id)
51
+ @exchange.publish(request, routing_key: @queue_name,
52
+ correlation_id: correlation_id,
53
+ reply_to: @reply_queue.name
54
+ )
55
+ end
56
+
57
+ def prepare_payload(method, *params)
58
+ JsonParser.new.build_request(method, *params)
59
+ end
60
+
61
+ def calculate_correlation_id
62
+ SecureRandom.uuid
63
+ end
64
+
65
+ def listen_for_responses
66
+ @reply_queue.subscribe(block: false) do |metadata, payload|
67
+ @results[metadata.correlation_id].push(payload)
68
+ end
69
+ end
70
+
71
+ def block_till_receive_response(correlation_id)
72
+ raw_response = @results[correlation_id].pop # blocks until can pop
73
+ response = parse_response(raw_response)
74
+ @results.delete(correlation_id)
75
+
76
+ response
77
+ end
78
+
79
+ def parse_response(response)
80
+ JsonParser.new.parse_response(response)
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,55 @@
1
+ module Lagomorph
2
+ class Session
3
+
4
+ CONNECTION_PARAM_KEYS = [
5
+ :host,
6
+ :heartbeat_interval,
7
+ :username,
8
+ :password,
9
+ :port
10
+ ]
11
+
12
+
13
+ def self.connect(connection_params)
14
+ new(connection_params).tap(&:open_connection)
15
+ end
16
+
17
+
18
+ def initialize(connection_params)
19
+ @connection_params = connection_params.select { |key,_|
20
+ CONNECTION_PARAM_KEYS.include?(key)
21
+ }
22
+ @mutex = Monitor.new
23
+ end
24
+
25
+ def open_connection
26
+ @mutex.synchronize do
27
+ @connection ||= if Lagomorph.using_bunny?
28
+ ::Bunny.new(@connection_params).tap(&:start)
29
+ else
30
+ ::MarchHare.connect(@connection_params)
31
+ end
32
+ end
33
+ end
34
+
35
+ def close_connection
36
+ return if @connection.nil? || @connection.closed?
37
+ @mutex.synchronize do
38
+ @connection.close
39
+ end
40
+ end
41
+
42
+ def create_channel(prefetch = nil)
43
+ @mutex.synchronize do
44
+ channel = @connection.create_channel
45
+ if Lagomorph.using_bunny?
46
+ channel.prefetch(prefetch)
47
+ else
48
+ channel.prefetch = prefetch
49
+ end
50
+ channel
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,42 @@
1
+ require 'lagomorph/json_parser'
2
+
3
+ module Lagomorph
4
+ class Subscriber
5
+
6
+ def initialize(worker_class)
7
+ @worker_class = worker_class
8
+ end
9
+
10
+ def subscribe(queue, channel)
11
+ queue.subscribe(manual_ack: true, block: false) do |metadata, payload|
12
+ result = process_request(payload)
13
+ response = build_response(result)
14
+ channel.ack(metadata.delivery_tag)
15
+ publish_response(channel, metadata, response)
16
+ end
17
+ end
18
+
19
+
20
+ private
21
+
22
+ def process_request(request)
23
+ method, params = parse_request(request)
24
+ @worker_class.new.send(method, *params)
25
+ end
26
+
27
+ def publish_response(channel, metadata, payload)
28
+ channel.default_exchange.publish(payload,
29
+ routing_key: metadata.reply_to,
30
+ correlation_id: metadata.correlation_id)
31
+ end
32
+
33
+ def parse_request(payload)
34
+ JsonParser.new.parse_request(payload)
35
+ end
36
+
37
+ def build_response(result)
38
+ JsonParser.new.build_response(result)
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ require 'lagomorph/queue_builder'
2
+ require 'lagomorph/json_parser'
3
+
4
+ module Lagomorph
5
+ class Supervisor
6
+
7
+ def initialize(session)
8
+ @session = session
9
+ end
10
+
11
+ def route(queue_name, worker_class)
12
+ prefetch = 10
13
+ durable = false
14
+
15
+ channel = @session.create_channel(prefetch)
16
+ queue = QueueBuilder.new(channel).queue(queue_name, durable: durable)
17
+
18
+ Subscriber.new(worker_class).subscribe(queue, channel)
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Lagomorph
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+ require 'lagomorph/session'
4
+ require 'lagomorph/supervisor'
5
+ require 'lagomorph/subscriber'
6
+ require 'lagomorph/rpc_call'
7
+
8
+ describe 'a Lagomorph RPC process' do
9
+
10
+ let(:rabbitmq_config) {
11
+ YAML.load_file(
12
+ File.join(File.expand_path(File.dirname(__FILE__)),'rabbitmq.yml')
13
+ )
14
+ }
15
+
16
+ class PongWorker
17
+ def pong
18
+ 'pong'
19
+ end
20
+
21
+ def echo(request)
22
+ request
23
+ end
24
+ end
25
+
26
+ context 'when supervising a PongWorker on the ping queue' do
27
+ let(:connection_params) {
28
+ {
29
+ host: rabbitmq_config.fetch('host'),
30
+ username: rabbitmq_config.fetch('username'),
31
+ password: rabbitmq_config.fetch('password')
32
+ }
33
+ }
34
+
35
+ let(:session) { Lagomorph::Session.connect(connection_params) }
36
+
37
+ let(:supervisor) { Lagomorph::Supervisor.new(session) }
38
+
39
+ let(:queue) { 'ping' }
40
+
41
+ before do
42
+ supervisor.route queue, PongWorker
43
+ end
44
+
45
+ context 'and we have an rpc call manager thingy' do
46
+ let!(:rpc_call) { Lagomorph::RpcCall.new(session) }
47
+
48
+ context 'when a pong rpc call is made on the ping queue' do
49
+ let(:result) { rpc_call.dispatch(queue, 'pong') }
50
+ it { expect(result).to eq 'pong' }
51
+ end
52
+
53
+ context 'when an echo rpc call is made on the ping queue' do
54
+ let(:result) { rpc_call.dispatch(queue, 'echo', 'test') }
55
+ it { expect(result).to eq 'test' }
56
+ end
57
+ after { rpc_call.close_channel }
58
+ end
59
+
60
+ context 'when using 8 threads, with one instance per thread' do
61
+ let(:number_of_threads) { 8 }
62
+ let(:total_calls) { 800 }
63
+ let(:calls_per_thread) { (total_calls / number_of_threads).ceil }
64
+
65
+ let(:rpc_calls) {
66
+ 1.upto(number_of_threads).map { Lagomorph::RpcCall.new(session) }
67
+ }
68
+
69
+ specify 'each thread will get the expected response' do
70
+ rpc_calls.map do |rpc_call|
71
+ Thread.new do
72
+ thread_results = calls_per_thread.times.map { |call_index|
73
+ rpc_call.dispatch(queue, 'echo', call_index).tap { |result|
74
+ expect(result).to eq call_index
75
+ }
76
+ }
77
+ end
78
+ end.each(&:join)
79
+
80
+ rpc_calls.each(&:close_channel)
81
+ end
82
+ end
83
+
84
+ after do
85
+ session.close_connection
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,3 @@
1
+ host: '127.0.0.1'
2
+ username: 'guest'
3
+ password: 'guest'
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'lagomorph'
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lagomorph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alessandro Berardi
8
+ - Adam Davies
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-11-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ name: json
21
+ prerelease: false
22
+ type: :runtime
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ name: bundler
35
+ prerelease: false
36
+ type: :development
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '1.7'
42
+ - !ruby/object:Gem::Dependency
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ name: march_hare
49
+ prerelease: false
50
+ type: :development
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ name: rake
63
+ prerelease: false
64
+ type: :development
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - !ruby/object:Gem::Dependency
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ name: rspec
77
+ prerelease: false
78
+ type: :development
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: "\n Lagomorph is a mammal of the order Lagomorpha, which comprises\
85
+ \ the hares, rabbits, and pikas.\n\n It's also a gem that implements the RPC\
86
+ \ pattern over AMPQ using RabbitMQ.\n In this case, it can work with either MRI\
87
+ \ (through the bunny gem) or jRuby \n (via the march_hare gem).\n "
88
+ email:
89
+ - berardialessandro@gmail.com
90
+ - adzdavies@gmail.com
91
+ executables: []
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - .gitignore
96
+ - .rspec
97
+ - .ruby-version
98
+ - .travis.yml
99
+ - Gemfile
100
+ - LICENSE.txt
101
+ - README.md
102
+ - Rakefile
103
+ - lagomorph.gemspec
104
+ - lib/lagomorph.rb
105
+ - lib/lagomorph/json_parser.rb
106
+ - lib/lagomorph/metadata_adapter.rb
107
+ - lib/lagomorph/queue_adapter.rb
108
+ - lib/lagomorph/queue_builder.rb
109
+ - lib/lagomorph/rpc_call.rb
110
+ - lib/lagomorph/session.rb
111
+ - lib/lagomorph/subscriber.rb
112
+ - lib/lagomorph/supervisor.rb
113
+ - lib/lagomorph/version.rb
114
+ - spec/lagomorph_spec.rb
115
+ - spec/rabbitmq.yml.example
116
+ - spec/spec_helper.rb
117
+ homepage: ''
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.1.9
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: RPC Messaging pattern using RabbitMQ
141
+ test_files:
142
+ - spec/lagomorph_spec.rb
143
+ - spec/rabbitmq.yml.example
144
+ - spec/spec_helper.rb