Permalink
Browse files

Added a soft stop and switched old one to kill.

  • Loading branch information...
1 parent 057bb48 commit 3159efa3860acc10d59d32e03e74f1d74e49080a @DAddYE committed Aug 26, 2011
Showing with 129 additions and 41 deletions.
  1. +0 −4 Gemfile
  2. +0 −5 Guardfile
  3. +2 −2 Rakefile
  4. +18 −1 bin/foreverb
  5. +5 −1 examples/sample
  6. +89 −23 lib/forever/base.rb
  7. +1 −1 lib/forever/version.rb
  8. +10 −1 spec/cli_spec.rb
  9. +3 −2 spec/foreverb_spec.rb
  10. +1 −1 spec/spec_helper.rb
View
@@ -2,7 +2,3 @@ source "http://rubygems.org"
# Specify your gem's dependencies in forever.gemspec
gemspec
-
-gem 'guard'
-gem 'guard-rspec'
-gem 'growl'
View
@@ -1,5 +0,0 @@
-guard 'rspec', :cli => '--color' do
- watch(%r{^spec/.+_spec\.rb$})
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
- watch('spec/spec_helper.rb') { "spec" }
-end
View
@@ -10,7 +10,7 @@ end
desc "Bump version on github"
task :bump do
- puts "\e[31mNothing to commit (working directory clean)\e[0m" and return unless `git status -s`.chomp!
+ puts "\e[31mNothing to commit (working directory clean)\e[0m" and return unless `git status -s`.strip == ""
version = Bundler.load_gemspec(Dir[File.expand_path('../*.gemspec', __FILE__)].first).version
sh "git add .; git commit -a -m \"Bump to version #{version}\""
end
@@ -24,4 +24,4 @@ RSpec::Core::RakeTask.new("spec") do |t|
t.rspec_opts = %w(-fs --color --fail-fast)
end
-task :default => :spec
+task :default => :spec
View
@@ -50,6 +50,23 @@ class CLI < Thor
end
end
+ desc "kill [DAEMON] [--all] [--yes]", "Kill one or more matching daemons"
+ method_option :all, :type => :boolean, :aliases => "-a", :desc => "All matching daemons"
+ method_option :yes, :type => :boolean, :aliases => "-y", :desc => "Don't ask permission to kill daemon"
+ def kill(daemon=nil)
+ find(daemon, :multiple => options.all).each do |conf|
+ if options.yes || yes?("Do you want really kill \e[1m#{conf[:file]}\e[0m?")
+ say_status "KILLING", conf[:file]
+ begin
+ pid = File.read(conf[:pid]).to_i
+ Process.kill(:INT, pid)
+ rescue Exception => e
+ say_status "ERROR", e.message, :red
+ end
+ end
+ end
+ end
+
desc "start [DAEMON] [--all] [--yes]", "Start one or more matching daemons"
method_option :all, :type => :boolean, :aliases => "-a", :desc => "All matching daemons"
method_option :yes, :type => :boolean, :aliases => "-y", :desc => "Don't ask permission to start the daemon"
@@ -122,4 +139,4 @@ class CLI < Thor
end
ARGV << "-h" if ARGV.empty?
-CLI.start(ARGV)
+CLI.start(ARGV)
View
@@ -6,6 +6,10 @@ require 'forever'
Forever.run do
dir File.expand_path('../', __FILE__) # Default is ../../__FILE__
+ every 5.seconds do
+ puts 'every 5 seconds'
+ end
+
on_ready do
puts "All jobs will will wait me for 1 second"; sleep 1
end
@@ -50,4 +54,4 @@ Forever.run do
on_exit do
puts "Bye bye"
end
-end
+end
View
@@ -16,20 +16,37 @@ def initialize(options={}, &block)
write_config!
- if ARGV.any? { |arg| arg == "config" }
- print config.to_yaml
- return
+ case ARGV[0]
+ when 'config'
+ print config.to_yaml
+ exit
+ when 'start', 'restart', 'up', nil
+ stop
+ when 'stop'
+ stop
+ exit
+ when 'kill'
+ stop!
+ exit
+ when 'help', '-h'
+ print <<-RUBY.gsub(/ {10}/,'') % File.basename(file)
+ Usage: \e[1m./%s\e[0m [start|stop|kill|restart|config]
+
+ Commands:
+
+ start stop (if present) the daemon and perform a start
+ stop stop the daemon if a during when it is idle
+ restart same as start
+ kill force stop by sending a KILL signal to the process
+ config show the current daemons config
+
+ RUBY
+ exit
end
- return if ARGV.any? { |arg| arg == "up" }
-
- stop!
-
- return if ARGV.any? { |arg| arg == "stop" }
-
fork do
$0 = "Forever: #{$0}"
- print "=> Process demonized with pid #{Process.pid} with Forever v.#{Forever::VERSION}\n"
+ print "=> Process demonized with pid \e[1m#{Process.pid}\e[0m with Forever v.#{Forever::VERSION}\n"
%w(INT TERM KILL).each { |signal| trap(signal) { stop! } }
trap(:HUP) do
@@ -46,12 +63,25 @@ def initialize(options={}, &block)
threads = []
safe_call(on_ready) if on_ready
+ started_at = Time.now
+
jobs.each do |job|
threads << Thread.new do
- loop { job.time?(Time.now) ? safe_call(job) : sleep(1) }
+ loop do
+ break if File.exist?(stop_txt) && File.mtime(stop_txt) > started_at
+ job.time?(Time.now) ? safe_call(job) : sleep(1)
+ end
end
end
+
+ # Launch our workers
threads.map(&:join)
+
+ # If we are here it means we are exiting so we can remove the pid and pending stop.txt
+ FileUtils.rm_f(pid)
+ FileUtils.rm_f(stop_txt)
+
+ on_exit.call if on_exit
end
self
@@ -95,19 +125,30 @@ def pid(value=nil)
# Search if there is a running process and stop it
#
def stop!
- if exists?(pid)
- _pid = File.read(pid).to_i
- print "=> Found pid #{_pid}...\n"
+ FileUtils.rm_f(stop_txt)
+ if running?
+ pid_was = File.read(pid).to_i
FileUtils.rm_f(pid)
- begin
- print "=> Killing process #{_pid}...\n"
- on_exit.call if on_exit
- Process.kill(:KILL, _pid)
- rescue Errno::ESRCH => e
- puts "=> #{e.message}"
- end
+ print "=> Killing process \e[1m%d\e[0m...\n" % pid_was
+ on_exit.call if on_exit
+ Process.kill(:KILL, pid_was)
else
- print "=> Pid not found, process seems don't exist!\n"
+ print "=> Process with \e[1mnot found\e[0m"
+ end
+ end
+
+ ##
+ # Perform a soft stop
+ #
+ def stop
+ if running?
+ print '=> Waiting the daemon\'s death '
+ FileUtils.touch(stop_txt)
+ while running?(true)
+ print '.'; $stdout.flush
+ sleep 1
+ end
+ print " \e[1mDONE\e[0m\n"
end
end
@@ -132,6 +173,27 @@ def on_ready(&block)
block_given? ? @_on_ready = block : @_on_ready
end
+ ##
+ # Returns true if the pid exist and the process is running
+ #
+ def running?(silent=false)
+ if exists?(pid)
+ current = File.read(pid).to_i
+ print "=> Found pid \e[1m%d\e[0m...\n" % current unless silent
+ else
+ print "=> Pid \e[1mnot found\e[0m, process seems don't exist!\n" unless silent
+ return false
+ end
+
+ is_running = begin
+ Process.kill(0, current)
+ rescue Errno::ESRCH
+ false
+ end
+
+ is_running
+ end
+
def to_s
"#<Forever dir:#{dir}, file:#{file}, log:#{log}, pid:#{pid} jobs:#{jobs.size}>"
end
@@ -161,5 +223,9 @@ def safe_call(block)
on_error[e] if on_error
end
end
+
+ def stop_txt
+ @_stop_txt ||= File.join(dir, 'stop.txt')
+ end
end # Base
-end # Forever
+end # Forever
@@ -1,3 +1,3 @@
module Forever
- VERSION = "0.2.4" unless defined?(Forever::VERSION)
+ VERSION = "0.2.5" unless defined?(Forever::VERSION)
end
View
@@ -22,4 +22,13 @@
result.should_not match(/ERROR/)
cli('list').should match(/NOT RUNNING/)
end
-end
+
+ it "should kill daemons" do
+ run_example
+ cli('list').should match(/RUNNING/)
+ result = cli('kill -a -y')
+ result.should match(/KILLING/)
+ result.should_not match(/ERROR/)
+ cli('list').should match(/NOT RUNNING/)
+ end
+end
@@ -3,6 +3,7 @@
describe Forever do
before :each do
+ $stdout = StringIO.new
ARGV << 'up'
end
@@ -41,7 +42,7 @@
sleep 0.1 while !File.exist?(@forever.pid)
pid = File.read(@forever.pid).to_i
Process.waitpid(pid)
- $stdout.string.should match(/pid not found/i)
+ $stdout.string.should match(/not found/i)
$stdout = stdout_was
end
-end
+end
View
@@ -45,4 +45,4 @@ def cli(task)
end
ARGV.clear
end
-end
+end

0 comments on commit 3159efa

Please sign in to comment.