bender 0.0.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.
- checksums.yaml +7 -0
- data/.env_sample +4 -0
- data/.gitignore +35 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +22 -0
- data/README.md +43 -0
- data/Rakefile +2 -0
- data/bender.gemspec +33 -0
- data/bin/bender +7 -0
- data/lib/bender/cli.rb +69 -0
- data/lib/bender/client.rb +85 -0
- data/lib/bender/version.rb +3 -0
- data/lib/bender/watcher.rb +67 -0
- data/lib/bender/watchers/god_unmonitor.rb +28 -0
- data/lib/bender/watchers/watcher_life_cycle_hook.rb +7 -0
- data/lib/bender.rb +1 -0
- data/spec/bender_spec.rb +43 -0
- data/spec/spec_helper.rb +7 -0
- data/watchers.yml +11 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7edca865195b4a76c8dd36e2667ca4e5da3525ec
|
4
|
+
data.tar.gz: 0c7a58986b30d1fd58f8e7d160f9b7306d9063c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ed1ea2f3f5f85090aaabc7bead95b69e8191f01dbb5f859a3da65067924b88ff4dbde922c72f51b89a8979a15cfce3cde8aa4fac7bb122280dc9697913aa55e
|
7
|
+
data.tar.gz: 2d0c454f83496d3c85951780691577e044e5bc13a97e16d8864d0728961735e0cfcf132eea9bc38718c69705bdd831c3ed2de938bfae2cf0a2d1691306e53abc
|
data/.env_sample
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
29
|
+
# Gemfile.lock
|
30
|
+
.ruby-version
|
31
|
+
.ruby-gemset
|
32
|
+
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
34
|
+
.rvmrc
|
35
|
+
.env
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bender (0.0.1)
|
5
|
+
activesupport (~> 4.2)
|
6
|
+
aws-sdk-v1 (~> 1.61)
|
7
|
+
dotenv (~> 1.0)
|
8
|
+
thor (~> 0.19)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activesupport (4.2.0)
|
14
|
+
i18n (~> 0.7)
|
15
|
+
json (~> 1.7, >= 1.7.7)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
aws-sdk-v1 (1.61.0)
|
20
|
+
json (~> 1.4)
|
21
|
+
nokogiri (>= 1.4.4)
|
22
|
+
byebug (3.5.1)
|
23
|
+
columnize (~> 0.8)
|
24
|
+
debugger-linecache (~> 1.2)
|
25
|
+
slop (~> 3.6)
|
26
|
+
coderay (1.1.0)
|
27
|
+
columnize (0.9.0)
|
28
|
+
debugger-linecache (1.2.0)
|
29
|
+
diff-lcs (1.1.3)
|
30
|
+
dotenv (1.0.2)
|
31
|
+
i18n (0.7.0)
|
32
|
+
json (1.8.2)
|
33
|
+
method_source (0.8.2)
|
34
|
+
mini_portile (0.6.2)
|
35
|
+
minitest (5.5.1)
|
36
|
+
nokogiri (1.6.6.2)
|
37
|
+
mini_portile (~> 0.6.0)
|
38
|
+
pry (0.10.1)
|
39
|
+
coderay (~> 1.1.0)
|
40
|
+
method_source (~> 0.8.1)
|
41
|
+
slop (~> 3.4)
|
42
|
+
pry-byebug (2.0.0)
|
43
|
+
byebug (~> 3.4)
|
44
|
+
pry (~> 0.10)
|
45
|
+
rake (10.1.0)
|
46
|
+
rspec (2.12.0)
|
47
|
+
rspec-core (~> 2.12.0)
|
48
|
+
rspec-expectations (~> 2.12.0)
|
49
|
+
rspec-mocks (~> 2.12.0)
|
50
|
+
rspec-core (2.12.2)
|
51
|
+
rspec-expectations (2.12.1)
|
52
|
+
diff-lcs (~> 1.1.3)
|
53
|
+
rspec-mocks (2.12.2)
|
54
|
+
slop (3.6.0)
|
55
|
+
thor (0.19.1)
|
56
|
+
thread_safe (0.3.4)
|
57
|
+
tzinfo (1.2.2)
|
58
|
+
thread_safe (~> 0.1)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
ruby
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
bender!
|
65
|
+
bundler (~> 1.7)
|
66
|
+
pry (~> 0.10)
|
67
|
+
pry-byebug (~> 2.0)
|
68
|
+
rake (~> 10.0)
|
69
|
+
rspec (~> 2.12)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Anthony Leak
|
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,43 @@
|
|
1
|
+
# bender
|
2
|
+
|
3
|
+
Reason for _bender_:
|
4
|
+
|
5
|
+
We run [Resque](https://github.com/resque/resque) workers hosted on AWS using auto scaling groups. In order to ensure workers are always running we use the super awesome [God](www.godrb.com) gem.
|
6
|
+
|
7
|
+
Our issue is when scaling-in we need to inform the resque workers to gracefully shutdown .i.e:
|
8
|
+
|
9
|
+
* Finish the current job
|
10
|
+
* Stop polling for new jobs
|
11
|
+
* Terminate the process
|
12
|
+
|
13
|
+
While we do make use of Resque's remote shutdown - God does what God does best and restarts the process. One solution would be to implement remote pause in Resque - we required additional management of our remote nodes during termination.
|
14
|
+
|
15
|
+
More to follow.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'bender'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install bender
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
TODO: Write usage instructions here
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
1. Fork it ( https://github.com/aleak/bender/fork )
|
40
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
41
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
42
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
43
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bender.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bender/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bender"
|
8
|
+
spec.version = Bender::VERSION
|
9
|
+
spec.authors = ["Anthony Leak"]
|
10
|
+
spec.email = ["anthony.leak@gmail.com"]
|
11
|
+
spec.summary = %q{Bender - Just a super guy.}
|
12
|
+
spec.description = %q{We all love Bender.}
|
13
|
+
spec.homepage = "https://www.github.com/aleak/bender"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "pry", '~> 0.10'
|
25
|
+
spec.add_development_dependency "pry-byebug", '~> 2.0'
|
26
|
+
spec.add_development_dependency "rspec", '~> 2.12'
|
27
|
+
|
28
|
+
spec.add_runtime_dependency 'aws-sdk-v1', '~> 1.61'
|
29
|
+
spec.add_runtime_dependency 'activesupport', '~> 4.2'
|
30
|
+
spec.add_runtime_dependency 'dotenv', '~> 1.0'
|
31
|
+
spec.add_runtime_dependency 'thor', '~> 0.19'
|
32
|
+
|
33
|
+
end
|
data/bin/bender
ADDED
data/lib/bender/cli.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'thor'
|
3
|
+
require 'active_support/core_ext/hash'
|
4
|
+
require 'bender/client'
|
5
|
+
|
6
|
+
module Bender
|
7
|
+
class CLI < Thor
|
8
|
+
class_option :config, :aliases => ["-c"], :type => :string, :required => true
|
9
|
+
|
10
|
+
def initialize(args = [], opts = {}, config = {})
|
11
|
+
super(args, opts, config)
|
12
|
+
|
13
|
+
if !File.exists?(options[:config])
|
14
|
+
puts "Cannot find #{options[:config]}."
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
config_options = YAML.load_file(options[:config]).deep_symbolize_keys
|
19
|
+
@options = @options.symbolize_keys.merge(config_options)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "start", "Start processing watchers."
|
23
|
+
option :require, :aliases => ["-r"], :type => :string
|
24
|
+
option :pid_file, :aliases => ["-p"], :type => :string
|
25
|
+
option :interval, :aliases => ["-i"], :type => :numeric
|
26
|
+
option :daemon, :aliases => ["-d"], :type => :boolean
|
27
|
+
option :timeout, :aliases => ["-t"], :type => :numeric
|
28
|
+
option :graceful_term, :aliases => ["-g"], :type => :boolean
|
29
|
+
|
30
|
+
def start
|
31
|
+
load_enviroment(options[:require])
|
32
|
+
opts = @options.symbolize_keys.slice(:timeout, :interval, :daemon, :pid_file)
|
33
|
+
Bender::Client.new(@options).start_watchers
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "publish", "Publish a message."
|
37
|
+
option :watcher, :aliases => ["-w"], :type => :string, :required => true
|
38
|
+
option :message, :aliases => ["-m"], :type => :string, :required => true
|
39
|
+
|
40
|
+
def publish
|
41
|
+
load_enviroment(options[:require])
|
42
|
+
opts = @options.symbolize_keys.slice(:timeout, :interval, :daemon, :pid_file)
|
43
|
+
Bender::Client.new(@options).publish options[:watcher], options[:message]
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
# Loads the environment from the given configuration file.
|
48
|
+
# @api private
|
49
|
+
def load_enviroment(file = nil)
|
50
|
+
file ||= "."
|
51
|
+
|
52
|
+
if File.directory?(file) && File.exists?(File.expand_path("#{file}/config/environment.rb"))
|
53
|
+
require 'rails'
|
54
|
+
require File.expand_path("#{file}/config/environment.rb")
|
55
|
+
if defined?(::Rails) && ::Rails.respond_to?(:application)
|
56
|
+
# Rails 3
|
57
|
+
::Rails.application.eager_load!
|
58
|
+
elsif defined?(::Rails::Initializer)
|
59
|
+
# Rails 2.3
|
60
|
+
$rails_rake_task = false
|
61
|
+
::Rails::Initializer.run :load_application_classes
|
62
|
+
end
|
63
|
+
elsif File.file?(file)
|
64
|
+
require File.expand_path(file)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'aws-sdk-v1'
|
2
|
+
require 'thwait'
|
3
|
+
require 'dotenv'
|
4
|
+
require 'active_support/inflector'
|
5
|
+
require 'bender/watcher'
|
6
|
+
|
7
|
+
Dotenv.load
|
8
|
+
|
9
|
+
module Bender
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
@@logger ||= Logger.new(STDOUT)
|
13
|
+
end
|
14
|
+
|
15
|
+
class Client
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def keep_running?
|
19
|
+
@@keep_running
|
20
|
+
end
|
21
|
+
|
22
|
+
def queue_prefix
|
23
|
+
@@queue_prefix ||= "#{ENV['QUEUE_PREFIX']}-#{Socket.gethostname}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(config)
|
28
|
+
@config = config
|
29
|
+
initialize_watchers
|
30
|
+
end
|
31
|
+
|
32
|
+
def trap_signals
|
33
|
+
%w{INT TERM}.each do |signal|
|
34
|
+
Signal.trap(signal) {
|
35
|
+
stop_watchers
|
36
|
+
exit
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def start_watchers
|
42
|
+
Bender.logger.info("Starting Watchers - Press Ctrl+C to stop watchers...")
|
43
|
+
@@keep_running = true
|
44
|
+
@threads = []
|
45
|
+
@watchers.each do |watcher|
|
46
|
+
@threads << Thread.new do
|
47
|
+
watcher.start
|
48
|
+
end
|
49
|
+
end
|
50
|
+
trap_signals
|
51
|
+
ThreadsWait.all_waits(*@threads)
|
52
|
+
end
|
53
|
+
|
54
|
+
def stop_watchers
|
55
|
+
puts "Stopping watchers..."
|
56
|
+
@@keep_running = false
|
57
|
+
ThreadsWait.all_waits(*@threads)
|
58
|
+
end
|
59
|
+
|
60
|
+
def publish(watcher, message)
|
61
|
+
sent = @watchers.select{|w| w.class.to_s.underscore == watcher}.collect do |watcher|
|
62
|
+
watcher.publish(message)
|
63
|
+
end
|
64
|
+
Bender.logger.info("Sent #{sent.size} message(s)")
|
65
|
+
end
|
66
|
+
|
67
|
+
def config
|
68
|
+
@config
|
69
|
+
end
|
70
|
+
|
71
|
+
def watchers
|
72
|
+
@watchers
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def initialize_watchers
|
78
|
+
@watchers = @config[:watchers].collect do |watcher_config|
|
79
|
+
Bender.logger.info("Loading #{watcher_config[:name]}")
|
80
|
+
WatcherFactory.create(watcher_config, self.config)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module WatcherFactory
|
2
|
+
def self.create(config, default_config)
|
3
|
+
watcher_class = config[:name]
|
4
|
+
require "bender/watchers/#{watcher_class}"
|
5
|
+
watcher_class.classify.constantize.new(default_config)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Watcher
|
10
|
+
def self.sqs
|
11
|
+
@@sqs ||= AWS::SQS.new({
|
12
|
+
:access_key_id => ENV['AWS_ACCESS_KEY'],
|
13
|
+
:secret_access_key => ENV['AWS_SECRET_ACCESS'],
|
14
|
+
:region => ENV['AWS_REGION']
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(options)
|
19
|
+
@options = options
|
20
|
+
load_queue
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
subscribe
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_queue
|
28
|
+
@queue ||= Watcher.sqs.queues.create(
|
29
|
+
"#{Bender::Client.queue_prefix}-#{@options[:name]}",
|
30
|
+
@options[:create_options]
|
31
|
+
)
|
32
|
+
rescue Exception => ex
|
33
|
+
Bender.logger.error("#{self.class}: #{ex.message}#{ex.backtrace.join("\n")}")
|
34
|
+
end
|
35
|
+
|
36
|
+
def subscribe
|
37
|
+
while Bender::Client.keep_running? do
|
38
|
+
Bender.logger.info("Polling #{@queue.arn} for #{self.class.to_s}")
|
39
|
+
@queue.poll(@options[:poll_options]) do |received_message|
|
40
|
+
safe_perform(received_message.body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
rescue Exception => ex
|
44
|
+
Bender.logger.error("#{self.class}: #{ex.message}#{ex.backtrace.join("\n")}")
|
45
|
+
end
|
46
|
+
|
47
|
+
def publish(message)
|
48
|
+
message = message.to_json if message.is_a? Hash
|
49
|
+
@queue.send_message(message)
|
50
|
+
rescue Exception => ex
|
51
|
+
Bender.logger.error("#{self.class}: #{ex.message}#{ex.backtrace.join("\n")}")
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def safe_perform(json)
|
57
|
+
message = JSON.parse(json, :symbolize_names => true) rescue :invalid
|
58
|
+
if message == :invalid
|
59
|
+
Bender.logger.error("#{self.class}: Unable to parse message: #{json}")
|
60
|
+
else
|
61
|
+
self.perform(message)
|
62
|
+
end
|
63
|
+
rescue Exception => ex
|
64
|
+
Bender.logger.error("#{self.class}: Perform : #{ex.message}#{ex.backtrace.join("\n")}")
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
class GodUnmonitor < Watcher
|
4
|
+
|
5
|
+
# Expects a message in the following format
|
6
|
+
# :task_or_group_name => 'resque'
|
7
|
+
def perform(message)
|
8
|
+
task_or_group_name = message[:task_or_group_name]
|
9
|
+
|
10
|
+
if task_or_group_name.nil?
|
11
|
+
Bender.logger.warn("GodUnmonitor: task_or_group_name not defined - #{message}")
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
Bender.logger.info("GodUnmonitor: #{task_or_group_name}")
|
16
|
+
|
17
|
+
# TODO: sanitize input
|
18
|
+
|
19
|
+
Open3.popen3("sudo god unmonitor #{task_or_group_name}") do |stdin, stdout, stderr, wait_thr|
|
20
|
+
info = stdout.read
|
21
|
+
error = stderr.read
|
22
|
+
Bender.logger.info("GodUnmonitor: #{info.rstrip}") unless info.empty?
|
23
|
+
Bender.logger.error("GodUnmonitor: #{error.rstrip}") unless error.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/bender.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bender/cli'
|
data/spec/bender_spec.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Bender" do
|
4
|
+
|
5
|
+
it "reads a config file" do
|
6
|
+
create_options = {:create_options => {
|
7
|
+
:visibility_timeout => 90,
|
8
|
+
:maximum_message_size => 262144
|
9
|
+
}}
|
10
|
+
|
11
|
+
poll_options = {:poll_options => {
|
12
|
+
:wait_time_seconds => 10,
|
13
|
+
:idle_timeout => 5
|
14
|
+
}}
|
15
|
+
|
16
|
+
config = {
|
17
|
+
:watchers => [{
|
18
|
+
:perform => :watcher_life_cycle_hook,
|
19
|
+
:queue => {
|
20
|
+
:name => "watcher_life_cycle_hook",
|
21
|
+
}.merge(create_options).merge(poll_options)
|
22
|
+
},
|
23
|
+
{
|
24
|
+
:perform => :god_unmonitor,
|
25
|
+
:queue => {
|
26
|
+
:name => "god_unmonitor",
|
27
|
+
}.merge(create_options).merge(poll_options)
|
28
|
+
}]
|
29
|
+
}
|
30
|
+
bender = Bender.new(config)
|
31
|
+
|
32
|
+
expect(bender.config).to eq(config)
|
33
|
+
expect(bender.watchers.count).to eq(config[:watchers].count)
|
34
|
+
|
35
|
+
watchers = bender.watchers.collect(&:class)
|
36
|
+
config[:watchers].each do |watcher|
|
37
|
+
expect(watchers).to include(watcher[:perform].to_s.classify.constantize)
|
38
|
+
end
|
39
|
+
|
40
|
+
bender.start_watchers
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/watchers.yml
ADDED
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bender
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anthony Leak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.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: '2.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aws-sdk-v1
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.61'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.61'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '4.2'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: dotenv
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: thor
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.19'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.19'
|
139
|
+
description: We all love Bender.
|
140
|
+
email:
|
141
|
+
- anthony.leak@gmail.com
|
142
|
+
executables:
|
143
|
+
- bender
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".env_sample"
|
148
|
+
- ".gitignore"
|
149
|
+
- ".rspec"
|
150
|
+
- Gemfile
|
151
|
+
- Gemfile.lock
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- bender.gemspec
|
156
|
+
- bin/bender
|
157
|
+
- lib/bender.rb
|
158
|
+
- lib/bender/cli.rb
|
159
|
+
- lib/bender/client.rb
|
160
|
+
- lib/bender/version.rb
|
161
|
+
- lib/bender/watcher.rb
|
162
|
+
- lib/bender/watchers/god_unmonitor.rb
|
163
|
+
- lib/bender/watchers/watcher_life_cycle_hook.rb
|
164
|
+
- spec/bender_spec.rb
|
165
|
+
- spec/spec_helper.rb
|
166
|
+
- watchers.yml
|
167
|
+
homepage: https://www.github.com/aleak/bender
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
metadata: {}
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
requirements: []
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 2.2.2
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Bender - Just a super guy.
|
191
|
+
test_files:
|
192
|
+
- spec/bender_spec.rb
|
193
|
+
- spec/spec_helper.rb
|