Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

make mongrel cleanup stale pidfiles (See related posts)

users of monitoring systems may have noticed that mongrel can leave stale PID files behind, which prevents automated monitors from restarting mongrels that have been detected as dead via a port or process check, as mongrel's default behaviour is to exit upon the detection of a pre-existing PID file, whether there is in fact a process of that id running or not.

a fix, in /usr/local/lib/ruby/gems/1.8/gems/mongrel-x.x.x/bin/mongrel_rails:


if File.exist? defaults[:pid_file]
# mongrels that crash can leave stale PID files behind, and these
# should not stop mongrel from being restarted by monitors...
pid = File.new(defaults[:pid_file]).readline
unless `ps -ef | grep #{pid} | grep -v grep`.length > 0
# use "ps ax" for freebsd
log "!!! PID file #{defaults[:pid_file]} exists, but is stale, and will be deleted so that this mongrel can run."
File.delete(defaults[:pid_file])
else
log "!!! PID file #{defaults[:pid_file]} already exists and the process id referred to in it is running. This mongrel is probably already running. #{defaults[:log_file]} for errors. EXITING."
exit 1
end
end


there is a call to at_exit in mongrel, which should be cleaning these files up.. but is not.

Comments on this post

laaz posts on Apr 13, 2007 at 07:11
This code has a BUG, which causes it to reverse its behaviour:
The line:
if `ps -ef | grep #{pid} | grep -v grep`.length > 0

Should read instead:
unless `ps -ef | grep #{pid} | grep -v grep`.length > 0



The following is the same thing in patch form:
--- bin/mongrel_rails-orig      2007-04-13 09:44:11.000000000 +0300
+++ bin/mongrel_rails   2007-04-13 10:00:39.000000000 +0300
@@ -83,10 +83,18 @@
       config = Mongrel::Rails::RailsConfigurator.new(settings) do
         if defaults[:daemon]
           if File.exist? defaults[:pid_file]
-            log "!!! PID file #{defaults[:pid_file]} already exists.  Mongrel could be running already.  Check your #{defaults[:log_file]} for errors."
-            log "!!! Exiting with error.  You must stop mongrel and clear the .pid before I'll attempt a start."
-            exit 1
-          end
+           # mongrels that crash can leave stale PID files behind, and these
+           # should not stop mongrel from being restarted by monitors...
+           pid = File.new(defaults[:pid_file]).readline
+           unless `ps -ef | grep #{pid} | grep -v grep`.length > 0
+             # use "ps ax" for freebsd
+             log "!!! PID file #{defaults[:pid_file]} exists, but is stale, and will be deleted so that this mongrel can run."
+             File.delete(defaults[:pid_file])
+           else
+             log "!!! PID file #{defaults[:pid_file]} already exists and the process id referred to in it is running.  This mongrel is probably already run
ning.  #{defaults[:log_file]} for errors.  EXITING."
+             exit 1
+           end
+         end

           daemonize
           log "Daemonized, any open files are closed.  Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info."


Apply it in mongrel directory (probably /usr/lib/ruby/gems/1.8/gems/mongrel-x.x.x/) by:
patch -p0 < /path/to/mongrel_stale_pid_file.patch
aktxyz posts on Apr 23, 2007 at 20:47
my take on the patch using ps --pid

if File.exist? defaults[:pid_file]
#===== new stuff
pid = File.new(defaults[:pid_file]).readline
if `ps --pid #{pid} --no-headers`.length > 0
log "!!! PID file #{defaults[:pid_file]} exists, but is stale, and will be deleted so that this mongrel can run."
File.delete(defaults[:pid_file])
else
log "!!! PID file #{defaults[:pid_file]} already exists and the process id referred to in it is running. This mongrel is probably already running. #{defaults[:log_file]} for errors. EXITING."
exit 1
end
#===== old stuff
#log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors."
#log "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start."
exit 1
end
tedhhi posts on May 15, 2007 at 19:10
As a minor improvement, forking a 'ps' isn't necessary at all. Using Process.kill, with a signal of 0, would be more elegant. Read more at http://www.rubycentral.com/book/ref_m_process.html#Process.kill .
rmm5t posts on May 24, 2007 at 18:16
Very nice. Thank you. I took the best of this plus the Process.kill comment that tedhhi gave and incorporated it into a patch for the mongrel team. Hopefully, they'll include it.
http://rubyforge.org/tracker/index.php?func=detail&aid=11098&group_id=1306&atid=5147
PaulGoscicki posts on Mar 29, 2008 at 12:58
Mongrel_cluster gem now has the
--clean
option to cleanup stale pid files. I've written about it here.

You need to create an account or log in to post comments to this site.