public
Description: A very fast & simple Ruby web server
Homepage: http://code.macournoyer.com/thin/
Clone URL: git://github.com/macournoyer/thin.git
Tail logfile when stoping and restarting a demonized server, fixes #26.
macournoyer (author)
Fri Feb 15 19:38:42 -0800 2008
commit  8f479da3a3c025b10a2b32e6c35fb3aa7da003be
tree    df7806e267c11d2ac8f7df20a40efc14ff4a9ffc
parent  96217b94e12fc1b472299d52359931c10863b698
...
1
 
2
3
4
...
1
2
3
4
5
0
@@ -1,4 +1,5 @@
0
 == 0.7.0 Spherical Cow release
0
+ * Tail logfile when stoping and restarting a demonized server, fixes #26.
0
  * Wrap application in a Rack::CommonLogger adapter in debug mode.
0
  * --debug (-D) option no longer set $DEBUG so logging will be less verbose
0
    and Ruby won't be too strict, fixes #36.
...
 
 
1
2
3
...
22
23
24
25
26
 
 
 
 
 
27
28
29
...
1
2
3
4
5
...
24
25
26
 
 
27
28
29
30
31
32
33
34
0
@@ -1,3 +1,5 @@
0
+require 'open3'
0
+
0
 module Thin
0
   # Run a command though the +thin+ command-line script.
0
   class Command
0
@@ -22,8 +24,11 @@ module Thin
0
     def run
0
       shell_cmd = shellify
0
       trace shell_cmd
0
- ouput = `#{shell_cmd}`.chomp
0
- log " " + ouput.gsub("\n", " \n") unless ouput.empty?
0
+ trap('INT') {} # Ignore INT signal to pass CTRL+C to subprocess
0
+ Open3.popen3(shell_cmd) do |stdin, stdout, stderr|
0
+ log stdout.gets until stdout.eof?
0
+ log stderr.gets until stderr.eof?
0
+ end
0
     end
0
     
0
     # Turn into a runnable shell command
...
70
71
72
73
 
 
 
 
74
75
76
77
78
79
 
 
 
 
80
81
82
...
88
89
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
92
93
94
...
70
71
72
 
73
74
75
76
77
78
79
80
81
 
82
83
84
85
86
87
88
...
94
95
96
97
98
99
100
101
102
103
104
105
106
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
135
136
137
138
139
140
141
142
143
0
@@ -70,13 +70,19 @@ module Thin
0
       def stop
0
         raise OptionRequired, :pid unless @options[:pid]
0
       
0
- Server.kill(@options[:pid], @options[:timeout] || 60)
0
+ tail_log(@options[:log]) do
0
+ Server.kill(@options[:pid], @options[:timeout] || 60)
0
+ wait_for_file :deletion, @options[:pid]
0
+ end
0
       end
0
     
0
       def restart
0
         raise OptionRequired, :pid unless @options[:pid]
0
       
0
- Server.restart(@options[:pid])
0
+ tail_log(@options[:log]) do
0
+ Server.restart(@options[:pid])
0
+ wait_for_file :creation, @options[:pid]
0
+ end
0
       end
0
     
0
       def config
0
@@ -88,6 +94,49 @@ module Thin
0
         File.open(config_file, 'w') { |f| f << @options.to_yaml }
0
         log ">> Wrote configuration to #{config_file}"
0
       end
0
+
0
+ protected
0
+ # Wait for a pid file to either be created or deleted.
0
+ def wait_for_file(state, file)
0
+ case state
0
+ when :creation then sleep 0.1 until File.exist?(file)
0
+ when :deletion then sleep 0.1 while File.exist?(file)
0
+ end
0
+ end
0
+
0
+ # Tail the log file of server +number+ during the execution of the block.
0
+ def tail_log(log_file)
0
+ if log_file
0
+ tail_thread = tail(log_file)
0
+ yield
0
+ tail_thread.kill
0
+ else
0
+ yield
0
+ end
0
+ end
0
+
0
+ # Acts like GNU tail command. Taken from Rails.
0
+ def tail(file)
0
+ tail_thread = Thread.new do
0
+ Thread.pass until File.exist?(file)
0
+ cursor = File.size(file)
0
+ last_checked = Time.now
0
+ File.open(file, 'r') do |f|
0
+ loop do
0
+ f.seek cursor
0
+ if f.mtime > last_checked
0
+ last_checked = f.mtime
0
+ contents = f.read
0
+ cursor += contents.length
0
+ print contents
0
+ STDOUT.flush
0
+ end
0
+ sleep 0.1
0
+ end
0
+ end
0
+ end
0
+ tail_thread
0
+ end
0
     end
0
   end
0
 end
0
\ No newline at end of file
...
99
100
101
102
 
 
 
103
104
105
...
99
100
101
 
102
103
104
105
106
107
0
@@ -99,7 +99,9 @@ module Thin
0
               sleep 0.1 while Process.running?(pid)
0
             end
0
           rescue Timeout::Error
0
- print "timeout! "
0
+ print "Timeout! "
0
+ send_signal('KILL', pid_file)
0
+ rescue Interrupt
0
             send_signal('KILL', pid_file)
0
           end
0
         end
...
62
63
64
 
 
 
 
 
65
66
67
 
68
69
70
71
72
 
73
74
75
...
62
63
64
65
66
67
68
69
70
71
 
72
73
74
75
76
 
77
78
79
80
0
@@ -62,14 +62,19 @@ describe Controller, 'start' do
0
 end
0
 
0
 describe Controller do
0
+ before do
0
+ @controller = Controller.new(:pid => 'thin.pid', :timeout => 10)
0
+ @controller.stub!(:wait_for_file)
0
+ end
0
+
0
   it "should stop" do
0
     Server.should_receive(:kill).with('thin.pid', 10)
0
- Controller.new(:pid => 'thin.pid', :timeout => 10).stop
0
+ @controller.stop
0
   end
0
   
0
   it "should restart" do
0
     Server.should_receive(:restart).with('thin.pid')
0
- Controller.new(:pid => 'thin.pid').restart
0
+ @controller.restart
0
   end
0
   
0
   it "should write configuration file" do
...
36
37
38
39
 
40
41
42
...
36
37
38
 
39
40
41
42
0
@@ -36,7 +36,7 @@ describe Server, 'on TCP socket' do
0
     post('/', :big => big).should include(big)
0
   end
0
   
0
- it "should handle GET in less then #{get_request_time = 0.004} RubySecond" do
0
+ it "should handle GET in less then #{get_request_time = 0.0045} RubySecond" do
0
     proc { get('/') }.should be_faster_then(get_request_time)
0
   end
0
   
...
18
19
20
21
 
22
23
24
...
18
19
20
 
21
22
23
24
0
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
0
   s.add_dependency 'rack', '>= 0.2.0'
0
   s.add_dependency 'eventmachine', '>= 0.8.1'
0
   unless WIN
0
- s.add_dependency 'daemons', '>= 1.0.9'
0
+ s.add_dependency 'daemons', '>= 1.0.9'
0
   end
0
 
0
   s.files = %w(COPYING CHANGELOG README Rakefile) +

Comments

    No one has commented yet.