Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Check that the pidfile is not already present before overriding it #371

Closed
wants to merge 2 commits into from

4 participants

@byroot

It fix the issue reported here: rails/rails#5534

At first I tried to write some test, but because of the exit(1) it's not that easy. If someone have a idea of how to write some test about that...

@JeronimoColon

Thanks for taking care of this. Hopefully it gets accepted cause it's a pain to loose the pid.

@raggi
Owner

I would like to do several things with this before merge:

  • Check if the PID is running, if it is, then abort
  • If the PID is not running, then boot and replace the pidfile.
  • Add tests.
@byroot

Sure, I'll try to find a moment to do that this week end.

@byroot

Here we are.

The code now check if the process is still running / dead / or owned by another user.
With associated tests.

I also tried to test the check_pid!method, but I don't know how to test exit and STDERR.puts calls.

@travisbot

This pull request passes (merged 3b9410e into 6141192).

@raggi raggi referenced this pull request from a commit
@byroot byroot Check if the PID in pidfile is still running #371
Then abort or remove the pidfile
b4d7b95
@raggi
Owner

Merged, thank you!

@raggi raggi closed this
@raggi
Owner

FTR, I made a minor change:

edc8b92

@raggi raggi referenced this pull request from a commit
@byroot byroot Check if the PID in pidfile is still running #371
Then abort or remove the pidfile
88ed888
@raggi raggi referenced this pull request from a commit
@byroot byroot Check if the PID in pidfile is still running #371
Then abort or remove the pidfile
03a7303
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 5, 2012
  1. @byroot
  2. @byroot

    Check if the PID in pidfile is still running #371

    byroot authored
    Then abort or remove the pidfile
This page is out of date. Refresh to see the latest.
Showing with 57 additions and 0 deletions.
  1. +31 −0 lib/rack/server.rb
  2. +26 −0 test/spec_server.rb
View
31 lib/rack/server.rb
@@ -247,11 +247,14 @@ def start &blk
pp app
end
+ check_pid! if options[:pid]
+
# Touch the wrapped app, so that the config.ru is loaded before
# daemonization (i.e. before chdir, etc).
wrapped_app
daemonize_app if options[:daemonize]
+
write_pid if options[:pid]
trap(:INT) do
@@ -319,5 +322,33 @@ def write_pid
::File.open(options[:pid], 'w'){ |f| f.write("#{Process.pid}") }
at_exit { ::File.delete(options[:pid]) if ::File.exist?(options[:pid]) }
end
+
+ def check_pid!
+ case pidfile_process_status
+ when :running
+ STDERR.puts "The process is still alive. aborting."
+ exit(1)
+ when :not_owned
+ STDERR.puts "The process is still alive. And owned by another user aborting."
+ exit(1)
+ when :dead
+ STDERR.puts "The process is no longer running. Removing the pid file."
+ ::File.delete(options[:pid])
+ end
+ end
+
+ def pidfile_process_status
+ return :exited unless ::File.exist?(options[:pid])
+
+ pid = ::File.read(options[:pid]).to_i
+ STDERR.puts "There is already a pid file wrote a by process with pid #{pid}"
+ Process.kill(0, pid)
+ :running
+ rescue Errno::ESRCH
+ :dead
+ rescue Errno::EPERM
+ :not_owned
+ end
+
end
end
View
26 test/spec_server.rb
@@ -71,4 +71,30 @@ def app
open(pidfile) { |f| f.read.should.eql $$.to_s }
end
+ should "check pid file presence and running process" do
+ pidfile = Tempfile.open('pidfile') { |f| f.write($$); break f }.path
+ server = Rack::Server.new(:pid => pidfile)
+ server.send(:pidfile_process_status).should.eql :running
+ end
+
+ should "check pid file presence and dead process" do
+ dead_pid = `echo $$`.to_i
+ pidfile = Tempfile.open('pidfile') { |f| f.write(dead_pid); break f }.path
+ server = Rack::Server.new(:pid => pidfile)
+ server.send(:pidfile_process_status).should.eql :dead
+ end
+
+ should "check pid file presence and exited process" do
+ pidfile = Tempfile.open('pidfile') { |f| break f }.path
+ ::File.delete(pidfile)
+ server = Rack::Server.new(:pid => pidfile)
+ server.send(:pidfile_process_status).should.eql :exited
+ end
+
+ should "check pid file presence and not owned process" do
+ pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
+ server = Rack::Server.new(:pid => pidfile)
+ server.send(:pidfile_process_status).should.eql :not_owned
+ end
+
end
Something went wrong with that request. Please try again.