growing_queue_condition 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dba41234a841850840821da4468b563ae833fd1c
4
+ data.tar.gz: 76d2500a4aebebfe74dcd04298e1ef388bb6b75a
5
+ SHA512:
6
+ metadata.gz: aa60b44babaf27aacaf53dae8a30546238581b2b0c4ee41393861392dfa47a37a842e18362cf98e086c533633b9f4c43153f2dfc284de025bcf4b01bb83e4d43
7
+ data.tar.gz: 89fa6dde4e3fd8d1f315fa43297b3f687db4b7c820b132909177924b3188fa0681470bcf85c8bd9146fa6af7a6707f4ab70b3dc149f4c1f6835b3912b660cabe
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle/
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage/
10
+ doc/
11
+ lib/bundler/man
12
+ pkg/
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .ruby-version
19
+ vendor/
20
+ .rspec
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.0"
6
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'god'
6
+
7
+ group :development, :test do
8
+ gem 'debugger'
9
+ gem 'guard'
10
+ gem 'guard-rspec'
11
+ gem 'guard-spork'
12
+ gem 'spork'
13
+ gem 'rspec'
14
+ gem 'simplecov'
15
+ end
data/Guardfile ADDED
@@ -0,0 +1,35 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara features specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
25
+
26
+ guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
27
+ watch('config/application.rb')
28
+ watch('config/environment.rb')
29
+ watch('config/environments/test.rb')
30
+ watch(%r{^config/initializers/.+\.rb$})
31
+ watch('Gemfile.lock')
32
+ watch('spec/spec_helper.rb') { :rspec }
33
+ watch('test/test_helper.rb') { :test_unit }
34
+ watch(%r{features/support/}) { :cucumber }
35
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bryan
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,61 @@
1
+ # GrowingQueueCondition [![Build Status](https://travis-ci.org/rubyisbeautiful/growing_queue_condition.png)](https://travis-ci.org/rubyisbeautiful/growing_queue_condition)[![Code Climate](https://codeclimate.com/github/rubyisbeautiful/growing_queue_condition.png)](https://codeclimate.com/github/rubyisbeautiful/growing_queue_condition)
2
+
3
+ This is a God::Condition for god [http://godrb.com/] to alert on a queue that is growing. The principal use case is
4
+ for a background processors, such as DelayedJob, Resque, ActiveMQ, etc...
5
+ but could be for any growing queue/table/data store.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'growing_queue_condition'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install growing_queue_condition
20
+
21
+ ## Usage
22
+
23
+ The gem requires a class that responds to an instance method queue_size. The class must be accessible to god.
24
+
25
+ ### Example
26
+
27
+ ``my_class.rb``
28
+ {code}
29
+ class MyClass
30
+
31
+ def <<*self
32
+
33
+ def queue_size
34
+ # code returning an int or int-able value
35
+ end
36
+
37
+ end
38
+ {code}
39
+
40
+ ``god_config.rb``
41
+ {code}
42
+ require 'growing_queue_condition'
43
+
44
+ restart.condition(:growing_queue) do |c|
45
+ c.times = [3,5]
46
+ c.interval = 30.seconds
47
+ c.obj = MyClass.new
48
+ end
49
+
50
+ {code}
51
+
52
+ The example will call the instantiated MyClass instance method queue_size at least 4 times. If the size is larger or
53
+ the same each time, the condition will fail. See 'Examples' for possible usages.
54
+
55
+ ## Contributing
56
+
57
+ 1. Fork it
58
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
59
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
60
+ 4. Push to the branch (`git push origin my-new-feature`)
61
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ class DjExample
2
+
3
+ attr_accessor :user
4
+ attr_accessor :pass
5
+ attr_accessor :host
6
+ attr_accessor :db
7
+ attr_accessor :table
8
+
9
+
10
+ def initialize(opts={})
11
+ @user = opts[:user]
12
+ @pass = opts[:pass]
13
+ @host = opts[:host]
14
+ @db = opts[:db]
15
+ @table = opts[:table]
16
+ end
17
+
18
+
19
+ # this is a pretty lame example that uses command line mysql client instead of mysql2
20
+ def queue_size
21
+ `mysql -u #{user} -p'#{pass}' -h #{host} --silent --skip-column-names #{db} --execute 'select count(*) from #{table}'`
22
+ end
23
+
24
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'growing_queue_condition/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'growing_queue_condition'
8
+ spec.version = GrowingQueueCondition::VERSION
9
+ spec.authors = ['rubyisbeautiful']
10
+ spec.email = ['bcptaylor@gmail.com']
11
+ spec.description = %q{a God::Condition for the god gem, which will alert on a neglected queue using any object/method}
12
+ spec.summary = %q{a God::Condition for the god gem, which will alert on a neglected queue}
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.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+
24
+ spec.add_runtime_dependency 'god'
25
+ end
@@ -0,0 +1,9 @@
1
+ # god has this flag to prevent bundler from unnecessarily loading all of god
2
+ $load_god = true
3
+
4
+ require 'god'
5
+ require 'growing_queue_condition/version'
6
+ require 'growing_queue_condition/base'
7
+
8
+ module GrowingQueueCondition
9
+ end
@@ -0,0 +1,95 @@
1
+ module God
2
+ module Conditions
3
+ # Condition Symbol :growing_queue
4
+ # Type: Poll
5
+ #
6
+ # Trigger when a queue is growing
7
+ #
8
+ # Parameters
9
+ # Required
10
+ # +obj+ is an instance of a queue interface class
11
+ # Optional
12
+ # +method+ is the method to call, it defaults to queue_size
13
+ #
14
+ # Examples
15
+ #
16
+ # Trigger if the queue has grown 3 out of the last 5 checks
17
+ #
18
+ # restart.condition(:growing_queue) do |c|
19
+ # c.times = [3,5]
20
+ # c.interval = 30.seconds
21
+ # c.obj = MyClass.new
22
+ # end
23
+ class GrowingQueue < PollCondition
24
+ attr_accessor :times, :obj, :meth
25
+
26
+
27
+ def initialize
28
+ super
29
+ self.times ||= [2, 3]
30
+ self.meth ||= :queue_size
31
+ end
32
+
33
+
34
+ def prepare
35
+ if self.times.kind_of? Integer
36
+ self.times = [self.times, self.times]
37
+ end
38
+
39
+ @timeline = Timeline.new(self.times[1])
40
+ end
41
+
42
+
43
+ def reset
44
+ @timeline.clear
45
+ end
46
+
47
+
48
+ def valid?
49
+ valid = true
50
+ valid &= complain("Attribute 'obj' must be specified", self) if self.obj.nil?
51
+ valid
52
+ end
53
+
54
+
55
+ def test
56
+ failing = false
57
+ count = obj.call(meth)
58
+ num_of_fails = times[0]
59
+ num_of_tests = times[1]
60
+
61
+ @timeline.push count.to_i
62
+
63
+ history = "[#{@timeline.join(', ')}]"
64
+
65
+ if @timeline.length < num_of_tests
66
+ self.info = 'not enough info'
67
+ return false
68
+ end
69
+
70
+ ary = @timeline.dup.flatten
71
+ fails = []
72
+
73
+ (num_of_fails == num_of_tests ? num_of_fails-1 : num_of_fails).times do
74
+ if ary[-1] == 0
75
+ fails << false
76
+ else
77
+ fails << (ary[-1] >= ary[-2])
78
+ end
79
+ ary.shift
80
+ end
81
+
82
+ bad, good = fails.partition { |f| TrueClass === f }
83
+ failing = bad.length >= num_of_fails
84
+
85
+ if failing
86
+ self.info = "count increasing: (#{bad.length} fails #{history}"
87
+ return true
88
+ else
89
+ self.info = "count ok: #{history}"
90
+ return false
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,3 @@
1
+ module GrowingQueueCondition
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ def setup_test(condition, max_size, ary)
4
+ ary.reverse!
5
+
6
+ t = God::Timeline.new(max_size)
7
+ begin
8
+ t.push ary.pop
9
+ end until ary.empty?
10
+
11
+ condition.instance_variable_set('@timeline', t)
12
+ end
13
+
14
+
15
+ describe God::Conditions::GrowingQueue do
16
+
17
+ before :each do
18
+ # don't care about logging and don't want to see it on STDOUT
19
+ God.log_file = '/dev/null'
20
+ end
21
+
22
+
23
+ context 'initialize' do
24
+
25
+ before :each do
26
+ subject.stub(:obj).and_return double.as_null_object
27
+ end
28
+
29
+ it 'should set a default method' do
30
+ subject.meth.should == :queue_size
31
+ end
32
+ end
33
+
34
+
35
+ context 'valid' do
36
+
37
+ it 'should be false if obj is not set' do
38
+ subject.stub(:watch).and_return(double(name: 'foo').as_null_object)
39
+ subject.valid?.should be_false
40
+ end
41
+ end
42
+
43
+
44
+ context 'test' do
45
+
46
+ context 'sanity check on setup_test' do
47
+
48
+ it 'should return a properly setup object' do
49
+ setup_test(subject, 3, [1,2,3])
50
+
51
+ t = subject.instance_variable_get('@timeline')
52
+ t[0].should == 1
53
+ t[1].should == 2
54
+ t[2].should == 3
55
+ end
56
+
57
+ end
58
+
59
+
60
+ context 'when times is 3,5' do
61
+
62
+ let(:subject){ God::Conditions::GrowingQueue.new }
63
+
64
+ before :each do
65
+ subject.times = [3,5]
66
+ end
67
+
68
+ it 'should be false with results 0,0 pushing 0 (not growing)' do
69
+ obj = double
70
+ obj.should_receive(:call).with(:queue_size).and_return 0
71
+
72
+ subject.obj = obj
73
+ setup_test(subject, 5, [0,0])
74
+
75
+ subject.test.should be_false
76
+ end
77
+
78
+ it 'should be false with results 1,2 pushing 3 (not enough info)' do
79
+ obj = double
80
+ obj.should_receive(:call).with(:queue_size).and_return 3
81
+
82
+ subject.obj = obj
83
+ setup_test(subject, 5, [1,2])
84
+
85
+ subject.test.should be_false
86
+ end
87
+
88
+ it 'should be true with results 1,2,3,4 pushing 5 (growing)' do
89
+ obj = double
90
+ obj.should_receive(:call).with(:queue_size).and_return 5
91
+
92
+ subject.obj = obj
93
+ setup_test(subject, 5, [1,2,3,4])
94
+
95
+ subject.test.should be_true
96
+ end
97
+
98
+ it 'should be false with results 1,2,3,4 pushing 3 (not growing)' do
99
+ obj = double
100
+ obj.should_receive(:call).with(:queue_size).and_return 3
101
+
102
+ subject.obj = obj
103
+ setup_test(subject, 5, [1,2,3,4])
104
+
105
+ subject.test.should be_false
106
+ end
107
+
108
+ it 'should be true with results 1,1,1,1 pushing 1 (not shrinking)' do
109
+ obj = double
110
+ obj.should_receive(:call).with(:queue_size).and_return 1
111
+
112
+ subject.obj = obj
113
+ setup_test(subject, 5, [1,1,1,1])
114
+
115
+ subject.test.should be_true
116
+ end
117
+
118
+ it 'should be true with results 1,2,1,2 pushing 2 (3 of 5 fails)' do
119
+ obj = double
120
+ obj.should_receive(:call).with(:queue_size).and_return 2
121
+
122
+ subject.obj = obj
123
+ setup_test(subject, 5, [1,2,1,2])
124
+
125
+ subject.test.should be_true
126
+ end
127
+
128
+ it 'should be false with results 1,2,1,2 pushing 1 (2 of 5 fails)' do
129
+ obj = double
130
+ obj.should_receive(:call).with(:queue_size).and_return 1
131
+
132
+ subject.obj = obj
133
+ setup_test(subject, 5, [1,2,1,2])
134
+
135
+ subject.test.should be_false
136
+ end
137
+
138
+ end
139
+
140
+ end
141
+
142
+
143
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'spork'
4
+ #require 'spork/ext/ruby-debug'
5
+
6
+ Spork.prefork do
7
+ require_relative '../lib/growing_queue_condition'
8
+ RSpec.configure do |config|
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.run_all_when_everything_filtered = true
11
+ config.filter_run :focus
12
+
13
+ # Run specs in random order to surface order dependencies. If you find an
14
+ # order dependency and want to debug it, you can fix the order by providing
15
+ # the seed, which is printed after each run.
16
+ # --seed 1234
17
+ config.order = 'random'
18
+ end
19
+ end
20
+
21
+ Spork.each_run do
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: growing_queue_condition
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - rubyisbeautiful
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-29 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: god
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: a God::Condition for the god gem, which will alert on a neglected queue
56
+ using any object/method
57
+ email:
58
+ - bcptaylor@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .travis.yml
65
+ - Gemfile
66
+ - Guardfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - examples/mysql_example.rb
71
+ - growing_queue_condition.gemspec
72
+ - lib/growing_queue_condition.rb
73
+ - lib/growing_queue_condition/base.rb
74
+ - lib/growing_queue_condition/version.rb
75
+ - spec/growing_queue_condition_spec.rb
76
+ - spec/spec_helper.rb
77
+ homepage: ''
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.14
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: a God::Condition for the god gem, which will alert on a neglected queue
101
+ test_files:
102
+ - spec/growing_queue_condition_spec.rb
103
+ - spec/spec_helper.rb
104
+ has_rdoc: