#199
[acts_as_ferret.git] / lib / unix_daemon.rb
blobceaf2d7c15242126565a79da9ec6d31fdddd7d96
1 ################################################################################
2 module ActsAsFerret
3   module Remote
5     ################################################################################
6     # methods for becoming a daemon on Unix-like operating systems
7     module UnixDaemon
9       ################################################################################
10       def platform_daemon (&block)
11         safefork do
12           write_pid_file
13           trap("TERM") { exit(0) }
14           sess_id = Process.setsid
15           STDIN.reopen("/dev/null")
16           STDOUT.reopen("#{RAILS_ROOT}/log/ferret_server.out", "a")
17           STDERR.reopen(STDOUT)
18           block.call
19         end
20       end
22       ################################################################################
23       # stop the daemon, nicely at first, and then forcefully if necessary
24       def stop
25         pid = read_pid_file
26         raise "ferret_server doesn't appear to be running" unless pid
27         $stdout.puts("stopping ferret server...")
28         Process.kill("TERM", pid)
29         30.times { Process.kill(0, pid); sleep(0.5) }
30         $stdout.puts("using kill -9 #{pid}")
31         Process.kill(9, pid)
32       rescue Errno::ESRCH => e
33         $stdout.puts("process #{pid} has stopped")
34       ensure
35         File.unlink(@cfg.pid_file) if File.exist?(@cfg.pid_file)
36       end
38       ################################################################################
39       def safefork (&block)
40         @fork_tries ||= 0
41         fork(&block)
42       rescue Errno::EWOULDBLOCK
43         raise if @fork_tries >= 20
44         @fork_tries += 1
45         sleep 5
46         retry
47       end
49       #################################################################################
50       # create the PID file and install an at_exit handler
51       def write_pid_file
52         raise "ferret_server may already be running, a pid file exists: #{@cfg.pid_file}" if read_pid_file
53         open(@cfg.pid_file, "w") {|f| f << Process.pid << "\n"}
54         at_exit { File.unlink(@cfg.pid_file) if read_pid_file == Process.pid }
55       end
57       #################################################################################
58       def read_pid_file
59         File.read(@cfg.pid_file).to_i if File.exist?(@cfg.pid_file)
60       end
62     end
63   end
64 end