liebre 0.1.21 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile.lock +9 -7
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/README.md +492 -195
  6. data/Rakefile +2 -0
  7. data/lib/liebre.rb +27 -16
  8. data/lib/liebre/actor.rb +11 -0
  9. data/lib/liebre/actor/consumer.rb +80 -0
  10. data/lib/liebre/actor/consumer/callback.rb +34 -0
  11. data/lib/liebre/actor/consumer/core.rb +80 -0
  12. data/lib/liebre/actor/consumer/reporter.rb +84 -0
  13. data/lib/liebre/actor/consumer/resources.rb +47 -0
  14. data/lib/liebre/actor/consumer/resources/config.rb +65 -0
  15. data/lib/liebre/actor/context.rb +40 -0
  16. data/lib/liebre/actor/context/declare.rb +44 -0
  17. data/lib/liebre/actor/context/handler.rb +44 -0
  18. data/lib/liebre/actor/publisher.rb +58 -0
  19. data/lib/liebre/actor/publisher/core.rb +42 -0
  20. data/lib/liebre/actor/publisher/reporter.rb +55 -0
  21. data/lib/liebre/actor/publisher/resources.rb +33 -0
  22. data/lib/liebre/actor/rpc/client.rb +88 -0
  23. data/lib/liebre/actor/rpc/client/core.rb +75 -0
  24. data/lib/liebre/actor/rpc/client/pending.rb +65 -0
  25. data/lib/liebre/actor/rpc/client/reporter.rb +71 -0
  26. data/lib/liebre/actor/rpc/client/resources.rb +62 -0
  27. data/lib/liebre/actor/rpc/client/task.rb +33 -0
  28. data/lib/liebre/actor/rpc/server.rb +74 -0
  29. data/lib/liebre/actor/rpc/server/callback.rb +28 -0
  30. data/lib/liebre/actor/rpc/server/core.rb +75 -0
  31. data/lib/liebre/actor/rpc/server/reporter.rb +72 -0
  32. data/lib/liebre/actor/rpc/server/resources.rb +53 -0
  33. data/lib/liebre/adapter.rb +8 -0
  34. data/lib/liebre/adapter/bunny.rb +23 -0
  35. data/lib/liebre/adapter/bunny/chan.rb +38 -0
  36. data/lib/liebre/adapter/bunny/conn.rb +32 -0
  37. data/lib/liebre/adapter/bunny/exchange.rb +20 -0
  38. data/lib/liebre/adapter/bunny/queue.rb +59 -0
  39. data/lib/liebre/adapter/interface.rb +26 -0
  40. data/lib/liebre/adapter/interface/chan.rb +29 -0
  41. data/lib/liebre/adapter/interface/conn.rb +21 -0
  42. data/lib/liebre/adapter/interface/exchange.rb +13 -0
  43. data/lib/liebre/adapter/interface/queue.rb +37 -0
  44. data/lib/liebre/bridge.rb +72 -0
  45. data/lib/liebre/bridge/channel_builder.rb +36 -0
  46. data/lib/liebre/config.rb +8 -38
  47. data/lib/liebre/engine.rb +61 -0
  48. data/lib/liebre/engine/builder.rb +48 -0
  49. data/lib/liebre/engine/repository.rb +56 -0
  50. data/lib/liebre/engine/state.rb +49 -0
  51. data/lib/liebre/runner.rb +15 -47
  52. data/lib/liebre/version.rb +1 -1
  53. data/liebre.gemspec +9 -7
  54. data/spec/integration/publish_and_consume_spec.rb +71 -0
  55. data/spec/integration/rpc_communication_spec.rb +81 -0
  56. data/spec/integration/start_twice_spec.rb +63 -0
  57. data/spec/liebre/actor/consumer_spec.rb +169 -0
  58. data/spec/liebre/actor/context/declare_spec.rb +69 -0
  59. data/spec/liebre/actor/context/handler_spec.rb +65 -0
  60. data/spec/liebre/actor/publisher_spec.rb +58 -0
  61. data/spec/liebre/actor/rpc/client_spec.rb +126 -0
  62. data/spec/liebre/actor/rpc/server_spec.rb +141 -0
  63. data/spec/liebre/adapter/bunny_spec.rb +66 -0
  64. data/spec/liebre/bridge_spec.rb +54 -0
  65. data/spec/liebre/engine/builder_spec.rb +42 -0
  66. data/spec/liebre/engine_spec.rb +90 -0
  67. data/spec/liebre/version_spec.rb +10 -0
  68. data/spec/spec_helper.rb +2 -9
  69. metadata +97 -58
  70. data/lib/liebre/common.rb +0 -7
  71. data/lib/liebre/common/utils.rb +0 -37
  72. data/lib/liebre/connection_manager.rb +0 -85
  73. data/lib/liebre/publisher.rb +0 -113
  74. data/lib/liebre/runner/consumers.rb +0 -46
  75. data/lib/liebre/runner/starter.rb +0 -44
  76. data/lib/liebre/runner/starter/consumer.rb +0 -129
  77. data/lib/liebre/runner/starter/consumer/handler.rb +0 -35
  78. data/lib/liebre/runner/starter/resources.rb +0 -45
  79. data/lib/liebre/runner/starter/resources/queue_builder.rb +0 -63
  80. data/lib/liebre/runner/starter/rpc.rb +0 -59
  81. data/lib/liebre/tasks.rb +0 -12
  82. data/spec/config/liebre.yml +0 -48
  83. data/spec/config/rabbitmq.yml +0 -35
  84. data/spec/integration_spec.rb +0 -76
  85. data/spec/liebre/config_spec.rb +0 -63
  86. data/spec/liebre/connection_manager_spec.rb +0 -44
  87. data/spec/liebre/publisher_spec.rb +0 -92
  88. data/spec/liebre/runner/consumers_spec.rb +0 -59
  89. data/spec/liebre/runner/starter/consumer_spec.rb +0 -145
  90. data/spec/liebre/runner/starter/resources/queue_builder_spec.rb +0 -69
  91. data/spec/liebre/runner/starter/resources_spec.rb +0 -38
  92. data/spec/liebre/runner/starter/rpc_spec.rb +0 -100
  93. data/spec/liebre/runner/starter_spec.rb +0 -70
  94. data/spec/liebre/runner_spec.rb +0 -54
