ryansch-bluepill 0.0.53

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +8 -0
  2. data/DESIGN.md +10 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +306 -0
  6. data/Rakefile +9 -0
  7. data/bin/bluepill +111 -0
  8. data/bin/bpsv +3 -0
  9. data/bin/sample_forking_server +53 -0
  10. data/bluepill.gemspec +29 -0
  11. data/examples/example.rb +87 -0
  12. data/examples/new_example.rb +89 -0
  13. data/examples/new_runit_example.rb +29 -0
  14. data/examples/runit_example.rb +26 -0
  15. data/lib/bluepill.rb +36 -0
  16. data/lib/bluepill/application.rb +203 -0
  17. data/lib/bluepill/application/client.rb +8 -0
  18. data/lib/bluepill/application/server.rb +23 -0
  19. data/lib/bluepill/condition_watch.rb +50 -0
  20. data/lib/bluepill/controller.rb +121 -0
  21. data/lib/bluepill/dsl.rb +12 -0
  22. data/lib/bluepill/dsl/app_proxy.rb +25 -0
  23. data/lib/bluepill/dsl/process_factory.rb +122 -0
  24. data/lib/bluepill/dsl/process_proxy.rb +44 -0
  25. data/lib/bluepill/group.rb +72 -0
  26. data/lib/bluepill/logger.rb +63 -0
  27. data/lib/bluepill/process.rb +478 -0
  28. data/lib/bluepill/process_conditions.rb +14 -0
  29. data/lib/bluepill/process_conditions/always_true.rb +18 -0
  30. data/lib/bluepill/process_conditions/cpu_usage.rb +19 -0
  31. data/lib/bluepill/process_conditions/http.rb +58 -0
  32. data/lib/bluepill/process_conditions/mem_usage.rb +32 -0
  33. data/lib/bluepill/process_conditions/process_condition.rb +22 -0
  34. data/lib/bluepill/process_statistics.rb +23 -0
  35. data/lib/bluepill/socket.rb +47 -0
  36. data/lib/bluepill/system.rb +235 -0
  37. data/lib/bluepill/trigger.rb +60 -0
  38. data/lib/bluepill/triggers/flapping.rb +56 -0
  39. data/lib/bluepill/util/rotational_array.rb +20 -0
  40. data/lib/bluepill/version.rb +4 -0
  41. metadata +192 -0
