bigwig 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/LICENSE +11 -0
- data/Manifest +16 -0
- data/README.markdown +92 -0
- data/Rakefile +8 -0
- data/bigwig.gemspec +38 -0
- data/bigwig.yml +8 -0
- data/bigwig.yml.example +8 -0
- data/bin/bigwig +3 -0
- data/bin/bigwig-ping +3 -0
- data/lib/bigwig.rb +33 -0
- data/lib/bigwig/internal_plugins/ping_plugin.rb +11 -0
- data/lib/bigwig/job.rb +48 -0
- data/lib/bigwig/pinger.rb +60 -0
- data/lib/bigwig/plugin.rb +16 -0
- data/lib/bigwig/plugins.rb +59 -0
- data/lib/bigwig/runner.rb +119 -0
- metadata +107 -0
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Released under the MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Brightbox Systems Ltd
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
10
|
+
|
11
|
+
See http://www.brightbox.co.uk/ for contact details.
|
data/Manifest
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
LICENSE
|
3
|
+
Manifest
|
4
|
+
README.markdown
|
5
|
+
Rakefile
|
6
|
+
bigwig.yml
|
7
|
+
bigwig.yml.example
|
8
|
+
bin/bigwig
|
9
|
+
bin/bigwig-ping
|
10
|
+
lib/bigwig.rb
|
11
|
+
lib/bigwig/internal_plugins/ping_plugin.rb
|
12
|
+
lib/bigwig/job.rb
|
13
|
+
lib/bigwig/pinger.rb
|
14
|
+
lib/bigwig/plugin.rb
|
15
|
+
lib/bigwig/plugins.rb
|
16
|
+
lib/bigwig/runner.rb
|
data/README.markdown
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
Bigwig
|
2
|
+
======
|
3
|
+
|
4
|
+
Bigwig is a daemon process that listens to a RabbitMQ queue and processes messages that it receives.
|
5
|
+
|
6
|
+
Typical Usage
|
7
|
+
-------------
|
8
|
+
|
9
|
+
* Install the bigwig gem
|
10
|
+
* Start an AMQP server
|
11
|
+
* Create a folder of plugins
|
12
|
+
* Create a bigwig configuration file
|
13
|
+
* Start bigwig - `bigwig start -c config -l logs`
|
14
|
+
|
15
|
+
Configuration
|
16
|
+
-------------
|
17
|
+
|
18
|
+
Bigwig expects you to give it a configuration file detailing how it is to connect to the AMQP server and how it should respond to incoming messages.
|
19
|
+
|
20
|
+
When invoking bigwig, it looks for a file called bigwig.yml in the current folder. Alternatively you can specify the configuration file using the `-c` command line option (note that you must supply an absolute path to the file, relative paths will fail).
|
21
|
+
|
22
|
+
A typical configuration file looks like this:
|
23
|
+
|
24
|
+
user: rabbit-user
|
25
|
+
password: crunchycarrots
|
26
|
+
vhost: /
|
27
|
+
server: my.amqpserver.com
|
28
|
+
port: 5672
|
29
|
+
queue: myqueue
|
30
|
+
warren_logging: false
|
31
|
+
plugins_folder: /full/path/to/a/folder
|
32
|
+
|
33
|
+
The first six items tell bigwig how to connect to the AMQP server. The next item specifies whether you want warren (the lower-level AMQP processor) to log its output. Lastly, you tell bigwig where to find its plugins.
|
34
|
+
|
35
|
+
Logging
|
36
|
+
-------
|
37
|
+
|
38
|
+
When invoking bigwig you should pass it the full path to a folder in which to write its log and pid files. If not specified, it will use the current folder. This is done using the `-l` command line option.
|
39
|
+
|
40
|
+
Messages
|
41
|
+
--------
|
42
|
+
|
43
|
+
Bigwig expects messages to be a string which can be deserialised into a Ruby Hash. The Hash is split into two sections - the "header" and the "data".
|
44
|
+
|
45
|
+
A typical message will look something like this:
|
46
|
+
|
47
|
+
message = {
|
48
|
+
:id => '123',
|
49
|
+
:method => 'my_command',
|
50
|
+
:data => {
|
51
|
+
:field => 'value',
|
52
|
+
:another_field => 'another_value'
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
The most important of these is the `:method` key. Bigwig unpacks this and uses that to lookup which plugin it should invoke (see below).
|
57
|
+
|
58
|
+
Plugins
|
59
|
+
-------
|
60
|
+
|
61
|
+
When bigwig starts it looks through the plugins folder specified within the configuration file (and all its sub-directories). It then loads all plugins that it finds.
|
62
|
+
|
63
|
+
For example, a plugin, which we shall call LoggingPlugin, would look like this:
|
64
|
+
|
65
|
+
* it should live in a file called `logging_plugin.rb` that is somewhere within your plugins folder
|
66
|
+
* it should define a class called `LoggingPlugin` that descends from `BigWig::Plugin`
|
67
|
+
* it should define a class method called `method`
|
68
|
+
* it should define a class method called `call`
|
69
|
+
|
70
|
+
class LoggingPlugin < BigWig::Plugin
|
71
|
+
def self.method
|
72
|
+
"logging"
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.call(task_id, args)
|
76
|
+
BigWig.logger.info "LoggingPlugin was invoked with #{args.inspect} as parameters"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
When bigwig receives a message where the `:method` parameter == 'logging' it will then invoke `LoggingPlugin#call`, passing it the `:id` and `:data` from the original message as task_id and args respectively.
|
81
|
+
|
82
|
+
Pings
|
83
|
+
-----
|
84
|
+
|
85
|
+
There is a plugin built-in to bigwig called PingPlugin, that registers itself under the name "ping". If you place a message onto the queue with :method => 'ping', the PingPlugin responds by writing a message to the log file. This is useful for monitoring bigwig - another system places ping messages onto the queue at regular intervals and we watch to ensure that the log file's update time is changing.
|
86
|
+
|
87
|
+
License
|
88
|
+
-------
|
89
|
+
|
90
|
+
(c) 2009 Brightbox Systems Ltd. Released under the MIT License - see LICENSE for more details.
|
91
|
+
|
92
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
Echoe.new 'bigwig' do | gem |
|
3
|
+
gem.author = 'David Smalley, Caius Durling, Rahoul Baruah'
|
4
|
+
gem.summary = 'A daemon that listens to an AMQP queue and responds to messages by invoking commands from a set of plugins'
|
5
|
+
gem.url = 'http://www.brightbox.co.uk/'
|
6
|
+
gem.runtime_dependencies = ["brightbox-warren >=0.9.0", "daemons >=1.0.10"]
|
7
|
+
gem.install_message = 'Welcome to bigwig. Please set up a configuration file and a plugins folder before starting bigwig...'
|
8
|
+
end
|
data/bigwig.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{bigwig}
|
5
|
+
s.version = "0.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["David Smalley, Caius Durling, Rahoul Baruah"]
|
9
|
+
s.date = %q{2009-10-06}
|
10
|
+
s.description = %q{A daemon that listens to an AMQP queue and responds to messages by invoking commands from a set of plugins}
|
11
|
+
s.email = %q{}
|
12
|
+
s.executables = ["bigwig", "bigwig-ping"]
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.markdown", "bin/bigwig", "bin/bigwig-ping", "lib/bigwig.rb", "lib/bigwig/internal_plugins/ping_plugin.rb", "lib/bigwig/job.rb", "lib/bigwig/pinger.rb", "lib/bigwig/plugin.rb", "lib/bigwig/plugins.rb", "lib/bigwig/runner.rb"]
|
14
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.markdown", "Rakefile", "bigwig.yml", "bigwig.yml.example", "bin/bigwig", "bin/bigwig-ping", "lib/bigwig.rb", "lib/bigwig/internal_plugins/ping_plugin.rb", "lib/bigwig/job.rb", "lib/bigwig/pinger.rb", "lib/bigwig/plugin.rb", "lib/bigwig/plugins.rb", "lib/bigwig/runner.rb", "bigwig.gemspec"]
|
15
|
+
s.homepage = %q{http://www.brightbox.co.uk/}
|
16
|
+
s.post_install_message = %q{Welcome to bigwig. Please set up a configuration file and a plugins folder before starting bigwig...}
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bigwig", "--main", "README.markdown"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{bigwig}
|
20
|
+
s.rubygems_version = %q{1.3.5}
|
21
|
+
s.summary = %q{A daemon that listens to an AMQP queue and responds to messages by invoking commands from a set of plugins}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_runtime_dependency(%q<brightbox-warren>, [">= 0.9.0"])
|
29
|
+
s.add_runtime_dependency(%q<daemons>, [">= 1.0.10"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<brightbox-warren>, [">= 0.9.0"])
|
32
|
+
s.add_dependency(%q<daemons>, [">= 1.0.10"])
|
33
|
+
end
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<brightbox-warren>, [">= 0.9.0"])
|
36
|
+
s.add_dependency(%q<daemons>, [">= 1.0.10"])
|
37
|
+
end
|
38
|
+
end
|
data/bigwig.yml
ADDED
data/bigwig.yml.example
ADDED
data/bin/bigwig
ADDED
data/bin/bigwig-ping
ADDED
data/lib/bigwig.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
BIGWIG_ROOT = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
|
5
|
+
module BigWig
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
def self.logger
|
9
|
+
@logger ||= begin
|
10
|
+
l = Logger.new(STDERR)
|
11
|
+
l.level = Logger::DEBUG
|
12
|
+
l
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.logger=(l)
|
17
|
+
@logger = l
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.connect_using config
|
21
|
+
env = ENV['WARREN_ENV'] || 'development'
|
22
|
+
|
23
|
+
h = {:user => config["user"], :pass => config["password"], :vhost => config["vhost"], :default_queue => config["queue"], :host => config["server"], :logging => config["warren_logging"]}
|
24
|
+
|
25
|
+
params = { env => h }
|
26
|
+
|
27
|
+
Warren::Queue.logger = BigWig::logger
|
28
|
+
Warren::Queue.connection = params
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Dir["#{BIGWIG_ROOT}/lib/bigwig/*.rb"].each {|r| require r }
|
33
|
+
Dir["#{BIGWIG_ROOT}/lib/bigwig/internal_plugins/*.rb"].each {|r| require r }
|
data/lib/bigwig/job.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module BigWig
|
2
|
+
require 'benchmark'
|
3
|
+
# Dispatches jobs as they are received from the queue to the relevant plugin.
|
4
|
+
# Each message on the queue is expected to take a form similar to:
|
5
|
+
# {
|
6
|
+
# :method => 'my_method_name',
|
7
|
+
# :id => 'optional arbitrary task identifier',
|
8
|
+
# :data => { :hash => :of, :relevant => :data }
|
9
|
+
# }
|
10
|
+
# The dispatch message asks for the Plugin that knows how to deal with the given method name and invokes it with the relevant id and data
|
11
|
+
class Job
|
12
|
+
|
13
|
+
# Dispatch the given message to the correct plugin
|
14
|
+
def self.dispatch(msg)
|
15
|
+
new(msg).run
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(msg)
|
19
|
+
@method = msg[:method]
|
20
|
+
@task_id = msg[:id]
|
21
|
+
@data = msg[:data] || {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Invoke the plugin with the given data and task id
|
25
|
+
def run
|
26
|
+
jobid = @task_id || rand(0xfffffff).to_s(16).upcase
|
27
|
+
BigWig::logger.info("Received #{@method} (job #{jobid}) with #{@data.inspect}")
|
28
|
+
|
29
|
+
result = nil
|
30
|
+
benchmark = begin
|
31
|
+
Benchmark.measure do
|
32
|
+
result = plugin_for(@method).call(@task_id, @data)
|
33
|
+
end
|
34
|
+
rescue StandardError => e
|
35
|
+
BigWig::logger.error("Bigwig Job id #{jobid} failed with exception #{e}: #{e.message}")
|
36
|
+
raise e
|
37
|
+
end
|
38
|
+
|
39
|
+
BigWig::logger.info("Bigwig Job id #{jobid} completed in #{benchmark.real.round} seconds")
|
40
|
+
return result
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def plugin_for(method)
|
45
|
+
BigWig::Plugins.plugin_for(method)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'warren'
|
2
|
+
require 'warren/adapters/bunny_adapter'
|
3
|
+
require 'daemons'
|
4
|
+
require 'optparse'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'benchmark'
|
7
|
+
require 'timeout'
|
8
|
+
|
9
|
+
module BigWig
|
10
|
+
class Pinger
|
11
|
+
attr_reader :config
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
def initialize(command_line)
|
15
|
+
load_options_from command_line
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
BigWig::logger.info("Starting bigwig pinger...")
|
20
|
+
@config = YAML.load(File.open(@options.config))
|
21
|
+
BigWig::connect_using @config
|
22
|
+
|
23
|
+
begin
|
24
|
+
Timeout::timeout(@options.timeout) do
|
25
|
+
begin
|
26
|
+
Warren::Queue.publish :default, :method => 'ping'
|
27
|
+
rescue Exception => ex
|
28
|
+
BigWig::logger.error("...ping failed with #{ex}")
|
29
|
+
exit 2
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue Timeout::Error => te
|
33
|
+
BigWig::logger.error("...ping timed out: #{te}")
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
|
37
|
+
BigWig::logger.info("...bigwig pinger finished")
|
38
|
+
exit 0
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
def load_options_from command_line
|
43
|
+
@options = OpenStruct.new(:config => File.expand_path('./bigwig.yml'), :timeout => 5)
|
44
|
+
opts = OptionParser.new do |opts|
|
45
|
+
opts.banner = "Usage: #{File.basename($0)} [options]"
|
46
|
+
opts.on('-h', '--help', 'Show this message') do
|
47
|
+
puts opts
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
opts.on('-c', '--config=file', 'Path to the config file; if not supplied then bigwig looks for bigwig.yml in the current folder') do |conf|
|
51
|
+
@options.config = conf
|
52
|
+
end
|
53
|
+
opts.on('-t', '--timeout=value', 'Timeout value in seconds') do | conf |
|
54
|
+
@options.timeout = conf.to_i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@args = opts.parse!(command_line)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module BigWig
|
2
|
+
class Plugin
|
3
|
+
# Each plugin should override Plugin::method and return the name of the command that
|
4
|
+
def self.method
|
5
|
+
raise "Plugins must override Plugin::method"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.register
|
9
|
+
{ self.method => self }
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.call(task_id, args)
|
13
|
+
BigWig.logger.warn "NotImplemented: Called #{self} with #{args} for task #{task_id}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module BigWig
|
2
|
+
# loads all the plugins from the BigWig::Plugins.root folder
|
3
|
+
class Plugins
|
4
|
+
class << self
|
5
|
+
attr_accessor :root
|
6
|
+
|
7
|
+
# load all plugins in the BigWig::Plugins.root folder
|
8
|
+
def load_all
|
9
|
+
register_plugins
|
10
|
+
end
|
11
|
+
|
12
|
+
# find the plugin with the given name
|
13
|
+
def plugin_for(key)
|
14
|
+
PLUGINS[key] || BigWig::Plugin
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
PLUGINS = {} unless defined? PLUGINS
|
19
|
+
|
20
|
+
# list of all known plugin files
|
21
|
+
def all_plugins
|
22
|
+
Dir["#{Plugins.root}/**/*_plugin.rb"]
|
23
|
+
end
|
24
|
+
|
25
|
+
# go through each plugin and register it
|
26
|
+
def register_plugins
|
27
|
+
all_plugins.each do |plugin|
|
28
|
+
BigWig.logger.info "Registering plugin: #{plugin}"
|
29
|
+
require plugin
|
30
|
+
plugin_class = constantize(camelize(File.basename(plugin, ".rb")))
|
31
|
+
PLUGINS.merge!(plugin_class.register)
|
32
|
+
end
|
33
|
+
# and add the inbuilt Ping plugin
|
34
|
+
PLUGINS.merge!(PingPlugin.register)
|
35
|
+
PLUGINS.freeze
|
36
|
+
end
|
37
|
+
|
38
|
+
# Helper method stolen from Rails :)
|
39
|
+
def constantize(camel_cased_word)
|
40
|
+
names = camel_cased_word.split('::')
|
41
|
+
names.shift if names.empty? || names.first.empty?
|
42
|
+
constant = Object
|
43
|
+
names.each do |name|
|
44
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
45
|
+
end
|
46
|
+
constant
|
47
|
+
end
|
48
|
+
|
49
|
+
# Helper method stolen from Rails :)
|
50
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
51
|
+
if first_letter_in_uppercase
|
52
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
53
|
+
else
|
54
|
+
lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'warren'
|
2
|
+
require 'warren/adapters/bunny_adapter'
|
3
|
+
require 'daemons'
|
4
|
+
require 'optparse'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'benchmark'
|
7
|
+
|
8
|
+
module BigWig
|
9
|
+
class Runner
|
10
|
+
attr_reader :args
|
11
|
+
attr_reader :options
|
12
|
+
attr_reader :config
|
13
|
+
|
14
|
+
# start the bigwig process
|
15
|
+
# use a default config file of bigwig.yml in the current folder, unless one is provided on the command line
|
16
|
+
def initialize(command_line_options)
|
17
|
+
load_options_from command_line_options
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
Daemons.run_proc('bigwig', :dir => @options.log_folder, :dir_mode => :normal, :log_output => true, :ARGV => self.args) do |*args|
|
22
|
+
@config = YAML.load(File.open(@options.config))
|
23
|
+
load_plugins_from @config["plugins_folder"]
|
24
|
+
begin
|
25
|
+
BigWig::logger.info("Starting Bigwig job worker")
|
26
|
+
|
27
|
+
trap_signals
|
28
|
+
BigWig::connect_using config
|
29
|
+
|
30
|
+
last_successful_subscription = Time.now
|
31
|
+
last_connection_failed = false
|
32
|
+
loop do
|
33
|
+
message_received = false
|
34
|
+
break if $exit
|
35
|
+
|
36
|
+
begin
|
37
|
+
Warren::Queue.subscribe(:default) do |msg|
|
38
|
+
BigWig::Job.dispatch(msg)
|
39
|
+
message_received = true
|
40
|
+
end
|
41
|
+
|
42
|
+
last_successful_subscription = Time.now # record the time in case we have a failure next time round
|
43
|
+
if last_connection_failed
|
44
|
+
BigWig.logger.info('...reconnected successfully')
|
45
|
+
last_connection_failed = false
|
46
|
+
end
|
47
|
+
sleep(0.5) unless message_received # if the queue was empty, go to sleep before checking for the next message
|
48
|
+
|
49
|
+
rescue Exception => ex # if there was an error connecting to the queue, wait a bit and then retry TODO: Change this exception
|
50
|
+
BigWig::logger.error("Error when subscribing to the queue: #{ex}")
|
51
|
+
retry_time = calculate_retry_time_based_upon last_successful_subscription
|
52
|
+
sleep(retry_time)
|
53
|
+
last_connection_failed = true
|
54
|
+
end
|
55
|
+
|
56
|
+
break if $exit
|
57
|
+
end
|
58
|
+
|
59
|
+
BigWig::logger.info("Bigwig job worker stopped")
|
60
|
+
rescue => e
|
61
|
+
BigWig::logger.fatal("Exiting due to exception #{e}, #{e.message}")
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def load_options_from command_line_options
|
69
|
+
@options = OpenStruct.new(:config => File.expand_path('./bigwig.yml'), :log_folder => File.expand_path('.'))
|
70
|
+
opts = OptionParser.new do |opts|
|
71
|
+
opts.banner = "Usage: #{File.basename($0)} [options] start|stop|restart|run"
|
72
|
+
opts.on('-h', '--help', 'Show this message') do
|
73
|
+
puts opts
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
opts.on('-c', '--config=file', 'Path to the config file; if not supplied then bigwig looks for bigwig.yml in the current folder') do |conf|
|
77
|
+
@options.config = conf
|
78
|
+
end
|
79
|
+
opts.on('-l', '--log=folder', 'Path to a folder for the log file; if not supplied then bigwig will write its PID and log to the current folder') do |conf|
|
80
|
+
@options.log_folder = conf
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@args = opts.parse!(command_line_options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def load_plugins_from folder
|
87
|
+
BigWig::Plugins.root = folder
|
88
|
+
BigWig::Plugins.load_all
|
89
|
+
end
|
90
|
+
|
91
|
+
def trap_signals
|
92
|
+
trap('TERM') do
|
93
|
+
BigWig::logger.info('Bigwig exiting due to TERM signal')
|
94
|
+
$exit = true
|
95
|
+
end
|
96
|
+
trap('INT') do
|
97
|
+
BigWig::logger.info('Bigwig exiting due to INT signal')
|
98
|
+
$exit = true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def calculate_retry_time_based_upon last_connection_time
|
103
|
+
seconds_since_last_connection = (Time.now - last_connection_time).to_i
|
104
|
+
minutes = (seconds_since_last_connection.to_f / 60.0)
|
105
|
+
minutes_squared = minutes * minutes
|
106
|
+
|
107
|
+
# use a quadratic equation seconds_till_retry = a.x.x + b.x + c
|
108
|
+
# where x is the time in minutes since last connection
|
109
|
+
scale_down_factor = 0.5 # a in our equation
|
110
|
+
scale_movement_factor = 5 # b in our equation
|
111
|
+
constant_factor = 20.0 # c in our equation
|
112
|
+
|
113
|
+
seconds_till_retry = (minutes_squared * scale_down_factor) + (minutes * scale_movement_factor) + constant_factor
|
114
|
+
BigWig::logger.info("#{minutes.to_i} minutes since last successful connection: retrying in #{seconds_till_retry.to_i} seconds...")
|
115
|
+
|
116
|
+
return seconds_till_retry.to_i
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bigwig
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.2"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Smalley, Caius Durling, Rahoul Baruah
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-06 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: brightbox-warren
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: daemons
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.10
|
34
|
+
version:
|
35
|
+
description: A daemon that listens to an AMQP queue and responds to messages by invoking commands from a set of plugins
|
36
|
+
email: ""
|
37
|
+
executables:
|
38
|
+
- bigwig
|
39
|
+
- bigwig-ping
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- CHANGELOG
|
44
|
+
- LICENSE
|
45
|
+
- README.markdown
|
46
|
+
- bin/bigwig
|
47
|
+
- bin/bigwig-ping
|
48
|
+
- lib/bigwig.rb
|
49
|
+
- lib/bigwig/internal_plugins/ping_plugin.rb
|
50
|
+
- lib/bigwig/job.rb
|
51
|
+
- lib/bigwig/pinger.rb
|
52
|
+
- lib/bigwig/plugin.rb
|
53
|
+
- lib/bigwig/plugins.rb
|
54
|
+
- lib/bigwig/runner.rb
|
55
|
+
files:
|
56
|
+
- CHANGELOG
|
57
|
+
- LICENSE
|
58
|
+
- Manifest
|
59
|
+
- README.markdown
|
60
|
+
- Rakefile
|
61
|
+
- bigwig.yml
|
62
|
+
- bigwig.yml.example
|
63
|
+
- bin/bigwig
|
64
|
+
- bin/bigwig-ping
|
65
|
+
- lib/bigwig.rb
|
66
|
+
- lib/bigwig/internal_plugins/ping_plugin.rb
|
67
|
+
- lib/bigwig/job.rb
|
68
|
+
- lib/bigwig/pinger.rb
|
69
|
+
- lib/bigwig/plugin.rb
|
70
|
+
- lib/bigwig/plugins.rb
|
71
|
+
- lib/bigwig/runner.rb
|
72
|
+
- bigwig.gemspec
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: http://www.brightbox.co.uk/
|
75
|
+
licenses: []
|
76
|
+
|
77
|
+
post_install_message: Welcome to bigwig. Please set up a configuration file and a plugins folder before starting bigwig...
|
78
|
+
rdoc_options:
|
79
|
+
- --line-numbers
|
80
|
+
- --inline-source
|
81
|
+
- --title
|
82
|
+
- Bigwig
|
83
|
+
- --main
|
84
|
+
- README.markdown
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
92
|
+
version:
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: "1.2"
|
98
|
+
version:
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: bigwig
|
102
|
+
rubygems_version: 1.3.5
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: A daemon that listens to an AMQP queue and responds to messages by invoking commands from a set of plugins
|
106
|
+
test_files: []
|
107
|
+
|