cloudist 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +61 -0
- data/LICENSE.txt +20 -0
- data/README.md +113 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/examples/queue_message.rb +19 -0
- data/examples/sandwich_client.rb +17 -0
- data/examples/sandwich_worker.rb +21 -0
- data/lib/cloudist.rb +141 -0
- data/lib/cloudist/basic_queue.rb +91 -0
- data/lib/cloudist/core_ext/string.rb +11 -0
- data/lib/cloudist/errors.rb +6 -0
- data/lib/cloudist/job.rb +54 -0
- data/lib/cloudist/job_queue.rb +28 -0
- data/lib/cloudist/listener.rb +30 -0
- data/lib/cloudist/payload.rb +128 -0
- data/lib/cloudist/publisher.rb +17 -0
- data/lib/cloudist/reply_queue.rb +32 -0
- data/lib/cloudist/request.rb +51 -0
- data/lib/cloudist/utils.rb +36 -0
- data/lib/cloudist/worker.rb +24 -0
- data/spec/cloudist/basic_queue_spec.rb +33 -0
- data/spec/cloudist/job_spec.rb +23 -0
- data/spec/cloudist/payload_spec.rb +126 -0
- data/spec/cloudist/request_spec.rb +41 -0
- data/spec/cloudist_spec.rb +24 -0
- data/spec/core_ext/string_spec.rb +16 -0
- data/spec/spec_helper.rb +15 -0
- metadata +270 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "amqp"
|
4
|
+
gem "json"
|
5
|
+
gem "activesupport"
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "rspec", "~> 2.3.0"
|
11
|
+
gem "moqueue", :git => "git://github.com/customink/moqueue.git"
|
12
|
+
gem "mocha"
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "jeweler", "~> 1.5.2"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
gem "reek", "~> 1.2.8"
|
17
|
+
gem "roodi", "~> 2.1.0"
|
18
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/customink/moqueue.git
|
3
|
+
revision: 091a8f57e5c79b0b25e152b4d5230e4031797d62
|
4
|
+
specs:
|
5
|
+
moqueue (0.1.4)
|
6
|
+
amqp
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.0.3)
|
12
|
+
amqp (0.6.7)
|
13
|
+
eventmachine (>= 0.12.4)
|
14
|
+
diff-lcs (1.1.2)
|
15
|
+
eventmachine (0.12.10)
|
16
|
+
git (1.2.5)
|
17
|
+
jeweler (1.5.2)
|
18
|
+
bundler (~> 1.0.0)
|
19
|
+
git (>= 1.2.5)
|
20
|
+
rake
|
21
|
+
json (1.4.6)
|
22
|
+
mocha (0.9.10)
|
23
|
+
rake
|
24
|
+
rake (0.8.7)
|
25
|
+
rcov (0.9.9)
|
26
|
+
reek (1.2.8)
|
27
|
+
ruby2ruby (~> 1.2)
|
28
|
+
ruby_parser (~> 2.0)
|
29
|
+
sexp_processor (~> 3.0)
|
30
|
+
roodi (2.1.0)
|
31
|
+
ruby_parser
|
32
|
+
rspec (2.3.0)
|
33
|
+
rspec-core (~> 2.3.0)
|
34
|
+
rspec-expectations (~> 2.3.0)
|
35
|
+
rspec-mocks (~> 2.3.0)
|
36
|
+
rspec-core (2.3.1)
|
37
|
+
rspec-expectations (2.3.0)
|
38
|
+
diff-lcs (~> 1.1.2)
|
39
|
+
rspec-mocks (2.3.0)
|
40
|
+
ruby2ruby (1.2.5)
|
41
|
+
ruby_parser (~> 2.0)
|
42
|
+
sexp_processor (~> 3.0)
|
43
|
+
ruby_parser (2.0.5)
|
44
|
+
sexp_processor (~> 3.0)
|
45
|
+
sexp_processor (3.0.5)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
activesupport
|
52
|
+
amqp
|
53
|
+
bundler (~> 1.0.0)
|
54
|
+
jeweler (~> 1.5.2)
|
55
|
+
json
|
56
|
+
mocha
|
57
|
+
moqueue!
|
58
|
+
rcov
|
59
|
+
reek (~> 1.2.8)
|
60
|
+
roodi (~> 2.1.0)
|
61
|
+
rspec (~> 2.3.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ivan Vanderbyl
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
Cloudist
|
2
|
+
========
|
3
|
+
|
4
|
+
Cloudist is a super fast job queue for high demand and scalable tasks. It uses AMQP (RabbitMQ mainly) for message store are
|
5
|
+
distribution, while providing a simple DSL for handling jobs and responses.
|
6
|
+
|
7
|
+
Cloudist can be used within Rails or just about any Ruby app to distribute long running tasks, such as encoding a video, generating PDFs, scraping site data
|
8
|
+
or even just sending emails. Unlike other job queues (DelayedJob etc) Cloudist does not load your entire Rails stack into memory for every worker, and it is not designed to, instead it
|
9
|
+
expects all the data your worker requires to be sent in the initial job request. This means your workers stay slim and can scale very quickly and even run on EC2 micros outside your applications
|
10
|
+
network without any further configuration.
|
11
|
+
|
12
|
+
Another way Cloudist differs from other AMQP based job queues like Minion is it allows workers to report events, logs, system stats and replies back to the application which distributed the
|
13
|
+
job, and unlike database based job queues, there is almost no delay between messages, except network latency of course.
|
14
|
+
|
15
|
+
Installation
|
16
|
+
------------
|
17
|
+
|
18
|
+
gem install cloudist
|
19
|
+
|
20
|
+
Or if your app has a Gemfile:
|
21
|
+
|
22
|
+
gem 'cloudist'
|
23
|
+
|
24
|
+
Usage
|
25
|
+
-----
|
26
|
+
|
27
|
+
Cloudist requires an EventMachine reactor loop and an AMQP connection, so if your application is already using one, or your web server supplies one (for example Thin) these examples will work
|
28
|
+
out of the box. Otherwise simply wrap everything inside this block:
|
29
|
+
|
30
|
+
Cloudist.settings = {:user => 'guest'} # Standard AMQP settings
|
31
|
+
Cloudist.start {
|
32
|
+
# usual stuff here
|
33
|
+
worker {
|
34
|
+
# define a worker
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
This will start and AMQP connection and EM loop then yield everything inside it.
|
39
|
+
|
40
|
+
In your worker:
|
41
|
+
|
42
|
+
Cloudist.worker {
|
43
|
+
job('make.sandwich') {
|
44
|
+
# Make sandwich here
|
45
|
+
|
46
|
+
# Your worker has access to the data sent from the server in the 'data' attribute
|
47
|
+
data # => {:bread => "white", :sauce => 'bbq'}
|
48
|
+
|
49
|
+
# Fire the finished event
|
50
|
+
finished!
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
In your application:
|
55
|
+
|
56
|
+
job = Cloudist.enqueue('make.sandwich', :bread => "white", :sauce => 'bbq')
|
57
|
+
|
58
|
+
Cloudist.listen(job) {
|
59
|
+
event('finished') {
|
60
|
+
# Called when we finish making a sandwich
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
You don't need to listen to responses immediately, if you store the job_id you can listen to responses at any time in the near future.
|
65
|
+
|
66
|
+
You can also queue jobs outside an EventMachine loop using Cloudist.enqueue but this will be very slow as it has to connect to your message queue first.
|
67
|
+
|
68
|
+
Acknowledgements
|
69
|
+
-------
|
70
|
+
|
71
|
+
Portions of this gem are based on code from the following projects:
|
72
|
+
|
73
|
+
- Heroku's Droid gem
|
74
|
+
- Lizzy
|
75
|
+
- Minion
|
76
|
+
- Nanite
|
77
|
+
- Smith
|
78
|
+
|
79
|
+
Contributing to Cloudist
|
80
|
+
------------------------
|
81
|
+
|
82
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
83
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
84
|
+
* Fork the project
|
85
|
+
* Start a feature/bugfix branch e.g. git checkout -b feature-my-awesome-idea or bugfix-this-does-not-work
|
86
|
+
* Commit and push until you are happy with your contribution
|
87
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
88
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
89
|
+
|
90
|
+
Copyright
|
91
|
+
---------
|
92
|
+
|
93
|
+
Copyright (c) 2011 Ivan Vanderbyl.
|
94
|
+
|
95
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
96
|
+
a copy of this software and associated documentation files (the
|
97
|
+
"Software"), to deal in the Software without restriction, including
|
98
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
99
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
100
|
+
permit persons to whom the Software is furnished to do so, subject to
|
101
|
+
the following conditions:
|
102
|
+
|
103
|
+
The above copyright notice and this permission notice shall be
|
104
|
+
included in all copies or substantial portions of the Software.
|
105
|
+
|
106
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
107
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
108
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
109
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
110
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
111
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
112
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
113
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "cloudist"
|
16
|
+
gem.homepage = "http://github.com/ivanvanderbyl/cloudist"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Super fast job queue using AMQP}
|
19
|
+
gem.description = %Q{Cloudist is a simple, highly scalable job queue for Ruby applications, it can run within Rails, or on EC2, and does not load your entire Rails stack like delayed job does.}
|
20
|
+
gem.email = "ivanvanderbyl@me.com"
|
21
|
+
gem.authors = ["Ivan Vanderbyl"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'reek/rake/task'
|
41
|
+
Reek::Rake::Task.new do |t|
|
42
|
+
t.fail_on_error = true
|
43
|
+
t.verbose = false
|
44
|
+
t.source_files = 'lib/**/*.rb'
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'roodi'
|
48
|
+
require 'roodi_task'
|
49
|
+
RoodiTask.new do |t|
|
50
|
+
t.verbose = false
|
51
|
+
end
|
52
|
+
|
53
|
+
task :default => :spec
|
54
|
+
|
55
|
+
require 'rake/rdoctask'
|
56
|
+
Rake::RDocTask.new do |rdoc|
|
57
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
58
|
+
|
59
|
+
rdoc.rdoc_dir = 'rdoc'
|
60
|
+
rdoc.title = "cloudist #{version}"
|
61
|
+
rdoc.rdoc_files.include('README*')
|
62
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
63
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require "rubygems"
|
3
|
+
require "cloudist"
|
4
|
+
|
5
|
+
ENV["AMQP_URL"] = 'amqp://test_pilot:t35t_p1l0t!@ec2-50-16-134-211.compute-1.amazonaws.com:5672/'
|
6
|
+
|
7
|
+
::Signal.trap('INT') { Cloudist.stop }
|
8
|
+
::Signal.trap('TERM'){ Cloudist.stop }
|
9
|
+
|
10
|
+
Cloudist.start {
|
11
|
+
|
12
|
+
payload = Cloudist::Payload.new({:event => "started"})
|
13
|
+
|
14
|
+
q = Cloudist::ReplyQueue.new('temp.reply.make.sandwich')
|
15
|
+
q.setup
|
16
|
+
q.publish_to_q(payload)
|
17
|
+
|
18
|
+
stop
|
19
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require "rubygems"
|
3
|
+
require "cloudist"
|
4
|
+
|
5
|
+
Cloudist.signal_trap!
|
6
|
+
|
7
|
+
Cloudist.start {
|
8
|
+
|
9
|
+
log.info("Dispatching sandwich making job...")
|
10
|
+
enqueue('make.sandwich', {:bread => 'white'})
|
11
|
+
|
12
|
+
# Listen to all sandwich jobs
|
13
|
+
listen('make.sandwich') {
|
14
|
+
Cloudist.log.info("Make sandwich event: #{id}")
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require "rubygems"
|
3
|
+
require "cloudist"
|
4
|
+
|
5
|
+
Cloudist.signal_trap!
|
6
|
+
|
7
|
+
Cloudist.start {
|
8
|
+
log.info("Started Worker")
|
9
|
+
|
10
|
+
worker {
|
11
|
+
job('make.sandwich') {
|
12
|
+
# Fire the started event
|
13
|
+
started!
|
14
|
+
|
15
|
+
log.info("JOB (#{id}) Make sandwich with #{data[:bread]} bread")
|
16
|
+
log.debug(data.inspect)
|
17
|
+
|
18
|
+
finished!
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
data/lib/cloudist.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'json'
|
3
|
+
require "active_support/hash_with_indifferent_access"
|
4
|
+
require "amqp"
|
5
|
+
require "mq"
|
6
|
+
require "logger"
|
7
|
+
require "digest/md5"
|
8
|
+
|
9
|
+
$:.unshift File.dirname(__FILE__)
|
10
|
+
require "cloudist/core_ext/string"
|
11
|
+
require "cloudist/errors"
|
12
|
+
require "cloudist/utils"
|
13
|
+
require "cloudist/basic_queue"
|
14
|
+
require "cloudist/job_queue"
|
15
|
+
require "cloudist/reply_queue"
|
16
|
+
require "cloudist/publisher"
|
17
|
+
require "cloudist/payload"
|
18
|
+
require "cloudist/request"
|
19
|
+
require "cloudist/worker"
|
20
|
+
require "cloudist/listener"
|
21
|
+
require "cloudist/job"
|
22
|
+
|
23
|
+
module Cloudist
|
24
|
+
class << self
|
25
|
+
# Start the Cloudist loop
|
26
|
+
#
|
27
|
+
# Cloudist.start {
|
28
|
+
# # Do stuff in here
|
29
|
+
# }
|
30
|
+
#
|
31
|
+
# == Options
|
32
|
+
# * :user => 'name'
|
33
|
+
# * :pass => 'secret'
|
34
|
+
# * :host => 'localhost'
|
35
|
+
# * :port => 5672
|
36
|
+
# * :vhost => /
|
37
|
+
#
|
38
|
+
# Refer to default config below for how to set these as defaults
|
39
|
+
#
|
40
|
+
def start(options = {}, &block)
|
41
|
+
config = settings.update(options)
|
42
|
+
AMQP.start(config) do
|
43
|
+
self.instance_eval(&block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Define a worker. Must be called inside start loop
|
48
|
+
#
|
49
|
+
# worker {
|
50
|
+
# job('make.sandwich') {}
|
51
|
+
# }
|
52
|
+
#
|
53
|
+
# Refer to examples.
|
54
|
+
def worker(options = {}, &block)
|
55
|
+
_worker = Cloudist::Worker.new(options)
|
56
|
+
_worker.instance_eval(&block)
|
57
|
+
return _worker
|
58
|
+
end
|
59
|
+
|
60
|
+
# Accepts either a queue name or a job instance returned from enqueue.
|
61
|
+
# This method operates in two modes, when given a queue name, it
|
62
|
+
# will return all responses regardless of job id so you can use the job
|
63
|
+
# id to lookup a database record to update etc.
|
64
|
+
# When given a job instance it will only return messages from that job.
|
65
|
+
def listen(job_or_queue_name, &block)
|
66
|
+
_listener = Cloudist::Listener.new(job_or_queue_name)
|
67
|
+
_listener.subscribe(&block)
|
68
|
+
return _listener
|
69
|
+
end
|
70
|
+
|
71
|
+
# Enqueues a job.
|
72
|
+
# Takes a queue name and data hash to be sent to the worker.
|
73
|
+
# Returns Job instance
|
74
|
+
# Use Job#id to reference job later on.
|
75
|
+
def enqueue(job_queue_name, data = nil)
|
76
|
+
raise EnqueueError, "Incorrect arguments, you must include data when enquing job" if data.nil?
|
77
|
+
# TODO: Detect if inside loop, if not use bunny sync
|
78
|
+
Cloudist::Publisher.enqueue(job_queue_name, data)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Call this at anytime inside the loop to exit the app.
|
82
|
+
def stop_safely
|
83
|
+
::EM.add_timer(0.2) {
|
84
|
+
::AMQP.stop {
|
85
|
+
::EM.stop
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
alias :stop :stop_safely
|
91
|
+
|
92
|
+
def closing?
|
93
|
+
::AMQP.closing?
|
94
|
+
end
|
95
|
+
|
96
|
+
def log
|
97
|
+
@@log ||= Logger.new($stdout)
|
98
|
+
end
|
99
|
+
|
100
|
+
def log=(log)
|
101
|
+
@@log = log
|
102
|
+
end
|
103
|
+
|
104
|
+
def handle_error(e)
|
105
|
+
log.error "#{e.class}: #{e.message}"#, :exception => e
|
106
|
+
log.error e.backtrace.join("\n")
|
107
|
+
end
|
108
|
+
|
109
|
+
def version
|
110
|
+
@@version ||= File.read(File.dirname(__FILE__) + '/../VERSION').strip
|
111
|
+
end
|
112
|
+
|
113
|
+
def default_settings
|
114
|
+
uri = URI.parse(ENV["AMQP_URL"] || 'amqp://guest:guest@localhost:5672/')
|
115
|
+
{
|
116
|
+
:vhost => uri.path,
|
117
|
+
:host => uri.host,
|
118
|
+
:user => uri.user,
|
119
|
+
:port => uri.port || 5672,
|
120
|
+
:pass => uri.password
|
121
|
+
}
|
122
|
+
rescue Object => e
|
123
|
+
raise "invalid AMQP_URL: (#{uri.inspect}) #{e.class} -> #{e.message}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def settings
|
127
|
+
@@settings ||= default_settings
|
128
|
+
end
|
129
|
+
|
130
|
+
def settings=(settings_hash)
|
131
|
+
@@settings = default_settings.update(settings_hash)
|
132
|
+
end
|
133
|
+
|
134
|
+
def signal_trap!
|
135
|
+
::Signal.trap('INT') { Cloudist.stop }
|
136
|
+
::Signal.trap('TERM'){ Cloudist.stop }
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|