vx-common-amqp 0.2.6

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 (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +276 -0
  7. data/README.md +29 -0
  8. data/Rakefile +6 -0
  9. data/bin/vx-consumers +12 -0
  10. data/lib/vx/common/amqp/cli.rb +88 -0
  11. data/lib/vx/common/amqp/config.rb +74 -0
  12. data/lib/vx/common/amqp/consumer/ack.rb +19 -0
  13. data/lib/vx/common/amqp/consumer/configuration.rb +119 -0
  14. data/lib/vx/common/amqp/consumer/publish.rb +32 -0
  15. data/lib/vx/common/amqp/consumer/subscribe.rb +67 -0
  16. data/lib/vx/common/amqp/consumer.rb +70 -0
  17. data/lib/vx/common/amqp/formatter.rb +105 -0
  18. data/lib/vx/common/amqp/mixins/callbacks.rb +35 -0
  19. data/lib/vx/common/amqp/mixins/logger.rb +17 -0
  20. data/lib/vx/common/amqp/session.rb +154 -0
  21. data/lib/vx/common/amqp/supervisor/threaded.rb +171 -0
  22. data/lib/vx/common/amqp/testing.rb +54 -0
  23. data/lib/vx/common/amqp/version.rb +7 -0
  24. data/lib/vx/common/amqp.rb +68 -0
  25. data/spec/integration/multi_threaded_spec.rb +89 -0
  26. data/spec/integration/threaded_supervisor_spec.rb +85 -0
  27. data/spec/lib/amqp/config_spec.rb +32 -0
  28. data/spec/lib/amqp/consumer_spec.rb +316 -0
  29. data/spec/lib/amqp/formatter_spec.rb +47 -0
  30. data/spec/lib/amqp/mixins/callbacks_spec.rb +26 -0
  31. data/spec/lib/amqp/session_spec.rb +144 -0
  32. data/spec/lib/amqp/supervisor/threaded_spec.rb +124 -0
  33. data/spec/lib/amqp_spec.rb +9 -0
  34. data/spec/spec_helper.rb +13 -0
  35. data/spec/support/amqp.rb +15 -0
  36. data/spec/support/ignore_me_error.rb +1 -0
  37. data/vx-common-amqp.gemspec +30 -0
  38. metadata +178 -0
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+ require 'timeout'
3
+ require 'thread'
4
+
5
+ describe Vx::Common::AMQP::Session do
6
+ let(:sess) { described_class.new }
7
+ let(:queue_name) { 'foo' }
8
+ let(:exch_name) { 'bar' }
9
+
10
+ subject { sess }
11
+
12
+ before { sess.open }
13
+ after { sess.close }
14
+
15
+ context "open" do
16
+ its("conn.status") { should eq :open }
17
+ its(:open?) { should be }
18
+ end
19
+
20
+ context "should reuse connection" do
21
+ before do
22
+ @id = sess.conn.object_id
23
+ end
24
+ its("conn.object_id") { should eq @id }
25
+ end
26
+
27
+ context "should reuse channel" do
28
+ before do
29
+ @id = sess.channel.id
30
+ end
31
+ its("channel.id") { should eq @id }
32
+ end
33
+
34
+ it 'channel by default should eq connection default channel' do
35
+ expect(sess.channel.id).to eq sess.conn.default_channel.id
36
+ end
37
+
38
+ context "with_channel" do
39
+ before do
40
+ @default = sess.channel.id
41
+ end
42
+
43
+ it "should create and close a new channel" do
44
+ sess.with_channel do
45
+ expect(sess.channel.id).to_not eq @default
46
+ end
47
+ expect(sess.channel.id).to eq @default
48
+ end
49
+ end
50
+
51
+ context "close" do
52
+ it "should close connection" do
53
+ expect{ sess.close }.to change{ sess.open? }.from(true).to(nil)
54
+ end
55
+ end
56
+
57
+ context "declare_exchange" do
58
+ let(:options) {{}}
59
+ let(:exch) { sess.declare_exchange exch_name, options }
60
+ subject { exch }
61
+
62
+ after { delete_exchange exch }
63
+
64
+ it{ should be }
65
+
66
+ context "by default" do
67
+ its(:name) { should eq exch_name }
68
+ its(:type) { should eq :topic }
69
+ its(:durable?) { should be_true }
70
+ its(:auto_delete?) { should be_false }
71
+ its("channel.id") { should eq sess.channel.id }
72
+ end
73
+
74
+ context "when exchange name is nil should use default_exchange_name" do
75
+ let(:exch) { sess.declare_exchange nil, options }
76
+ its(:name) { should eq 'amq.topic' }
77
+ end
78
+
79
+ context "when pass durable: false" do
80
+ let(:options) { { durable: false } }
81
+ its(:durable?) { should be_false }
82
+ end
83
+
84
+ context "when pass auto_delete: true" do
85
+ let(:options) { { auto_delete: true } }
86
+ its(:auto_delete?) { should be_true }
87
+ end
88
+
89
+ context "when pass type: :fanout" do
90
+ let(:options) { { type: :fanout } }
91
+ its(:type) { should eq :fanout }
92
+ end
93
+
94
+ context "when pass :channel" do
95
+ let(:ch) { sess.conn.create_channel }
96
+ let(:options) { { channel: ch } }
97
+ its("channel.id") { should eq ch.id }
98
+ end
99
+ end
100
+
101
+ context "declare_queue" do
102
+ let(:options) {{}}
103
+ let(:queue) { sess.declare_queue queue_name, options }
104
+ subject { queue }
105
+
106
+ after { delete_queue queue }
107
+
108
+ it{ should be }
109
+
110
+ context "by default" do
111
+ its(:name) { should eq queue_name }
112
+ its(:durable?) { should be_true }
113
+ its(:auto_delete?) { should be_false }
114
+ its(:exclusive?) { should be_false }
115
+ its("channel.id") { should eq sess.channel.id }
116
+ end
117
+
118
+ context 'when queue name is nil should use generated name' do
119
+ let(:queue) { sess.declare_queue nil, options }
120
+ its(:name) { should match(/amq\.gen/) }
121
+ end
122
+
123
+ context "when pass durable: false" do
124
+ let(:options) { { durable: false } }
125
+ its(:durable?) { should be_false }
126
+ end
127
+
128
+ context "when pass auto_delete: true" do
129
+ let(:options) { { auto_delete: true } }
130
+ its(:auto_delete?) { should be_true }
131
+ end
132
+
133
+ context "when pass exclusive: true" do
134
+ let(:options) { { exclusive: true } }
135
+ its(:exclusive?) { should be_true }
136
+ end
137
+
138
+ context "when pass :channel" do
139
+ let(:ch) { sess.conn.create_channel }
140
+ let(:options) { { channel: ch } }
141
+ its("channel.id") { should eq ch.id }
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+ require 'timeout'
3
+
4
+ describe Vx::Common::AMQP::Supervisor::Threaded, jruby: true do
5
+ let(:supervisor) { described_class.new }
6
+ let(:runner) {
7
+ Struct.new(:timeout, :error) do
8
+ def run
9
+ sleep timeout
10
+ raise IgnoreMeError if error
11
+ end
12
+ end
13
+ }
14
+
15
+ after { Vx::Common::AMQP.config.reset! }
16
+ before { Vx::Common::AMQP.config.reset! }
17
+
18
+ it { should be }
19
+
20
+ it "should add a new task" do
21
+ expect{
22
+ supervisor.add runner.new(1, false), :run, 1
23
+ }.to change { supervisor.size }.from(0).to(1)
24
+ end
25
+
26
+ context "run" do
27
+ let(:mutex) { Mutex.new }
28
+ let(:collected) { [] }
29
+ let(:len) { 1 }
30
+ let(:runner) {
31
+ Proc.new do
32
+ id = Thread.current[:vx_amqp_consumer_id]
33
+ mutex.synchronize do
34
+ collected.push id
35
+ end
36
+ sleep 1
37
+ end
38
+ }
39
+
40
+ before do
41
+ len.times {|n| supervisor.add runner, :call, n + 1 }
42
+ expect(supervisor.size).to eq len
43
+ end
44
+
45
+ context "start one task" do
46
+ it "should be" do
47
+ timeout 2 do
48
+ th = supervisor.run_async
49
+ sleep 0.2
50
+ supervisor.shutdown
51
+ timeout(10) { th.join }
52
+ expect(collected).to eq [1]
53
+ end
54
+ end
55
+ end
56
+
57
+ context "start 5 tasks" do
58
+ let(:len) { 5 }
59
+
60
+ it "should be", slow: true do
61
+ timeout 10 do
62
+ th = supervisor.run_async
63
+ sleep 0.2
64
+ supervisor.shutdown
65
+ timeout(10) { th.join }
66
+ expect(collected.sort).to eq [1,2,3,4,5]
67
+ end
68
+ end
69
+ end
70
+
71
+ context "restart broken tasks" do
72
+ let(:len) { 2 }
73
+ let(:runner) {
74
+ Proc.new do
75
+ sleep 0.1
76
+ id = Thread.current[:vx_amqp_consumer_id]
77
+ mutex.synchronize do
78
+ collected.push id
79
+ end
80
+ raise IgnoreMeError
81
+ end
82
+ }
83
+ it "should be" do
84
+ timeout 10 do
85
+ th = supervisor.run_async
86
+ sleep 2.2
87
+ supervisor.shutdown
88
+ timeout(10) { th.join }
89
+ while !collected.empty?
90
+ first, second = collected.shift, collected.shift
91
+ expect([first,second].sort).to eq [1,2]
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ context "raise when attemts limit reached" do
98
+ let(:runner) {
99
+ Proc.new do
100
+ raise IgnoreMeError
101
+ end
102
+ }
103
+
104
+ it "should be" do
105
+ Vx::Common::AMQP.configure do |c|
106
+ c.spawn_attempts = 1
107
+ end
108
+ th = supervisor.run_async
109
+ th.abort_on_exception = false
110
+ timeout 10 do
111
+ expect {
112
+ th.join
113
+ }.to raise_error(Vx::Common::AMQP::Supervisor::Threaded::SpawnAttemptsLimitReached)
114
+ end
115
+ end
116
+ end
117
+
118
+ def timeout(val, &block)
119
+ Timeout.timeout(val, &block)
120
+ end
121
+ end
122
+
123
+ end
124
+
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vx::Common::AMQP do
4
+ let(:amqp) { described_class }
5
+ subject { amqp }
6
+
7
+ its(:config) { should be }
8
+ its(:session) { should be }
9
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path '../../lib/vx/common/amqp', __FILE__
2
+
3
+ require 'rspec/autorun'
4
+
5
+ Dir[File.expand_path("../..", __FILE__) + "/spec/support/**.rb"].each {|f| require f}
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rr
9
+
10
+ config.after(:suite) do
11
+ Vx::Common::AMQP.close
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ def delete_queue(q)
2
+ Vx::Common::AMQP.logger.info "[AMQP] delete queue #{q.inspect[0..30]}"
3
+ if q
4
+ q.purge
5
+ q.delete if_unused: false, if_empty: false
6
+ end
7
+ true
8
+ end
9
+
10
+ def delete_exchange(x)
11
+ Vx::Common::AMQP.logger.info "[AMQP] delete exchnage #{x.inspect[0..30]}"
12
+ x.delete if x
13
+ true
14
+ end
15
+
@@ -0,0 +1 @@
1
+ class IgnoreMeError < Exception ; end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vx/common/amqp/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vx-common-amqp"
8
+ spec.version = Vx::Common::AMQP::VERSION
9
+ spec.authors = ["Dmitry Galinsky"]
10
+ spec.email = ["dima.exe@gmail.com"]
11
+ spec.description = %q{ Common amqp code }
12
+ spec.summary = %q{ Common amqp code }
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+
23
+ spec.add_runtime_dependency "bunny", "~> 1.0.0"
24
+ spec.add_runtime_dependency "vx-common-rack-builder", "~> 0.0.2"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.3"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "rr"
30
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vx-common-amqp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Galinsky
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bunny
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: vx-common-rack-builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rr
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
+ description: ' Common amqp code '
98
+ email:
99
+ - dima.exe@gmail.com
100
+ executables:
101
+ - vx-consumers
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - .rspec
107
+ - .travis.yml
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/vx-consumers
113
+ - lib/vx/common/amqp.rb
114
+ - lib/vx/common/amqp/cli.rb
115
+ - lib/vx/common/amqp/config.rb
116
+ - lib/vx/common/amqp/consumer.rb
117
+ - lib/vx/common/amqp/consumer/ack.rb
118
+ - lib/vx/common/amqp/consumer/configuration.rb
119
+ - lib/vx/common/amqp/consumer/publish.rb
120
+ - lib/vx/common/amqp/consumer/subscribe.rb
121
+ - lib/vx/common/amqp/formatter.rb
122
+ - lib/vx/common/amqp/mixins/callbacks.rb
123
+ - lib/vx/common/amqp/mixins/logger.rb
124
+ - lib/vx/common/amqp/session.rb
125
+ - lib/vx/common/amqp/supervisor/threaded.rb
126
+ - lib/vx/common/amqp/testing.rb
127
+ - lib/vx/common/amqp/version.rb
128
+ - spec/integration/multi_threaded_spec.rb
129
+ - spec/integration/threaded_supervisor_spec.rb
130
+ - spec/lib/amqp/config_spec.rb
131
+ - spec/lib/amqp/consumer_spec.rb
132
+ - spec/lib/amqp/formatter_spec.rb
133
+ - spec/lib/amqp/mixins/callbacks_spec.rb
134
+ - spec/lib/amqp/session_spec.rb
135
+ - spec/lib/amqp/supervisor/threaded_spec.rb
136
+ - spec/lib/amqp_spec.rb
137
+ - spec/spec_helper.rb
138
+ - spec/support/amqp.rb
139
+ - spec/support/ignore_me_error.rb
140
+ - vx-common-amqp.gemspec
141
+ homepage: ''
142
+ licenses:
143
+ - MIT
144
+ metadata: {}
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: 1.9.3
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 2.1.11
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: Common amqp code
165
+ test_files:
166
+ - spec/integration/multi_threaded_spec.rb
167
+ - spec/integration/threaded_supervisor_spec.rb
168
+ - spec/lib/amqp/config_spec.rb
169
+ - spec/lib/amqp/consumer_spec.rb
170
+ - spec/lib/amqp/formatter_spec.rb
171
+ - spec/lib/amqp/mixins/callbacks_spec.rb
172
+ - spec/lib/amqp/session_spec.rb
173
+ - spec/lib/amqp/supervisor/threaded_spec.rb
174
+ - spec/lib/amqp_spec.rb
175
+ - spec/spec_helper.rb
176
+ - spec/support/amqp.rb
177
+ - spec/support/ignore_me_error.rb
178
+ has_rdoc: