evrone-common-amqp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +6 -0
- data/bin/amqp_consumers +12 -0
- data/evrone-common-amqp.gemspec +30 -0
- data/lib/evrone/common/amqp.rb +68 -0
- data/lib/evrone/common/amqp/cli.rb +88 -0
- data/lib/evrone/common/amqp/config.rb +74 -0
- data/lib/evrone/common/amqp/consumer.rb +70 -0
- data/lib/evrone/common/amqp/consumer/ack.rb +19 -0
- data/lib/evrone/common/amqp/consumer/configuration.rb +93 -0
- data/lib/evrone/common/amqp/consumer/publish.rb +32 -0
- data/lib/evrone/common/amqp/consumer/subscribe.rb +67 -0
- data/lib/evrone/common/amqp/formatter.rb +109 -0
- data/lib/evrone/common/amqp/mixins/logger.rb +17 -0
- data/lib/evrone/common/amqp/mixins/with_middleware.rb +16 -0
- data/lib/evrone/common/amqp/session.rb +154 -0
- data/lib/evrone/common/amqp/supervisor/threaded.rb +170 -0
- data/lib/evrone/common/amqp/testing.rb +46 -0
- data/lib/evrone/common/amqp/version.rb +7 -0
- data/spec/integration/multi_threaded_spec.rb +83 -0
- data/spec/integration/threaded_supervisor_spec.rb +85 -0
- data/spec/lib/amqp/consumer_spec.rb +281 -0
- data/spec/lib/amqp/formatter_spec.rb +47 -0
- data/spec/lib/amqp/mixins/with_middleware_spec.rb +32 -0
- data/spec/lib/amqp/session_spec.rb +144 -0
- data/spec/lib/amqp/supervisor/threaded_spec.rb +123 -0
- data/spec/lib/amqp_spec.rb +9 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/amqp.rb +15 -0
- data/spec/support/ignore_me_error.rb +1 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 81d6b307b28367c98533ef3000051ea2a1619e19
|
4
|
+
data.tar.gz: 745c5cb989ec2c7f8c12e3f00726375f876b2ab8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db6971498021c327ffb10fff8965c9d625a4713bda71450e8cd1f8f497147a1471a85ea5cf58466baaf07658725d474d45f44f2acd942c4dc2c7ff4889a29156
|
7
|
+
data.tar.gz: fb37745e6b620966a4e1de10e92ee644ac11b594affb6a061775a0e7c589a4ab9c472698f75cb27cdfd34e6b18cc833176d967c21edcc71682dd8d1accc0b656
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Dmitry Galinsky
|
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,29 @@
|
|
1
|
+
# Evrone::Common::Amqp
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'evrone-common-amqp'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install evrone-common-amqp
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/amqp_consumers
ADDED
@@ -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 'evrone/common/amqp/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "evrone-common-amqp"
|
8
|
+
spec.version = Evrone::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.pre3"
|
24
|
+
spec.add_runtime_dependency "evrone-common-rack-builder"
|
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
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path("../amqp/version", __FILE__)
|
2
|
+
|
3
|
+
module Evrone
|
4
|
+
module Common
|
5
|
+
module AMQP
|
6
|
+
|
7
|
+
autoload :Config, File.expand_path("../amqp/config", __FILE__)
|
8
|
+
autoload :Session, File.expand_path("../amqp/session", __FILE__)
|
9
|
+
autoload :Consumer, File.expand_path("../amqp/consumer", __FILE__)
|
10
|
+
autoload :CLI, File.expand_path("../amqp/cli", __FILE__)
|
11
|
+
autoload :Formatter, File.expand_path("../amqp/formatter", __FILE__)
|
12
|
+
|
13
|
+
module Supervisor
|
14
|
+
autoload :Threaded, File.expand_path("../amqp/supervisor/threaded", __FILE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
autoload :Logger, File.expand_path("../amqp/mixins/logger", __FILE__)
|
18
|
+
autoload :WithMiddleware, File.expand_path("../amqp/mixins/with_middleware", __FILE__)
|
19
|
+
|
20
|
+
extend self
|
21
|
+
|
22
|
+
@@config = Common::AMQP::Config.new
|
23
|
+
@@session = Common::AMQP::Session.new
|
24
|
+
|
25
|
+
def configure
|
26
|
+
yield config
|
27
|
+
end
|
28
|
+
|
29
|
+
def config
|
30
|
+
@@config
|
31
|
+
end
|
32
|
+
|
33
|
+
def session
|
34
|
+
@@session
|
35
|
+
end
|
36
|
+
|
37
|
+
def open
|
38
|
+
session.open
|
39
|
+
end
|
40
|
+
|
41
|
+
def open?
|
42
|
+
session.open?
|
43
|
+
end
|
44
|
+
|
45
|
+
def close
|
46
|
+
session.close
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger
|
50
|
+
config.logger
|
51
|
+
end
|
52
|
+
|
53
|
+
def logger=(val)
|
54
|
+
config.logger = val
|
55
|
+
end
|
56
|
+
|
57
|
+
def shutdown
|
58
|
+
Common::AMQP::Session.shutdown
|
59
|
+
Evrone::Common::AMQP::Supervisor::Threaded.shutdown
|
60
|
+
end
|
61
|
+
|
62
|
+
def shutdown?
|
63
|
+
Common::AMQP::Session.shutdown?
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
trap "INT" do
|
5
|
+
Evrone::Common::AMQP.shutdown
|
6
|
+
end
|
7
|
+
|
8
|
+
module Evrone
|
9
|
+
module Common
|
10
|
+
module AMQP
|
11
|
+
class CLI
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@options = parse_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
require_before_executing
|
19
|
+
load_consumers
|
20
|
+
|
21
|
+
consumers = find_consumers.inject({}) do |a,c|
|
22
|
+
a[c] = 2
|
23
|
+
a
|
24
|
+
end
|
25
|
+
|
26
|
+
supervisor = Common::AMQP::Supervisor::Threaded.new
|
27
|
+
consumers.each do |k,v|
|
28
|
+
v.times do |n|
|
29
|
+
supervisor.add k, :subscribe, n
|
30
|
+
end
|
31
|
+
end
|
32
|
+
supervisor.run
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def find_consumers
|
38
|
+
Evrone::Common::AMQP::Consumer.classes.inject([]) do |a,c|
|
39
|
+
c = Kernel.const_get(c)
|
40
|
+
a << c if c.method_defined? :perform
|
41
|
+
a
|
42
|
+
end.uniq
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_consumers
|
46
|
+
if l = @options[:load_from]
|
47
|
+
path = File.expand_path(l, Dir.pwd)
|
48
|
+
Dir["#{path}/**.rb"].each do |f|
|
49
|
+
load f
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def require_before_executing
|
55
|
+
if r = @options[:require]
|
56
|
+
require File.expand_path(r, Dir.pwd)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_options
|
61
|
+
options = {}
|
62
|
+
|
63
|
+
OptionParser.new do |opts|
|
64
|
+
opts.banner = "Usage: amqp_consumers [options]"
|
65
|
+
|
66
|
+
opts.on("-r", "--require FILE", String, 'Require file before executing') do |r|
|
67
|
+
options[:require] = r
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on("-l", "--load DIR", "Load consumers from directory") do |l|
|
71
|
+
options[:load_from] = l
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.on("-c", "--consumer CONSUMER[,NUM]", "a", "b") do |l|
|
75
|
+
name,num = l.split(",")
|
76
|
+
num ||= 1
|
77
|
+
options[:consumers] ||= []
|
78
|
+
options[:consumers] << [name, num.to_i]
|
79
|
+
end
|
80
|
+
end.parse!
|
81
|
+
|
82
|
+
options
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'evrone/common/rack/builder'
|
3
|
+
|
4
|
+
module Evrone
|
5
|
+
module Common
|
6
|
+
module AMQP
|
7
|
+
class Config
|
8
|
+
|
9
|
+
attr_accessor :url, :default_exchange_options, :default_queue_options,
|
10
|
+
:default_publish_options, :default_exchange_type, :logger, :pool_timeout,
|
11
|
+
:heartbeat, :spawn_attempts, :content_type
|
12
|
+
|
13
|
+
attr_reader :publishing_builder, :recieving_builder, :subscribing_builder
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
reset!
|
17
|
+
end
|
18
|
+
|
19
|
+
def formatter
|
20
|
+
Common::AMQP::Formatter
|
21
|
+
end
|
22
|
+
|
23
|
+
def publishing(&block)
|
24
|
+
@publishing_builder = Common::Rack::Builder.new(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def recieving(&block)
|
28
|
+
@recieving_builder = Common::Rack::Builder.new(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def subscribing(&block)
|
32
|
+
@subscribing_builder = Common::Rack::Builder.new(&block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_exchange_name
|
36
|
+
"amq.#{default_exchange_type}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset!
|
40
|
+
@url = nil
|
41
|
+
@logger = ::Logger.new(STDOUT)
|
42
|
+
@default_exchange_type = :topic
|
43
|
+
@pool_timeout = 0.1
|
44
|
+
@heartbeat = 10
|
45
|
+
|
46
|
+
@publishing_builder = nil
|
47
|
+
@recieving_builder = nil
|
48
|
+
@subscribing_builder = nil
|
49
|
+
|
50
|
+
@spawn_attempts = 5
|
51
|
+
|
52
|
+
@content_type = 'application/json'
|
53
|
+
|
54
|
+
@default_exchange_options = {
|
55
|
+
durable: true,
|
56
|
+
auto_delete: false
|
57
|
+
}
|
58
|
+
|
59
|
+
@default_queue_options = {
|
60
|
+
durable: true,
|
61
|
+
autodelete: false,
|
62
|
+
exclusive: false
|
63
|
+
}
|
64
|
+
|
65
|
+
@default_publish_options = {
|
66
|
+
durable: false
|
67
|
+
}
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Evrone
|
4
|
+
module Common
|
5
|
+
module AMQP
|
6
|
+
module Consumer
|
7
|
+
|
8
|
+
autoload :Configuration, File.expand_path("../consumer/configuration", __FILE__)
|
9
|
+
autoload :Publish, File.expand_path("../consumer/publish", __FILE__)
|
10
|
+
autoload :Subscribe, File.expand_path("../consumer/subscribe", __FILE__)
|
11
|
+
autoload :Sleep, File.expand_path("../consumer/sleep", __FILE__)
|
12
|
+
autoload :Ack, File.expand_path("../consumer/ack", __FILE__)
|
13
|
+
|
14
|
+
include Common::AMQP::Consumer::Ack
|
15
|
+
include Common::AMQP::Logger
|
16
|
+
|
17
|
+
attr_accessor :delivery_info
|
18
|
+
attr_accessor :properties
|
19
|
+
attr_accessor :channel
|
20
|
+
|
21
|
+
@@classes = []
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.extend ClassMethods
|
25
|
+
@@classes << base.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.classes
|
29
|
+
@@classes
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
|
34
|
+
include Common::AMQP::Consumer::Configuration
|
35
|
+
include Common::AMQP::Consumer::Publish
|
36
|
+
include Common::AMQP::Consumer::Subscribe
|
37
|
+
include Common::AMQP::Logger
|
38
|
+
include Common::AMQP::WithMiddleware
|
39
|
+
|
40
|
+
def shutdown?
|
41
|
+
Common::AMQP.shutdown?
|
42
|
+
end
|
43
|
+
|
44
|
+
def shutdown
|
45
|
+
Common::AMQP.shutdown
|
46
|
+
end
|
47
|
+
|
48
|
+
def session
|
49
|
+
Common::AMQP.session
|
50
|
+
end
|
51
|
+
|
52
|
+
def config
|
53
|
+
Common::AMQP.config
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def declare_exchange
|
59
|
+
session.declare_exchange(exchange_name, exchange_options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def declare_queue
|
63
|
+
session.declare_queue(queue_name, queue_options)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|