public
Rubygem
Description: A very fast & simple Ruby web server
Homepage: http://code.macournoyer.com/thin/
Clone URL: git://github.com/macournoyer/thin.git
Click here to lend your support to: thin and make a donation at www.pledgie.com !
Add --force (-f) option to force stopping of a daemonized server, [#72 
state:resolved]
macournoyer (author)
Sun Jul 13 20:27:39 -0700 2008
commit  729b76ae2391a197e14d1bb8ec2d40f82a47b1a4
tree    f79aa8ce3ad7c533e12aea53033d85a8bf4e36f4
parent  fef2e74f143dee8fea49e110e51aa3a66ecccc9b
...
1
 
2
3
4
...
1
2
3
4
5
0
@@ -1,4 +1,5 @@
0
 == 1.0.0 The Big release
0
+ * Add --force (-f) option to force stopping of a daemonized server, fixes [#72 state:resolved]
0
  * Update halycon adapter loader [mtodd]
0
 
0
 == 0.8.2 Double Margarita release
...
83
84
85
86
 
87
88
89
...
83
84
85
 
86
87
88
89
0
@@ -83,7 +83,7 @@ module Thin
0
         raise OptionRequired, :pid unless @options[:pid]
0
       
0
         tail_log(@options[:log]) do
0
-          if Server.kill(@options[:pid], @options[:timeout] || 60)
0
+          if Server.kill(@options[:pid], @options[:force] ? 0 : (@options[:timeout] || 60))
0
             wait_for_file :deletion, @options[:pid]
0
           end
0
         end
...
89
90
91
92
 
 
93
94
95
96
97
98
99
 
 
 
 
100
101
102
103
104
105
106
107
108
109
110
...
113
114
115
116
117
 
 
118
119
120
 
 
 
121
122
123
124
125
126
 
 
 
 
 
127
128
129
130
 
 
 
131
132
133
...
89
90
91
 
92
93
94
95
96
 
 
 
 
97
98
99
100
101
 
 
 
 
 
 
 
102
103
104
...
107
108
109
 
 
110
111
112
113
114
115
116
117
118
 
119
120
 
121
122
123
124
125
126
127
128
 
 
129
130
131
132
133
134
0
@@ -89,22 +89,16 @@ module Thin
0
     end
0
     
0
     module ClassMethods
0
-      # Send a QUIT signal the process which PID is stored in +pid_file+.
0
+      # Send a QUIT or INT (if timeout is +0+) signal the process which
0
+      # PID is stored in +pid_file+.
0
       # If the process is still running after +timeout+, KILL signal is
0
       # sent.
0
       def kill(pid_file, timeout=60)
0
-        if pid = send_signal('QUIT', pid_file)
0
-          Timeout.timeout(timeout) do
0
-            sleep 0.1 while Process.running?(pid)
0
-          end
0
+        if timeout == 0
0
+          send_signal('INT', pid_file, timeout)
0
+        else
0
+          send_signal('QUIT', pid_file, timeout)
0
         end
0
-      rescue Timeout::Error
0
-        print "Timeout! "
0
-        send_signal('KILL', pid_file)
0
-      rescue Interrupt
0
-        send_signal('KILL', pid_file)
0
-      ensure
0
-        File.delete(pid_file) if File.exist?(pid_file)
0
       end
0
       
0
       # Restart the server by sending HUP signal.
0
@@ -113,21 +107,28 @@ module Thin
0
       end
0
       
0
       # Send a +signal+ to the process which PID is stored in +pid_file+.
0
-      def send_signal(signal, pid_file)
0
-        if File.exist?(pid_file) && pid = open(pid_file).read
0
+      def send_signal(signal, pid_file, timeout=60)
0
+        if File.file?(pid_file) && pid = open(pid_file).read
0
           pid = pid.to_i
0
           print "Sending #{signal} signal to process #{pid} ... "
0
           Process.kill(signal, pid)
0
+          Timeout.timeout(timeout) do
0
+            sleep 0.1 while Process.running?(pid)
0
+          end
0
           puts
0
-          pid
0
         else
0
           puts "Can't stop process, no PID found in #{pid_file}"
0
-          nil
0
         end
0
+      rescue Timeout::Error
0
+        puts "Timeout! "
0
+        Process.kill("KILL", pid)
0
+      rescue Interrupt
0
+        Process.kill("KILL", pid)
0
       rescue Errno::ESRCH # No such process
0
         puts "process not found!"
0
-        nil
0
-      end
0
+      ensure
0
+        File.delete(pid_file) if File.exist?(pid_file)
0
+      end      
0
     end
0
     
0
     protected
...
102
103
104
 
105
106
107
...
102
103
104
105
106
107
108
0
@@ -102,6 +102,7 @@ module Thin
0
         opts.on("-b", "--backend CLASS", "Backend to use, full classname")              { |name| @options[:backend] = name }
0
         opts.on("-t", "--timeout SEC", "Request or command timeout in sec " +            
0
                                        "(default: #{@options[:timeout]})")              { |sec| @options[:timeout] = sec.to_i }
0
+        opts.on("-f", "--force", "Force the execution of the command")                  { @options[:force] = true }
0
         opts.on(      "--max-conns NUM", "Maximum number of connections " +
0
                                          "(default: #{@options[:max_conns]})",
0
                                          "Might require sudo to set higher then 1024")  { |num| @options[:max_conns] = num.to_i } unless Thin.win?
...
94
95
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
98
99
...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
0
@@ -94,6 +94,23 @@ describe 'Daemonizing' do
0
     File.exist?(@server.pid_file).should be_false
0
   end
0
   
0
+  it 'should force kill process in pid file' do
0
+    @pid = fork do
0
+      @server.daemonize
0
+      loop { sleep 3 }
0
+    end
0
+  
0
+    server_should_start_in_less_then 3
0
+    
0
+    @pid = @server.pid
0
+  
0
+    silence_stream STDOUT do
0
+      TestServer.kill(@server.pid_file, 0)
0
+    end
0
+  
0
+    File.exist?(@server.pid_file).should be_false
0
+  end
0
+  
0
   it 'should send kill signal if timeout' do
0
     @pid = fork do
0
       @server.should_receive(:stop) # pretend we cannot handle the INT signal

Comments