thin 0.6.1-x86-mswin32-60 → 0.6.2-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of thin might be problematic. Click here for more details.
- data/CHANGELOG +24 -0
- data/benchmark/simple.rb +4 -3
- data/benchmark/utils.rb +1 -1
- data/bin/thin +24 -16
- data/example/adapter.rb +25 -7
- data/example/monit_sockets +20 -0
- data/example/monit_unixsock +20 -0
- data/lib/thin.rb +1 -0
- data/lib/thin/cluster.rb +13 -23
- data/lib/thin/command.rb +40 -0
- data/lib/thin/connection.rb +12 -7
- data/lib/thin/daemonizing.rb +47 -20
- data/lib/thin/headers.rb +4 -1
- data/lib/thin/logging.rb +1 -0
- data/lib/thin/request.rb +21 -14
- data/lib/thin/response.rb +30 -7
- data/lib/thin/server.rb +48 -22
- data/lib/thin/stats.rb +258 -19
- data/lib/thin/version.rb +14 -2
- data/lib/thin_parser.so +0 -0
- data/spec/cluster_spec.rb +66 -38
- data/spec/command_spec.rb +15 -0
- data/spec/daemonizing_spec.rb +3 -0
- data/spec/request_spec.rb +13 -3
- data/spec/response_spec.rb +2 -2
- data/spec/server_spec.rb +44 -10
- data/tasks/gem.rake +2 -8
- metadata +6 -2
data/lib/thin/version.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
module Thin
|
2
|
+
# Raised when a feature is not supported on the
|
3
|
+
# current platform.
|
4
|
+
class PlatformNotSupported < RuntimeError; end
|
5
|
+
|
2
6
|
module VERSION #:nodoc:
|
3
7
|
MAJOR = 0
|
4
8
|
MINOR = 6
|
5
|
-
TINY =
|
9
|
+
TINY = 2
|
6
10
|
|
7
11
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
12
|
|
9
|
-
CODENAME = '
|
13
|
+
CODENAME = 'Rambo'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.win?
|
17
|
+
RUBY_PLATFORM =~ /mswin/
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.ruby_18?
|
21
|
+
RUBY_VERSION =~ /^1\.8/
|
10
22
|
end
|
11
23
|
end
|
data/lib/thin_parser.so
CHANGED
Binary file
|
data/spec/cluster_spec.rb
CHANGED
@@ -26,36 +26,27 @@ describe Cluster, "with host and port" do
|
|
26
26
|
end
|
27
27
|
calls.should == [3000, 3001, 3002]
|
28
28
|
end
|
29
|
-
|
30
|
-
it 'should
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should absolutize file path' do
|
37
|
-
@cluster.pid_file_for(3000).should == File.expand_path(File.dirname(__FILE__) + "/rails_app/thin.3000.pid")
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should start on specified port' do
|
41
|
-
@cluster.should_receive(:`) do |with|
|
42
|
-
with.should include('thin start', '--daemonize', 'thin.3001.log', 'thin.3001.pid', '--port=3001')
|
43
|
-
with.should_not include('--socket')
|
44
|
-
''
|
45
|
-
end
|
29
|
+
|
30
|
+
it 'should start on each port' do
|
31
|
+
Command.should_receive(:run).with(:start, options_for_port(3000))
|
32
|
+
Command.should_receive(:run).with(:start, options_for_port(3001))
|
33
|
+
Command.should_receive(:run).with(:start, options_for_port(3002))
|
46
34
|
|
47
|
-
@cluster.
|
35
|
+
@cluster.start
|
48
36
|
end
|
49
37
|
|
50
|
-
it 'should stop on
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
''
|
55
|
-
end
|
38
|
+
it 'should stop on each port' do
|
39
|
+
Command.should_receive(:run).with(:stop, options_for_port(3000))
|
40
|
+
Command.should_receive(:run).with(:stop, options_for_port(3001))
|
41
|
+
Command.should_receive(:run).with(:stop, options_for_port(3002))
|
56
42
|
|
57
|
-
@cluster.
|
43
|
+
@cluster.stop
|
58
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def options_for_port(port)
|
48
|
+
{ :daemonize => true, :log => "thin.#{port}.log", :timeout => 10, :address => "0.0.0.0", :port => port, :pid => "thin.#{port}.pid", :chdir => "./spec/rails_app" }
|
49
|
+
end
|
59
50
|
end
|
60
51
|
|
61
52
|
describe Cluster, "with UNIX socket" do
|
@@ -86,23 +77,60 @@ describe Cluster, "with UNIX socket" do
|
|
86
77
|
calls.should == [0, 1, 2]
|
87
78
|
end
|
88
79
|
|
89
|
-
it 'should start
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
''
|
94
|
-
end
|
80
|
+
it 'should start each server' do
|
81
|
+
Command.should_receive(:run).with(:start, options_for_socket(0))
|
82
|
+
Command.should_receive(:run).with(:start, options_for_socket(1))
|
83
|
+
Command.should_receive(:run).with(:start, options_for_socket(2))
|
95
84
|
|
96
|
-
@cluster.
|
85
|
+
@cluster.start
|
97
86
|
end
|
98
87
|
|
99
|
-
it 'should stop
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
it 'should stop each server' do
|
89
|
+
Command.should_receive(:run).with(:stop, options_for_socket(0))
|
90
|
+
Command.should_receive(:run).with(:stop, options_for_socket(1))
|
91
|
+
Command.should_receive(:run).with(:stop, options_for_socket(2))
|
92
|
+
|
93
|
+
@cluster.stop
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
private
|
98
|
+
def options_for_socket(number)
|
99
|
+
{ :daemonize => true, :log => "thin.#{number}.log", :timeout => 10, :socket => "/tmp/thin.#{number}.sock", :pid => "thin.#{number}.pid", :chdir => "./spec/rails_app" }
|
104
100
|
end
|
101
|
+
end
|
105
102
|
|
106
|
-
|
103
|
+
describe Cluster, "controlling only one server" do
|
104
|
+
before do
|
105
|
+
@cluster = Cluster.new(:chdir => File.dirname(__FILE__) + '/rails_app',
|
106
|
+
:address => '0.0.0.0',
|
107
|
+
:port => 3000,
|
108
|
+
:servers => 3,
|
109
|
+
:timeout => 10,
|
110
|
+
:log => 'thin.log',
|
111
|
+
:pid => 'thin.pid',
|
112
|
+
:only => 3001
|
113
|
+
)
|
114
|
+
@cluster.script = File.dirname(__FILE__) + '/../bin/thin'
|
115
|
+
@cluster.silent = true
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should call only specified server' do
|
119
|
+
calls = []
|
120
|
+
@cluster.send(:with_each_server) do |n|
|
121
|
+
calls << n
|
122
|
+
end
|
123
|
+
calls.should == [3001]
|
107
124
|
end
|
125
|
+
|
126
|
+
it "should start only specified server" do
|
127
|
+
Command.should_receive(:run).with(:start, options_for_port(3001))
|
128
|
+
|
129
|
+
@cluster.start
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
def options_for_port(port)
|
134
|
+
{ :daemonize => true, :log => "thin.#{port}.log", :timeout => 10, :address => "0.0.0.0", :port => port, :pid => "thin.#{port}.pid", :chdir => "./spec/rails_app" }
|
135
|
+
end
|
108
136
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Command do
|
4
|
+
before do
|
5
|
+
@command = Command.new(:start, :port => 3000, :daemonize => true, :log => 'hi.log', :pid => nil)
|
6
|
+
@command.script = File.dirname(__FILE__) + '/../bin/thin'
|
7
|
+
@command.silent = true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should shellify command' do
|
11
|
+
out = @command.shellify
|
12
|
+
out.should include('--port=3000', '--daemonize', '--log="hi.log"', 'thin start --')
|
13
|
+
out.should_not include('--pid=')
|
14
|
+
end
|
15
|
+
end
|
data/spec/daemonizing_spec.rb
CHANGED
@@ -19,6 +19,7 @@ describe 'Daemonizing' do
|
|
19
19
|
sleep 1
|
20
20
|
end
|
21
21
|
|
22
|
+
sleep 1
|
22
23
|
Process.wait(@pid)
|
23
24
|
File.exist?(@server.pid_file).should be_true
|
24
25
|
@pid = @server.pid
|
@@ -87,6 +88,8 @@ describe 'Daemonizing' do
|
|
87
88
|
Process.running?(@pid).should be_false
|
88
89
|
end
|
89
90
|
|
91
|
+
it "should restart"
|
92
|
+
|
90
93
|
after do
|
91
94
|
Process.kill(9, @pid.to_i) if @pid && Process.running?(@pid.to_i)
|
92
95
|
Process.kill(9, @server.pid) if @server.pid && Process.running?(@server.pid)
|
data/spec/request_spec.rb
CHANGED
@@ -190,18 +190,28 @@ EOS
|
|
190
190
|
end
|
191
191
|
|
192
192
|
it "should move body to tempfile when too big" do
|
193
|
+
request = Request.new
|
194
|
+
request.parse("POST /postit HTTP/1.1\r\nContent-Length: #{Request::MAX_BODY*2}\r\n\r\n#{'X' * Request::MAX_BODY}")
|
195
|
+
request.parse('X' * Request::MAX_BODY)
|
196
|
+
|
197
|
+
request.body.size.should == Request::MAX_BODY * 2
|
198
|
+
request.should be_finished
|
199
|
+
request.body.class.should == Tempfile
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should delete body tempfile when closing" do
|
193
203
|
body = 'X' * (Request::MAX_BODY + 1)
|
194
204
|
|
195
205
|
request = R(<<-EOS.chomp, true)
|
196
206
|
POST /postit HTTP/1.1
|
197
|
-
Host: localhost:3000
|
198
|
-
Content-Type: text/html
|
199
207
|
Content-Length: #{body.size}
|
200
208
|
|
201
209
|
#{body}
|
202
210
|
EOS
|
203
211
|
|
204
|
-
request.body.
|
212
|
+
request.body.path.should_not be_nil
|
213
|
+
request.close
|
214
|
+
request.body.path.should be_nil
|
205
215
|
end
|
206
216
|
|
207
217
|
it "should raise error when header is too big" do
|
data/spec/response_spec.rb
CHANGED
@@ -52,7 +52,7 @@ describe Response do
|
|
52
52
|
out.should include("\r\n\r\n<html></html>")
|
53
53
|
end
|
54
54
|
|
55
|
-
it "should be
|
55
|
+
it "should be fast" do
|
56
56
|
@response.body << <<-EOS
|
57
57
|
<html><head><title>Dir listing</title></head>
|
58
58
|
<body><h1>Listing stuff</h1><ul>
|
@@ -60,7 +60,7 @@ describe Response do
|
|
60
60
|
</ul></body></html>
|
61
61
|
EOS
|
62
62
|
|
63
|
-
proc { @response.each { |l| l } }.should be_faster_then(
|
63
|
+
proc { @response.each { |l| l } }.should be_faster_then(0.00011)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should be closeable" do
|
data/spec/server_spec.rb
CHANGED
@@ -10,11 +10,11 @@ describe Server do
|
|
10
10
|
body << env['rack.input'].read
|
11
11
|
[200, { 'Content-Type' => 'text/html', 'Content-Length' => body.size.to_s }, body]
|
12
12
|
end
|
13
|
-
server = Thin::Server.new('0.0.0.0', 3333, app)
|
14
|
-
server.timeout = 3
|
15
|
-
server.silent = true
|
13
|
+
@server = Thin::Server.new('0.0.0.0', 3333, app)
|
14
|
+
@server.timeout = 3
|
15
|
+
@server.silent = true
|
16
16
|
|
17
|
-
@thread = Thread.new { server.start }
|
17
|
+
@thread = Thread.new { @server.start }
|
18
18
|
sleep 0.1 until @thread.status == 'sleep'
|
19
19
|
end
|
20
20
|
|
@@ -23,18 +23,18 @@ describe Server do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should GET from TCPSocket' do
|
26
|
-
raw(
|
26
|
+
raw("GET /?this HTTP/1.1\r\n\r\n").
|
27
27
|
should include("HTTP/1.1 200 OK",
|
28
28
|
"Content-Type: text/html", "Content-Length: ",
|
29
29
|
"Connection: close", "this")
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should return empty string on incomplete headers' do
|
33
|
-
raw(
|
33
|
+
raw("GET /?this HTTP/1.1\r\nHost:").should be_empty
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should return empty string on incorrect Content-Length' do
|
37
|
-
raw(
|
37
|
+
raw("POST / HTTP/1.1\r\nContent-Length: 300\r\n\r\naye").should be_empty
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'should POST from Net::HTTP' do
|
@@ -58,7 +58,40 @@ describe Server do
|
|
58
58
|
get('/').should include('"REMOTE_ADDR"=>"127.0.0.1"')
|
59
59
|
end
|
60
60
|
|
61
|
+
it "should wait for current requests before soft stopping" do
|
62
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
63
|
+
socket.write("GET / HTTP/1.1")
|
64
|
+
@server.stop # Stop the server in the middle of a request
|
65
|
+
socket.write("\r\n\r\n")
|
66
|
+
|
67
|
+
out = socket.read
|
68
|
+
socket.close
|
69
|
+
|
70
|
+
out.should_not be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not accept new requests when soft stopping" do
|
74
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
75
|
+
socket.write("GET / HTTP/1.1")
|
76
|
+
@server.stop # Stop the server in the middle of a request
|
77
|
+
|
78
|
+
EventMachine.next_tick do
|
79
|
+
proc { get('/') }.should raise_error(Errno::ECONNRESET)
|
80
|
+
end
|
81
|
+
|
82
|
+
socket.close
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should drop current requests when hard stopping" do
|
86
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
87
|
+
socket.write("GET / HTTP/1.1")
|
88
|
+
@server.stop! # Force stop the server in the middle of a request
|
89
|
+
|
90
|
+
EventMachine.next_tick { socket.should be_closed }
|
91
|
+
end
|
92
|
+
|
61
93
|
after do
|
94
|
+
@server.stop!
|
62
95
|
@thread.kill
|
63
96
|
end
|
64
97
|
|
@@ -67,8 +100,8 @@ describe Server do
|
|
67
100
|
Net::HTTP.get(URI.parse('http://0.0.0.0:3333' + url))
|
68
101
|
end
|
69
102
|
|
70
|
-
def raw(
|
71
|
-
socket = TCPSocket.new(
|
103
|
+
def raw(data)
|
104
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
72
105
|
socket.write data
|
73
106
|
out = socket.read
|
74
107
|
socket.close
|
@@ -143,11 +176,12 @@ describe Server, "on UNIX domain socket" do
|
|
143
176
|
end
|
144
177
|
|
145
178
|
it "should remove socket file after server stops" do
|
146
|
-
@server.stop
|
179
|
+
@server.stop!
|
147
180
|
File.exist?('/tmp/thin_test.sock').should be_false
|
148
181
|
end
|
149
182
|
|
150
183
|
after do
|
184
|
+
@server.stop!
|
151
185
|
@thread.kill
|
152
186
|
end
|
153
187
|
|
data/tasks/gem.rake
CHANGED
@@ -67,17 +67,11 @@ namespace :gem do
|
|
67
67
|
system 'ssh macournoyer@macournoyer.com "cd code.macournoyer.com && gem generate_index"'
|
68
68
|
end
|
69
69
|
|
70
|
-
desc 'Upload
|
70
|
+
desc 'Upload gems (ruby & win32) to rubyforge.org'
|
71
71
|
task :rubyforge => :gem do
|
72
72
|
sh 'rubyforge login'
|
73
73
|
sh "rubyforge add_release thin thin #{Thin::VERSION::STRING} pkg/#{spec.full_name}.gem"
|
74
|
-
sh "rubyforge add_file thin thin #{Thin::VERSION::STRING} pkg/#{spec.full_name}.gem"
|
75
|
-
end
|
76
|
-
|
77
|
-
desc 'Upload the precompiled win32 gem to rubyforge.org'
|
78
|
-
task 'rubyforge:win' do
|
79
|
-
sh 'rubyforge login'
|
80
|
-
sh "rubyforge add_release thin thin #{Thin::VERSION::STRING} pkg/#{spec.full_name}-x86-mswin32-60.gem"
|
74
|
+
sh "rubyforge add_file thin thin #{Thin::VERSION::STRING} pkg/#{spec.full_name}.gem"
|
81
75
|
sh "rubyforge add_file thin thin #{Thin::VERSION::STRING} pkg/#{spec.full_name}-x86-mswin32-60.gem"
|
82
76
|
end
|
83
77
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: x86-mswin32-60
|
6
6
|
authors:
|
7
7
|
- Marc-Andre Cournoyer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-01-
|
12
|
+
date: 2008-01-30 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -50,6 +50,8 @@ files:
|
|
50
50
|
- doc/benchmarks.txt
|
51
51
|
- example/adapter.rb
|
52
52
|
- example/config.ru
|
53
|
+
- example/monit_sockets
|
54
|
+
- example/monit_unixsock
|
53
55
|
- example/thin.god
|
54
56
|
- lib/rack
|
55
57
|
- lib/rack/adapter
|
@@ -58,6 +60,7 @@ files:
|
|
58
60
|
- lib/rack/handler/thin.rb
|
59
61
|
- lib/thin
|
60
62
|
- lib/thin/cluster.rb
|
63
|
+
- lib/thin/command.rb
|
61
64
|
- lib/thin/connection.rb
|
62
65
|
- lib/thin/daemonizing.rb
|
63
66
|
- lib/thin/headers.rb
|
@@ -70,6 +73,7 @@ files:
|
|
70
73
|
- lib/thin/version.rb
|
71
74
|
- lib/thin.rb
|
72
75
|
- spec/cluster_spec.rb
|
76
|
+
- spec/command_spec.rb
|
73
77
|
- spec/daemonizing_spec.rb
|
74
78
|
- spec/headers_spec.rb
|
75
79
|
- spec/rack_rails_spec.rb
|