foreverb 0.2.4 → 0.2.5

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.
data/CHANGES.md CHANGED
@@ -1,11 +1,11 @@
1
- # Version 0.2.4 (unreleased)
1
+ # Version 0.2.4 - July 25, 2011
2
2
 
3
3
  * Ruby 1.9.2 compatibility
4
4
  * Stop process using pid instead of file
5
5
  * Added specs
6
6
  * Fixed `foreverb list` where in some scenarios don't return a list of processes
7
7
 
8
- # Version 0.2.3
8
+ # Version 0.2.3 - July 21, 2011
9
9
 
10
10
  * Added global monitoring, to easily watch each `foreverb` daemon
11
11
  * Look daemons through config file and unix command `ps`
data/Gemfile CHANGED
@@ -2,7 +2,3 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in forever.gemspec
4
4
  gemspec
5
-
6
- gem 'guard'
7
- gem 'guard-rspec'
8
- gem 'growl'
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  desc "Bump version on github"
12
12
  task :bump do
13
- puts "\e[31mNothing to commit (working directory clean)\e[0m" and return unless `git status -s`.chomp!
13
+ puts "\e[31mNothing to commit (working directory clean)\e[0m" and return if `git status -s`.strip == ""
14
14
  version = Bundler.load_gemspec(Dir[File.expand_path('../*.gemspec', __FILE__)].first).version
15
15
  sh "git add .; git commit -a -m \"Bump to version #{version}\""
16
16
  end
@@ -24,4 +24,4 @@ RSpec::Core::RakeTask.new("spec") do |t|
24
24
  t.rspec_opts = %w(-fs --color --fail-fast)
25
25
  end
26
26
 
27
- task :default => :spec
27
+ task :default => :spec
@@ -50,6 +50,23 @@ class CLI < Thor
50
50
  end
51
51
  end
52
52
 
53
+ desc "kill [DAEMON] [--all] [--yes]", "Kill one or more matching daemons"
54
+ method_option :all, :type => :boolean, :aliases => "-a", :desc => "All matching daemons"
55
+ method_option :yes, :type => :boolean, :aliases => "-y", :desc => "Don't ask permission to kill daemon"
56
+ def kill(daemon=nil)
57
+ find(daemon, :multiple => options.all).each do |conf|
58
+ if options.yes || yes?("Do you want really kill \e[1m#{conf[:file]}\e[0m?")
59
+ say_status "KILLING", conf[:file]
60
+ begin
61
+ pid = File.read(conf[:pid]).to_i
62
+ Process.kill(:INT, pid)
63
+ rescue Exception => e
64
+ say_status "ERROR", e.message, :red
65
+ end
66
+ end
67
+ end
68
+ end
69
+
53
70
  desc "start [DAEMON] [--all] [--yes]", "Start one or more matching daemons"
54
71
  method_option :all, :type => :boolean, :aliases => "-a", :desc => "All matching daemons"
55
72
  method_option :yes, :type => :boolean, :aliases => "-y", :desc => "Don't ask permission to start the daemon"
@@ -122,4 +139,4 @@ class CLI < Thor
122
139
  end
123
140
 
124
141
  ARGV << "-h" if ARGV.empty?
125
- CLI.start(ARGV)
142
+ CLI.start(ARGV)
@@ -6,6 +6,10 @@ require 'forever'
6
6
  Forever.run do
7
7
  dir File.expand_path('../', __FILE__) # Default is ../../__FILE__
8
8
 
9
+ every 5.seconds do
10
+ puts 'every 5 seconds'
11
+ end
12
+
9
13
  on_ready do
10
14
  puts "All jobs will will wait me for 1 second"; sleep 1
11
15
  end
@@ -50,4 +54,4 @@ Forever.run do
50
54
  on_exit do
51
55
  puts "Bye bye"
52
56
  end
53
- end
57
+ end
@@ -16,20 +16,37 @@ module Forever
16
16
 
17
17
  write_config!
18
18
 
