liebre 0.1.21 → 0.2.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.
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,81 @@
1
+ RSpec.describe "RPC client-server communication" do
2
+
3
+ let(:connections) { {"test_conn" => {}} }
4
+
5
+ let :exchange do
6
+ {:name => "__test__.liebre.rpc_communication_exchange",
7
+ :type => "fanout",
8
+ :opts => {:auto_delete => true, :durable => false}}
9
+ end
10
+
11
+ let :client_queue do
12
+ {:prefix => "__test__.liebre.client_rpc_communication_queue"}
13
+ end
14
+
15
+ let :server_queue do
16
+ {:name => "__test__.liebre.server_rpc_communication_queue",
17
+ :opts => {:auto_delete => true, :durable => false}}
18
+ end
19
+
20
+ let(:handler_class) { double 'handler_class' }
21
+ let(:handler) { double 'handler' }
22
+
23
+ let :actors do
24
+ {
25
+ :rpc_clients => {
26
+ :my_client => {
27
+ :connection => "test_conn",
28
+ :resources => {:exchange => exchange, :queue => client_queue}
29
+ }
30
+ },
31
+ :rpc_servers => {
32
+ :my_server => {
33
+ :connection => "test_conn",
34
+ :prefetch_count => 5,
35
+ :pool_size => 1,
36
+ :handler => handler_class,
37
+ :resources => {:exchange => exchange, :queue => server_queue}
38
+ }
39
+ }
40
+ }
41
+ end
42
+
43
+ let :config do
44
+ Liebre::Config.new.tap do |config|
45
+ config.adapter = Liebre::Adapter::Bunny
46
+ config.connections = connections
47
+ config.actors = actors
48
+ end
49
+ end
50
+
51
+ let(:payload) { "some_data" }
52
+ let(:headers) { {"foo" => "bar"} }
53
+
54
+ let(:response) { "some_response" }
55
+
56
+ it "sends and receives data" do
57
+ engine = Liebre::Engine.new(config)
58
+ engine.start
59
+
60
+ repo = engine.repo
61
+ rpc_client = repo.rpc_client(:my_client)
62
+
63
+ callback = nil
64
+ expect(handler_class).to receive :new do |payload, meta, given_callback|
65
+ expect(payload ).to eq payload
66
+ expect(meta.headers).to eq headers
67
+ callback = given_callback
68
+
69
+ handler
70
+ end
71
+ expect(handler).to receive :call do
72
+ callback.reply(response)
73
+ end
74
+
75
+ sleep(0.1) # wait for all declarations and bindings to take place
76
+
77
+ opts = {:headers => headers}
78
+ expect(rpc_client.request(payload, opts, 0.2)).to eq response
79
+ end
80
+
81
+ end
@@ -0,0 +1,63 @@
1
+ RSpec.describe "Start actors twice" do
2
+
3
+ let(:connections) { {"test_conn" => {}} }
4
+
5
+ let :exchange do
6
+ {:name => "__test__.liebre.publish_and_consume_exchange",
7
+ :type => "fanout",
8
+ :opts => {:auto_delete => true, :durable => false}}
9
+ end
10
+
11
+ let :queue do
12
+ {:name => "__test__.liebre.publish_and_consume_queue",
13
+ :opts => {:auto_delete => true, :durable => false}}
14
+ end
15
+
16
+ let(:handler_class) { double 'handler_class' }
17
+ let(:handler) { double 'handler' }
18
+
19
+ let :actors do
20
+ {
21
+ :publishers => {
22
+ :my_publisher => {
23
+ :connection => "test_conn",
24
+ :resources => {:exchange => exchange}
25
+ }
26
+ },
27
+ :consumers => {
28
+ :my_consumer => {
29
+ :connection => "test_conn",
30
+ :prefetch_count => 5,
31
+ :pool_size => 1,
32
+ :handler => handler_class,
33
+ :resources => {:exchange => exchange, :queue => queue}
34
+ }
35
+ }
36
+ }
37
+ end
38
+
39
+ let :config do
40
+ Liebre::Config.new.tap do |config|
41
+ config.adapter = Liebre::Adapter::Bunny
42
+ config.connections = connections
43
+ config.actors = actors
44
+ end
45
+ end
46
+
47
+ let(:payload) { "some_data" }
48
+ let(:headers) { {"foo" => "bar"} }
49
+
50
+ it "sends and receives data" do
51
+ engine = Liebre::Engine.new(config)
52
+ repo = engine.repo
53
+
54
+ engine.start(only: [:publishers, :rpc_servers])
55
+ expect(repo.publisher(:my_publisher)).not_to be nil
56
+ expect { repo.consumer(:my_consumer) }.to raise_error KeyError
57
+
58
+ engine.start()
59
+ expect(repo.publisher(:my_publisher)).not_to be nil
60
+ expect(repo.consumer(:my_consumer) ).not_to be nil
61
+ end
62
+
63
+ end
@@ -0,0 +1,169 @@
1
+ RSpec.describe Liebre::Actor::Consumer do
2
+
3
+ let(:chan) { double 'chan' }
4
+ let(:declare) { double 'declare' }
5
+ let(:handler) { double 'handler' }
6
+
7
+ let :spec do
8
+ {:exchange => {:name => "foo"},
9
+ :queue => {:name => "bar"},
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(:queue) { double 'queue' }
27
+ let(:exchange) { double 'exchange' }
28
+
29
+ let(:dead_queue) { double 'dead_queue' }
30
+ let(:dead_exchange) { double 'dead_exchange' }
31
+
32
+ let(:dead_letter_opts) do
33
+ {:arguments => {"x-dead-letter-exchange" => "bar-error"}}
34
+ end
35
+
36
+ before do
37
+ allow(subject).to receive(:async).and_return(subject)
38
+
39
+ allow(declare).to receive(:queue).
40
+ with(:name => "bar", :opts => dead_letter_opts).and_return(queue)
41
+
42
+ allow(declare).to receive(:exchange).
43
+ with(:name => "foo").and_return(exchange)
44
+
45
+ allow(declare).to receive(:queue).
46
+ with(:name => "bar-error", :opts => {}).and_return(dead_queue)
47
+
48
+ allow(declare).to receive(:exchange).
49
+ with(:name => "bar-error", :type => "fanout", :opts => {}).and_return(dead_exchange)
50
+
51
+ allow(declare).to receive(:bind).
52
+ with(queue, exchange, :fake => "bind_config")
53
+
54
+ allow(declare).to receive(:bind).
55
+ with(dead_queue, dead_exchange)
56
+ end
57
+
58
+ let(:info) { double 'info' }
59
+ let(:meta) { double 'meta' }
60
+ let(:payload) { "some_data" }
61
+
62
+ describe '#start' do
63
+ it 'declares and binds queue and exchange, and subscribes to the queue' do
64
+ expect(declare).to receive(:queue).
65
+ with(:name => "bar", :opts => dead_letter_opts).and_return(queue)
66
+
67
+ expect(declare).to receive(:exchange).
68
+ with(:name => "foo").and_return(exchange)
69
+
70
+ expect(declare).to receive(:bind).
71
+ with(queue, exchange, :fake => "bind_config")
72
+
73
+ expect(declare).to receive(:queue).
74
+ with(:name => "bar-error", :opts => {}).and_return(dead_queue)
75
+
76
+ expect(declare).to receive(:exchange).
77
+ with(:name => "bar-error", :type => "fanout", :opts => {}).and_return(dead_exchange)
78
+
79
+ expect(declare).to receive(:bind).
80
+ with(dead_queue, dead_exchange)
81
+
82
+ subscription_block = nil
83
+ expect(queue).to receive(:subscribe) do |opts, &block|
84
+ expect(opts).to eq :block => false, :manual_ack => true
85
+ subscription_block = block
86
+ end
87
+
88
+ subject.start
89
+
90
+ expect(subject).to receive(:consume).
91
+ with(info, meta, payload)
92
+
93
+ subscription_block.(info, meta, payload)
94
+ end
95
+ end
96
+
97
+ describe '#clean' do
98
+ it 'deletes all queues and exchanges' do
99
+ expect(queue ).to receive(:delete)
100
+ expect(exchange ).to receive(:delete)
101
+ expect(dead_queue ).to receive(:delete)
102
+ expect(dead_exchange).to receive(:delete)
103
+
104
+ subject.clean
105
+ end
106
+ end
107
+
108
+ describe '#consume' do
109
+ context 'on success' do
110
+ it 'runs the handler with a callbacks object' do
111
+ callback = nil
112
+ expect(handler).to receive :call do |given_payload, given_meta, given_callback|
113
+ expect(given_payload).to eq payload
114
+ expect(given_meta ).to eq meta
115
+
116
+ callback = given_callback
117
+ end
118
+
119
+ subject.consume(info, meta, payload)
120
+
121
+ expect(subject).to receive(:ack).with(info, {})
122
+ callback.ack()
123
+
124
+ expect(subject).to receive(:nack).with(info, {})
125
+ callback.nack()
126
+
127
+ expect(subject).to receive(:reject).with(info, :requeue => true)
128
+ callback.reject(:requeue => true)
129
+ end
130
+ end
131
+
132
+ context 'on handler failure' do
133
+ let(:error) { double 'error' }
134
+
135
+ it 'calls failed on the consumer' do
136
+ error_block = nil
137
+ expect(handler).to receive :call do |payload, meta, callback, &block|
138
+ error_block = block
139
+ end
140
+
141
+ subject.consume(info, meta, payload)
142
+
143
+ expect(subject).to receive(:failed).
144
+ with(info, error)
145
+
146
+ error_block.(error)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#ack, #nack, #reject and #failed' do
152
+ let(:error) { double 'error', :message => "foo", :backtrace => [] }
153
+
154
+ it 'delegates to the queue' do
155
+ expect(queue).to receive(:ack).with(info, {})
156
+ subject.ack(info)
157
+
158
+ expect(queue).to receive(:nack).with(info, {})
159
+ subject.nack(info)
160
+
161
+ expect(queue).to receive(:reject).with(info, :requeue => true)
162
+ subject.reject(info, :requeue => true)
163
+
164
+ expect(queue).to receive(:reject).with(info, {})
165
+ subject.failed(info, error)
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1,69 @@
1
+ RSpec.describe Liebre::Actor::Context::Declare do
2
+
3
+ let(:chan) { double 'chan' }
4
+
5
+ subject { described_class.new(chan) }
6
+
7
+ describe '#default_exchange' do
8
+ let(:default_exchange) { double 'default_exchange' }
9
+
10
+ it 'builds the default exchange' do
11
+ expect(chan).to receive(:default_exchange).
12
+ and_return(default_exchange)
13
+
14
+ expect(subject.default_exchange).to eq default_exchange
15
+ end
16
+ end
17
+
18
+ describe '#exchange' do
19
+ let(:exchange) { double 'exchange' }
20
+
21
+ let :opts do
22
+ {:name => "foo",
23
+ :type => "fanout",
24
+ :opts => {:durable => true}}
25
+ end
26
+
27
+ it 'builds an exchange with the given options' do
28
+ expect(chan).to receive(:exchange).
29
+ with("foo", "fanout", :durable => true).
30
+ and_return(exchange)
31
+
32
+ expect(subject.exchange(opts)).to eq exchange
33
+ end
34
+ end
35
+
36
+ describe '#queue' do
37
+ let(:queue) { double 'queue' }
38
+
39
+ let :opts do
40
+ {:name => "foo",
41
+ :opts => {:durable => true}}
42
+ end
43
+
44
+ it 'builds an queue with the given options' do
45
+ expect(chan).to receive(:queue).
46
+ with("foo", :durable => true).
47
+ and_return(queue)
48
+
49
+ expect(subject.queue(opts)).to eq queue
50
+ end
51
+ end
52
+
53
+ describe '#bind' do
54
+ let(:queue) { double 'queue' }
55
+ let(:exchange) { double 'exchange' }
56
+ let(:opts) { [{:routing_key => "foo"}, {:routing_key => "bar"}] }
57
+
58
+ it 'binds as many option sets as given' do
59
+ expect(queue).to receive(:bind).
60
+ with(exchange, :routing_key => "foo")
61
+
62
+ expect(queue).to receive(:bind).
63
+ with(exchange, :routing_key => "bar")
64
+
65
+ subject.bind(queue, exchange, opts)
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,65 @@
1
+ RSpec.describe Liebre::Actor::Context::Handler do
2
+
3
+ let(:pool_size) { 3 }
4
+ let(:handler_class) { double 'handler_class' }
5
+
6
+ let :opts do
7
+ {:pool_size => pool_size,
8
+ :handler => handler_class}
9
+ end
10
+
11
+ subject { described_class.new(opts) }
12
+
13
+ let(:pool) { double 'pool' }
14
+
15
+ before do
16
+ allow(Concurrent::FixedThreadPool).to receive(:new).
17
+ with(pool_size).and_return(pool)
18
+ end
19
+
20
+ describe '#call' do
21
+ def pool_block *args, &block
22
+ pool_block = nil
23
+ expect(pool).to receive :post do |&given_block|
24
+ pool_block = given_block
25
+ end
26
+
27
+ subject.call(*args, &block)
28
+ pool_block
29
+ end
30
+
31
+ let(:handler) { double 'handler' }
32
+
33
+ context 'on success' do
34
+ it 'runs the handler on the pool' do
35
+ block = pool_block("foo", "bar") {}
36
+
37
+ expect(handler_class).to receive(:new).
38
+ with("foo", "bar").and_return(handler)
39
+
40
+ expect(handler).to receive(:call)
41
+
42
+ block.()
43
+ end
44
+ end
45
+
46
+ context 'on handler error' do
47
+ let(:target) { double 'target' }
48
+
49
+ it 'runs the given block with the error as argument' do
50
+ block = pool_block("foo") { target.boom! }
51
+
52
+ expect(target).to receive(:boom!)
53
+
54
+ expect(handler_class).to receive(:new).
55
+ with("foo").and_return(handler)
56
+
57
+ expect(handler).to receive(:call).
58
+ and_raise("boom")
59
+
60
+ block.()
61
+ end
62
+ end
63
+ end
64
+
65
+ end