From: Payton Swick Date: 2006-01-11T01:51:25+09:00 Subject: Re: Daemonize like fetchmail Would this be correct usage of the file, then? def pid dpid = nil File.open(pid_file, File::RDONLY) { |file| dpid = file.gets.chomp if file.flock(File::LOCK_SH|File::LOCK_NB); file.flock(File::LOCK_UN) } if pid_exists? dpid.to_i end def save_pid File.open(pid_file, File::CREAT|File::EXCL|File::WRONLY) { |file| file.puts $$ if file.flock(File::LOCK_EX); file.flock(File::LOCK_UN) } end -Payton ara.t.howard@noaa.gov wrote: > On Tue, 10 Jan 2006, Payton Swick wrote: > >> Well, I did it myself anyway. Hope it's useful: >> http://rubyforge.org/projects/pidify/ >> >> -Payton > > > it does look useful. few comments/suggestions though > > - since it's *nix specify anyhow you might want to use O_EXCL when > opening > the file since otherwise there is a race condition to create the file > > - on the same page using File#flock with File::LOCK_EX when writing and > File::LOCK_SH for writing and reading (with File::LOCK_NB of course) > will > avoid the race conditions and possibibity of reading a half-baked file > > - escalation of signals with a pause between is useful for killing > processes > since many trap signit and most do not die immediately. something like > > def maim(pid, signals=%w(SIGTERM SIGQUIT SIGKILL), suspend=4) > pid = Integer("#{ pid }") > signals = [ signals ].flatten.map{|sig| "#{ sig }"} > suspend = Integer("#{ suspend }") > > existed = false > sigs.each do |sig| > begin > Process::kill(sig, pid) > existed = true > rescue Errno::ESRCH > return(existed ? true : nil) > end > return true unless alive?(pid) > sleep suspend > return true unless alive?(pid) > end > return(not alive?(pid)) > end > > which makes sure the process is actually dead prevents removing the > pidfile in cases where the Process::kill didn't work > > - the alive function above can be something like this > > def alive pid > pid = Integer("#{ pid }") > begin > Process::kill 0, pid > true > rescue Errno::ESRCH > false > end > end > > cheers. > > -a