@@ -0,0 +1,58 @@
1
+ RSpec.describe Liebre::Actor::Publisher do
2
+
3
+ let(:chan) { double 'chan' }
4
+ let(:declare) { double 'declare' }
5
+ let(:spec) { {:exchange => {:fake => "config"}} }
6
+ let(:logger) { double 'logger', :info => nil, :error => nil }
7
+
8
+ let :context do
9
+ double 'context', :chan => chan,
10
+ :declare => declare,
11
+ :name => "foo",
12
+ :spec => spec,
13
+ :logger => logger
14
+ end
15
+
16
+ subject { described_class.new(context) }
17
+
18
+ before do
19
+ allow(subject).to receive(:async).and_return(subject)
20
+ end
21
+
22
+ let(:exchange) { double 'exchange' }
23
+
24
+ before do
25
+ allow(declare).to receive(:exchange).
26
+ with(:fake => "config").and_return(exchange)
27
+ end
28
+
29
+ describe '#start' do
30
+ it 'declares the exchange' do
31
+ expect(declare).to receive(:exchange).
32
+ with(:fake => "config").and_return(exchange)
33
+
34
+ subject.start
35
+ end
36
+ end
37
+
38
+ describe '#clean' do
39
+ it 'deletes the exchange' do
40
+ expect(exchange).to receive(:delete)
41
+
42
+ subject.clean
43
+ end
44
+ end
45
+
46
+ describe '#publish' do
47
+ it 'publishes through the exchange' do
48
+ allow(declare).to receive(:exchange).
49
+ with(:fake => "config").and_return(exchange)
50
+
51
+ expect(exchange).to receive(:publish).
52
+ with("some_data", :routing_key => "bar")
53
+
54
+ subject.publish("some_data", :routing_key => "bar")
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,126 @@
1
+ require 'concurrent'
2
+
3
+ RSpec.describe Liebre::Actor::RPC::Client do
4
+
5
+ let(:chan) { double 'chan' }
6
+ let(:declare) { double 'declare' }
7
+
8
+ let :spec do
9
+ {:exchange => {:fake => "exchange_config"},
10
+ :queue => {:prefix => "client_test"},
11
+ :bind => {:fake => "bind_config"}}
12
+ end
13
+
14
+ let(:logger) { double 'logger', :info => nil, :error => nil }
15
+
16
+ let :context do
17
+ double 'context', :chan => chan,
18
+ :declare => declare,
19
+ :name => "foo",
20
+ :spec => spec,
21
+ :logger => logger
22
+ end
23
+
24
+ subject { described_class.new(context) }
25
+
26
+ let(:response_queue) { double 'request_queue', :name => "queue_1234" }
27
+ let(:request_exchange) { double 'request_exchange' }
28
+ let(:task) { double 'task', :execute => true, :shutdown => true }
29
+
30
+ before do
31
+ allow(subject).to receive(:async).and_return(subject)
32
+
33
+ allow(declare).to receive :queue do |config|
34
+ expect(config[:name]).to match /^client_test_.+$/
35
+ expect(config[:opts]).to eq :auto_delete => true, :exclusive => true, :durable => false
36
+
37
+ response_queue
38
+ end
39
+
40
+ allow(declare).to receive(:exchange).
41
+ with(:fake => "exchange_config").and_return(request_exchange)
42
+
43
+ allow(Concurrent::TimerTask).to receive(:new).
44
+ with(anything).and_return(task)
45
+ end
46
+
47
+ let(:info) { double 'info' }
48
+ let(:meta) { double 'meta' }
49
+ let(:payload) { "some_payload" }
50
+ let(:response) { "some_response" }
51
+
52
+ describe '#start' do
53
+ it 'declares queue and exchange, and subscribes to the queue' do
54
+ expect(declare).to receive :queue do |config|
55
+ expect(config[:name]).to match /^client_test_.+$/
56
+ expect(config[:opts]).to eq :auto_delete => true, :exclusive => true, :durable => false
57
+
58
+ response_queue
59
+ end
60
+
61
+ expect(declare).to receive(:exchange).
62
+ with(:fake => "exchange_config").and_return(request_exchange)
63
+
64
+ subscription_block = nil
65
+ expect(response_queue).to receive(:subscribe) do |opts, &block|
66
+ expect(opts).to eq :block => false, :manual_ack => false
67
+ subscription_block = block
68
+ end
69
+
70
+ task_block = nil
71
+ expect(Concurrent::TimerTask).to receive(:new) do |opts, &block|
72
+ expect(opts[:execution_interval]).to be_a Numeric
73
+ task_block = block
74
+
75
+ task
76
+ end
77
+ expect(task).to receive(:execute)
78
+
79
+ subject.start
80
+
81
+ expect(subject).to receive(:reply).with(meta, response)
82
+ subscription_block.(info, meta, response)
83
+
84
+ expect(subject).to receive(:expire)
85
+ task_block.()
86
+ end
87
+ end
88
+
89
+ describe '#clean' do
90
+ it 'deletes queue and exchange' do
91
+ expect(response_queue ).to receive(:delete)
92
+ expect(request_exchange).to receive(:delete)
93
+
94
+ subject.clean
95
+ end
96
+ end
97
+
98
+ describe '#request and #reply' do
99
+ it 'replies and releases the client only when a matching response is received' do
100
+ correlation_id = nil
101
+ expect(request_exchange).to receive :publish do |given_payload, opts|
102
+ expect(payload ).to eq payload
103
+ expect(opts[:reply_to]).to eq "queue_1234"
104
+
105
+ correlation_id = opts[:correlation_id]
106
+ end
107
+
108
+ thread = Thread.new do
109
+ subject.request(payload)
110
+ end
111
+ sleep(0.1)
112
+ expect(thread.alive?).to eq true # waiting for response
113
+
114
+ no_matching_meta = double("not_matching_meta", :correlation_id => "not-matching")
115
+ subject.reply(no_matching_meta, response)
116
+ sleep(0.1)
117
+ expect(thread.alive?).to eq true # waiting for a matching response
118
+
119
+ matching_meta = double("matching_meta", :correlation_id => correlation_id)
120
+ subject.reply(matching_meta, response)
121
+ sleep(0.1)
122
+ expect(thread.value).to eq response
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,141 @@
1
+ RSpec.describe Liebre::Actor::RPC::Server do
2
+
3
+ let(:chan) { double 'chan' }
4
+ let(:declare) { double 'declare' }
5
+ let(:handler) { double 'handler' }
6
+
7
+ let :spec do
8
+ {:exchange => {:fake => "exchange_config"},
9
+ :queue => {:fake => "queue_config"},
10
+ :bind => {:fake => "bind_config"}}
11
+ end
12
+
13
+ let(:logger) { double 'logger', :info => nil, :error => nil }
14
+
15
+ let :context do
16
+ double 'context', :chan => chan,
17
+ :declare => declare,
18
+ :name => "foo",
19
+ :handler => handler,
20
+ :spec => spec,
21
+ :logger => logger
22
+ end
23
+
24
+ subject { described_class.new(context) }
25
+
26
+ let(:request_queue) { double 'request_queue' }
27
+ let(:request_exchange) { double 'request_exchange' }
28
+ let(:response_exchange) { double 'response_exchange' }
29
+
30
+ before do
31
+ allow(subject).to receive(:async).and_return(subject)
32
+
33
+ allow(declare).to receive(:queue).
34
+ with(:fake => "queue_config").and_return(request_queue)
35
+
36
+ allow(declare).to receive(:exchange).
37
+ with(:fake => "exchange_config").and_return(request_exchange)
38
+
39
+ allow(declare).to receive(:default_exchange).
40
+ and_return(response_exchange)
41
+
42
+ allow(declare).to receive(:bind).
43
+ with(request_queue, request_exchange, :fake => "bind_config")
44
+ end
45
+
46
+ let(:info) { double 'info' }
47
+ let(:payload) { "some_data" }
48
+
49
+ let :meta do
50
+ double 'meta', :reply_to => "reply.queue",
51
+ :correlation_id => "123"
52
+ end
53
+
54
+ describe '#start' do
55
+ it 'declares and binds queue and exchange, and subscribes to the queue' do
56
+ expect(declare).to receive(:queue).
57
+ with(:fake => "queue_config").and_return(request_queue)
58
+
59
+ expect(declare).to receive(:exchange).
60
+ with(:fake => "exchange_config").and_return(request_exchange)
61
+
62
+ expect(declare).to receive(:default_exchange).
63
+ and_return(response_exchange)
64
+
65
+ expect(declare).to receive(:bind).
66
+ with(request_queue, request_exchange, :fake => "bind_config")
67
+
68
+ subscription_block = nil
69
+ expect(request_queue).to receive(:subscribe) do |opts, &block|
70
+ expect(opts).to eq :block => false, :manual_ack => false
71
+ subscription_block = block
72
+ end
73
+
74
+ subject.start
75
+
76
+ expect(subject).to receive(:handle).
77
+ with(meta, payload)
78
+
79
+ subscription_block.(info, meta, payload)
80
+ end
81
+ end
82
+
83
+ describe '#clean' do
84
+ it 'deletes queue and exchange' do
85
+ expect(request_queue ).to receive(:delete)
86
+ expect(response_exchange).to receive(:delete)
87
+
88
+ subject.clean
89
+ end
90
+ end
91
+
92
+ describe '#handle' do
93
+ context 'on success' do
94
+ let(:response) { "some_response" }
95
+
96
+ it 'runs the handler with a callback object' do
97
+ callback = nil
98
+ expect(handler).to receive :call do |given_payload, given_meta, given_callback|
99
+ expect(given_payload).to eq payload
100
+ expect(given_meta ).to eq meta
101
+
102
+ callback = given_callback
103
+ end
104
+
105
+ subject.handle(meta, payload)
106
+
107
+ expect(subject).to receive(:reply).with(meta, "some_response", {})
108
+ callback.reply(response)
109
+ end
110
+ end
111
+
112
+ context 'on handler failure' do
113
+ let(:error) { double 'error' }
114
+
115
+ it 'calls failed on the server' do
116
+ error_block = nil
117
+ expect(handler).to receive :call do |payload, meta, callback, &block|
118
+ error_block = block
119
+ end
120
+
121
+ subject.handle(meta, payload)
122
+
123
+ expect(subject).to receive(:failed).
124
+ with(meta, error)
125
+
126
+ error_block.(error)
127
+ end
128
+ end
129
+ end
130
+
131
+ describe '#reply' do
132
+ let(:response) { "some_response" }
133
+
134
+ it 'delegates to the queue' do
135
+ expect(response_exchange).to receive(:publish).
136
+ with(response, :routing_key => "reply.queue", :correlation_id => "123")
137
+ subject.reply(meta, response)
138
+ end
139
+ end
140
+
141
+ end
@@ -0,0 +1,66 @@
1
+ RSpec.describe Liebre::Adapter::Bunny do
2
+
3
+ subject { described_class.new }
4
+
5
+ describe '#connect and conn methods' do
6
+ let(:opts) { {:host => "localhost"} }
7
+
8
+ let(:common_opts) { {:auto_delete => true, :durable => false} }
9
+
10
+ it 'everything' do
11
+ # start a connection
12
+ #
13
+ conn = subject.connection(opts)
14
+ session = conn.session
15
+
16
+ expect(conn.opts ).to eq opts
17
+ expect(session.open?).to eq false
18
+
19
+ conn.start
20
+ expect(session.open?).to eq true
21
+
22
+ # open a channel
23
+ #
24
+ chan = conn.open_channel
25
+ channel = chan.channel
26
+ expect(channel.open?).to eq true
27
+
28
+ # open an exchange, a queue and bind them
29
+ #
30
+ exchange = chan.exchange("foo", "fanout", common_opts)
31
+ queue = chan.queue("bar", common_opts)
32
+ queue.bind(exchange)
33
+
34
+ # publish and get message, reject and ack
35
+ #
36
+ exchange.publish("some_data")
37
+
38
+ queue.get(:manual_ack => true) do |info, properties, payload|
39
+ expect(payload).to eq "some_data"
40
+
41
+ queue.reject(info, :requeue => true)
42
+ end
43
+
44
+ queue.get(:manual_ack => true) do |info, properties, payload|
45
+ expect(payload).to eq "some_data"
46
+
47
+ queue.ack(info, :requeue => true)
48
+ end
49
+
50
+ queue.get(:manual_ack => true) do |*args|
51
+ expect(args).to eq [nil, nil, nil]
52
+ end
53
+
54
+ # close a channel
55
+ #
56
+ chan.close
57
+ expect(channel.open?).to eq false
58
+
59
+ # stop a connection
60
+ #
61
+ conn.stop
62
+ expect(session.open?).to eq false
63
+ end
64
+ end
65
+
66
+ end
@@ -0,0 +1,54 @@
1
+ RSpec.describe Liebre::Bridge do
2
+
3
+ let(:adapter) { double 'adapter' }
4
+
5
+ let(:name_1) { :foo }
6
+ let(:name_2) { :bar }
7
+ let(:opts_1) { double 'opts_1' }
8
+ let(:opts_2) { double 'opts_2' }
9
+
10
+ let(:connections) { {name_1 => opts_1, name_2 => opts_2}}
11
+
12
+ let(:logger) { double 'logger', :info => nil }
13
+
14
+ let :config do
15
+ double 'config', :adapter => adapter,
16
+ :connections => connections,
17
+ :logger => logger
18
+ end
19
+
20
+ subject { described_class.new(config) }
21
+
22
+ let(:conn_1) { double 'conn_1' }
23
+ let(:conn_2) { double 'conn_2' }
24
+
25
+ before do
26
+ allow(adapter).to receive(:connection).
27
+ with(opts_1).and_return(conn_1)
28
+
29
+ allow(adapter).to receive(:connection).
30
+ with(opts_2).and_return(conn_2)
31
+ end
32
+
33
+ describe '#open_channel' do
34
+ let(:chan) { double 'chan' }
35
+
36
+ let :chan_opts do
37
+ {:connection => name_2, :prefetch_count => 8}
38
+ end
39
+
40
+ it 'opens configured channels' do
41
+ expect(conn_1).to receive(:start)
42
+ expect(conn_2).to receive(:start)
43
+ subject.start
44
+
45
+ expect(conn_2).to receive(:open_channel).
46
+ and_return(chan)
47
+ expect(chan).to receive(:set_prefetch).
48
+ with(chan_opts[:prefetch_count])
49
+
50
+ expect(subject.open_channel(chan_opts)).to eq chan
51
+ end
52
+ end
53
+
54
+ end