19
- if ARGV.any? { |arg| arg == "config" }
20
- print config.to_yaml
21
- return
19
+ case ARGV[0]
20
+ when 'config'
21
+ print config.to_yaml
22
+ exit
23
+ when 'start', 'restart', 'up', nil
24
+ stop
25
+ when 'stop'
26
+ stop
27
+ exit
28
+ when 'kill'
29
+ stop!
30
+ exit
31
+ when 'help', '-h'
32
+ print <<-RUBY.gsub(/ {10}/,'') % File.basename(file)
33
+ Usage: \e[1m./%s\e[0m [start|stop|kill|restart|config]
34
+
35
+ Commands:
36
+
37
+ start stop (if present) the daemon and perform a start
38
+ stop stop the daemon if a during when it is idle
39
+ restart same as start
40
+ kill force stop by sending a KILL signal to the process
41
+ config show the current daemons config
42
+
43
+ RUBY
44
+ exit
22
45
  end
23
46
 
24
- return if ARGV.any? { |arg| arg == "up" }
25
-
26
- stop!
27
-
28
- return if ARGV.any? { |arg| arg == "stop" }
29
-
30
47
  fork do
31
48
  $0 = "Forever: #{$0}"
32
- print "=> Process demonized with pid #{Process.pid} with Forever v.#{Forever::VERSION}\n"
49
+ print "=> Process demonized with pid \e[1m#{Process.pid}\e[0m with Forever v.#{Forever::VERSION}\n"
33
50
 
34
51
  %w(INT TERM KILL).each { |signal| trap(signal) { stop! } }
35
52
  trap(:HUP) do
@@ -46,12 +63,25 @@ module Forever
46
63
 
47
64
  threads = []
48
65
  safe_call(on_ready) if on_ready
66
+ started_at = Time.now
67
+
49
68
  jobs.each do |job|
50
69
  threads << Thread.new do
51
- loop { job.time?(Time.now) ? safe_call(job) : sleep(1) }
70
+ loop do
71
+ break if File.exist?(stop_txt) && File.mtime(stop_txt) > started_at
72
+ job.time?(Time.now) ? safe_call(job) : sleep(1)
73
+ end
52
74
  end
53
75
  end
76
+
77
+ # Launch our workers
54
78
  threads.map(&:join)
79
+
80
+ # If we are here it means we are exiting so we can remove the pid and pending stop.txt
81
+ FileUtils.rm_f(pid)
82
+ FileUtils.rm_f(stop_txt)
83
+
84
+ on_exit.call if on_exit
55
85
  end
56
86
 
57
87
  self
@@ -95,19 +125,30 @@ module Forever
95
125
  # Search if there is a running process and stop it
96
126
  #
97
127
  def stop!
98
- if exists?(pid)
99
- _pid = File.read(pid).to_i
100
- print "=> Found pid #{_pid}...\n"
128
+ FileUtils.rm_f(stop_txt)
129
+ if running?
130
+ pid_was = File.read(pid).to_i
101
131
  FileUtils.rm_f(pid)
102
- begin
103
- print "=> Killing process #{_pid}...\n"
104
- on_exit.call if on_exit
105
- Process.kill(:KILL, _pid)
106
- rescue Errno::ESRCH => e
107
- puts "=> #{e.message}"
108
- end
132
+ print "=> Killing process \e[1m%d\e[0m...\n" % pid_was
133
+ on_exit.call if on_exit
134
+ Process.kill(:KILL, pid_was)
109
135
  else
110
- print "=> Pid not found, process seems don't exist!\n"
136
+ print "=> Process with \e[1mnot found\e[0m"
137
+ end
138
+ end
139
+
140
+ ##
141
+ # Perform a soft stop
142
+ #
143
+ def stop
144
+ if running?
145
+ print '=> Waiting the daemon\'s death '
146
+ FileUtils.touch(stop_txt)
147
+ while running?(true)
148
+ print '.'; $stdout.flush
149
+ sleep 1
150
+ end
151
+ print " \e[1mDONE\e[0m\n"
111
152
  end
112
153
  end
113
154
 
@@ -132,6 +173,27 @@ module Forever
132
173
  block_given? ? @_on_ready = block : @_on_ready
133
174
  end
134
175
 
176
+ ##
177
+ # Returns true if the pid exist and the process is running
178
+ #
179
+ def running?(silent=false)
180
+ if exists?(pid)
181
+ current = File.read(pid).to_i
182
+ print "=> Found pid \e[1m%d\e[0m...\n" % current unless silent
183
+ else
184
+ print "=> Pid \e[1mnot found\e[0m, process seems don't exist!\n" unless silent
185
+ return false
186
+ end
187
+
188
+ is_running = begin
189
+ Process.kill(0, current)
190
+ rescue Errno::ESRCH
191
+ false
192
+ end
193
+
194
+ is_running
195
+ end
196
+
135
197
  def to_s
136
198
  "#<Forever dir:#{dir}, file:#{file}, log:#{log}, pid:#{pid} jobs:#{jobs.size}>"
137
199
  end
@@ -161,5 +223,9 @@ module Forever
161
223
  on_error[e] if on_error
162
224
  end
163
225
  end
226
+
227
+ def stop_txt
228
+ @_stop_txt ||= File.join(dir, 'stop.txt')
229
+ end
164
230
  end # Base
165
- end # Forever
231
+ end # Forever
@@ -1,3 +1,3 @@
1
1
  module Forever
2
- VERSION = "0.2.4" unless defined?(Forever::VERSION)
2
+ VERSION = "0.2.5" unless defined?(Forever::VERSION)
3
3
  end
@@ -22,4 +22,13 @@ describe "CLI" do
22
22
  result.should_not match(/ERROR/)
23
23
  cli('list').should match(/NOT RUNNING/)
24
24
  end
25
- end
25
+
26
+ it "should kill daemons" do
27
+ run_example
28
+ cli('list').should match(/RUNNING/)
29
+ result = cli('kill -a -y')
30
+ result.should match(/KILLING/)
31
+ result.should_not match(/ERROR/)
32
+ cli('list').should match(/NOT RUNNING/)
33
+ end
34
+ end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  describe Forever do
4
4
 
5
5
  before :each do
6
+ $stdout = StringIO.new
6
7
  ARGV << 'up'
7
8
  end
8
9
 
@@ -41,7 +42,7 @@ describe Forever do
41
42
  sleep 0.1 while !File.exist?(@forever.pid)
42
43
  pid = File.read(@forever.pid).to_i
43
44
  Process.waitpid(pid)
44
- $stdout.string.should match(/pid not found/i)
45
+ $stdout.string.should match(/not found/i)
45
46
  $stdout = stdout_was
46
47
  end
47
- end
48
+ end
@@ -45,4 +45,4 @@ RSpec.configure do |config|
45
45
  end
46
46
  ARGV.clear
47
47
  end
48
- end
48
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreverb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 4
10
- version: 0.2.4
9
+ - 5
10
+ version: 0.2.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - DAddYE
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-26 00:00:00 +02:00
18
+ date: 2011-08-26 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -63,7 +63,6 @@ files:
63
63
  - .gitignore
64
64
  - CHANGES.md
65
65
  - Gemfile
66
- - Guardfile
67
66
  - README.md
68
67
  - Rakefile
69
68
  - bin/foreverb
data/Guardfile DELETED
@@ -1,5 +0,0 @@
1
- guard 'rspec', :cli => '--color' do
2
- watch(%r{^spec/.+_spec\.rb$})
3
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { "spec" }
5
- end