@@ -0,0 +1,60 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Bluepill
3
+ class Trigger
4
+ @implementations = {}
5
+ def self.inherited(klass)
6
+ @implementations[klass.name.split('::').last.underscore.to_sym] = klass
7
+ end
8
+
9
+ def self.[](name)
10
+ @implementations[name]
11
+ end
12
+
13
+ attr_accessor :process, :logger, :mutex, :scheduled_events
14
+
15
+ def initialize(process, options = {})
16
+ self.process = process
17
+ self.logger = options[:logger]
18
+ self.mutex = Mutex.new
19
+ self.scheduled_events = []
20
+ end
21
+
22
+ def reset!
23
+ self.cancel_all_events
24
+ end
25
+
26
+ def notify(transition)
27
+ raise "Implement in subclass"
28
+ end
29
+
30
+ def dispatch!(event)
31
+ self.process.dispatch!(event, self.class.name.split("::").last)
32
+ end
33
+
34
+ def schedule_event(event, delay)
35
+ # TODO: maybe wrap this in a ScheduledEvent class with methods like cancel
36
+ thread = Thread.new(self) do |trigger|
37
+ begin
38
+ sleep delay.to_f
39
+ trigger.dispatch!(event)
40
+ trigger.mutex.synchronize do
41
+ trigger.scheduled_events.delete_if { |_, thread| thread == Thread.current }
42
+ end
43
+ rescue StandardError => e
44
+ trigger.logger.err(e)
45
+ trigger.logger.err(e.backtrace.join("\n"))
46
+ end
47
+ end
48
+
49
+ self.scheduled_events.push([event, thread])
50
+ end
51
+
52
+ def cancel_all_events
53
+ self.logger.info "Canceling all scheduled events"
54
+ self.mutex.synchronize do
55
+ self.scheduled_events.each {|_, thread| thread.kill}
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,56 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Bluepill
3
+ module Triggers
4
+ class Flapping < Bluepill::Trigger
5
+ TRIGGER_STATES = [:starting, :restarting]
6
+
7
+ PARAMS = [:times, :within, :retry_in]
8
+
9
+ attr_accessor *PARAMS
10
+ attr_reader :timeline
11
+
12
+ def initialize(process, options = {})
13
+ options.reverse_merge!(:times => 5, :within => 1, :retry_in => 5)
14
+
15
+ options.each_pair do |name, val|
16
+ instance_variable_set("@#{name}", val) if PARAMS.include?(name)
17
+ end
18
+
19
+ @timeline = Util::RotationalArray.new(@times)
20
+ super
21
+ end
22
+
23
+ def notify(transition)
24
+ if TRIGGER_STATES.include?(transition.to_name)
25
+ self.timeline << Time.now.to_i
26
+ self.check_flapping
27
+ end
28
+ end
29
+
30
+ def reset!
31
+ @timeline.clear
32
+ super
33
+ end
34
+
35
+ def check_flapping
36
+ # The process has not flapped if we haven't encountered enough incidents
37
+ return unless (@timeline.compact.length == self.times)
38
+
39
+ # Check if the incident happend within the timeframe
40
+ duration = (@timeline.last - @timeline.first) <= self.within
41
+
42
+ if duration
43
+ self.logger.info "Flapping detected: retrying in #{self.retry_in} seconds"
44
+
45
+ self.schedule_event(:start, self.retry_in) unless self.retry_in == 0 # retry_in zero means "do not retry, ever"
46
+ self.schedule_event(:unmonitor, 0)
47
+
48
+ @timeline.clear
49
+
50
+ # This will prevent a transition from happening in the process state_machine
51
+ throw :halt
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Bluepill
3
+ module Util
4
+ class RotationalArray < Array
5
+ def initialize(size)
6
+ @capacity = size
7
+
8
+ super() # no size - intentionally
9
+ end
10
+
11
+ def push(value)
12
+ super(value)
13
+
14
+ self.shift if self.length > @capacity
15
+ self
16
+ end
17
+ alias_method :<<, :push
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Bluepill
3
+ VERSION = "0.0.53".freeze
4
+ end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ryansch-bluepill
3
+ version: !ruby/object:Gem::Version
4
+ hash: 117
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 53
10
+ version: 0.0.53
11
+ platform: ruby
12
+ authors:
13
+ - Arya Asemanfar
14
+ - Gary Tsang
15
+ - Rohith Ravi
16
+ - Ryan Schlesinger
17
+ autorequire:
18
+ bindir: bin
19
+ cert_chain: []
20
+
21
+ date: 2011-08-19 00:00:00 -07:00
22
+ default_executable:
23
+ dependencies:
24
+ - !ruby/object:Gem::Dependency
25
+ name: daemons
26
+ prerelease: false
27
+ requirement: &id001 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ hash: 19
33
+ segments:
34
+ - 1
35
+ - 1
36
+ - 0
37
+ version: 1.1.0
38
+ type: :runtime
39
+ version_requirements: *id001
40
+ - !ruby/object:Gem::Dependency
41
+ name: state_machine
42
+ prerelease: false
43
+ requirement: &id002 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ hash: 51
49
+ segments:
50
+ - 0
51
+ - 9
52
+ - 4
53
+ version: 0.9.4
54
+ type: :runtime
55
+ version_requirements: *id002
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ prerelease: false
59
+ requirement: &id003 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 7
65
+ segments:
66
+ - 3
67
+ - 0
68
+ - 0
69
+ version: 3.0.0
70
+ type: :runtime
71
+ version_requirements: *id003
72
+ - !ruby/object:Gem::Dependency
73
+ name: i18n
74
+ prerelease: false
75
+ requirement: &id004 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 11
81
+ segments:
82
+ - 0
83
+ - 5
84
+ - 0
85
+ version: 0.5.0
86
+ type: :runtime
87
+ version_requirements: *id004
88
+ - !ruby/object:Gem::Dependency
89
+ name: bundler
90
+ prerelease: false
91
+ requirement: &id005 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 1
99
+ - 0
100
+ - 10
101
+ version: 1.0.10
102
+ type: :development
103
+ version_requirements: *id005
104
+ description: Bluepill keeps your daemons up while taking up as little resources as possible. After all you probably want the resources of your server to be used by whatever daemons you are running rather than the thing that's supposed to make sure they are brought back up, should they die or misbehave.
105
+ email:
106
+ - ryan@instanceinc.com
107
+ executables:
108
+ - bluepill
109
+ - bpsv
110
+ - sample_forking_server
111
+ extensions: []
112
+
113
+ extra_rdoc_files:
114
+ - LICENSE
115
+ - README.md
116
+ files:
117
+ - .gitignore
118
+ - DESIGN.md
119
+ - Gemfile
120
+ - LICENSE
121
+ - README.md
122
+ - Rakefile
123
+ - bin/bluepill
124
+ - bin/bpsv
125
+ - bin/sample_forking_server
126
+ - bluepill.gemspec
127
+ - examples/example.rb
128
+ - examples/new_example.rb
129
+ - examples/new_runit_example.rb
130
+ - examples/runit_example.rb
131
+ - lib/bluepill.rb
132
+ - lib/bluepill/application.rb
133
+ - lib/bluepill/application/client.rb
134
+ - lib/bluepill/application/server.rb
135
+ - lib/bluepill/condition_watch.rb
136
+ - lib/bluepill/controller.rb
137
+ - lib/bluepill/dsl.rb
138
+ - lib/bluepill/dsl/app_proxy.rb
139
+ - lib/bluepill/dsl/process_factory.rb
140
+ - lib/bluepill/dsl/process_proxy.rb
141
+ - lib/bluepill/group.rb
142
+ - lib/bluepill/logger.rb
143
+ - lib/bluepill/process.rb
144
+ - lib/bluepill/process_conditions.rb
145
+ - lib/bluepill/process_conditions/always_true.rb
146
+ - lib/bluepill/process_conditions/cpu_usage.rb
147
+ - lib/bluepill/process_conditions/http.rb
148
+ - lib/bluepill/process_conditions/mem_usage.rb
149
+ - lib/bluepill/process_conditions/process_condition.rb
150
+ - lib/bluepill/process_statistics.rb
151
+ - lib/bluepill/socket.rb
152
+ - lib/bluepill/system.rb
153
+ - lib/bluepill/trigger.rb
154
+ - lib/bluepill/triggers/flapping.rb
155
+ - lib/bluepill/util/rotational_array.rb
156
+ - lib/bluepill/version.rb
157
+ has_rdoc: true
158
+ homepage: http://github.com/ryansch/bluepill
159
+ licenses: []
160
+
161
+ post_install_message:
162
+ rdoc_options: []
163
+
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ none: false
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ hash: 3
172
+ segments:
173
+ - 0
174
+ version: "0"
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ hash: 3
181
+ segments:
182
+ - 0
183
+ version: "0"
184
+ requirements: []
185
+
186
+ rubyforge_project:
187
+ rubygems_version: 1.6.2
188
+ signing_key:
189
+ specification_version: 3
190
+ summary: A process monitor written in Ruby with stability and minimalism in mind.
191
+ test_files: []
192
+