puma 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

@@ -1,3 +1,9 @@
1
+ === 1.6.3 / 2012-09-04
2
+
3
+ * 1 bug fix:
4
+ * Close sockets waiting in the reactor when a hot restart is performed
5
+ so that browsers reconnect on the next request
6
+
1
7
  === 1.6.2 / 2012-08-27
2
8
 
3
9
  * 1 bug fix:
@@ -325,12 +325,13 @@ module Puma
325
325
 
326
326
  @listeners << [str, io]
327
327
  when "unix"
328
+ path = "#{uri.host}#{uri.path}"
329
+
328
330
  if fd = @inherited_fds.delete(str)
329
331
  log "* Inherited #{str}"
330
- io = server.inherit_unix_listener uri.path, fd
332
+ io = server.inherit_unix_listener path, fd
331
333
  else
332
334
  log "* Listening on #{str}"
333
- path = "#{uri.host}#{uri.path}"
334
335
 
335
336
  umask = nil
336
337
 
@@ -25,7 +25,7 @@ module Puma
25
25
  # too taxing on performance.
26
26
  module Const
27
27
 
28
- PUMA_VERSION = VERSION = "1.6.2".freeze
28
+ PUMA_VERSION = VERSION = "1.6.3".freeze
29
29
 
30
30
  # The default number of seconds for another request within a persistent
31
31
  # session.
@@ -16,6 +16,9 @@ module Puma
16
16
  def initialize(stdout, stderr)
17
17
  @stdout = stdout
18
18
  @stderr = stderr
19
+
20
+ @stdout.sync = true
21
+ @stderr.sync = true
19
22
  end
20
23
 
21
24
  attr_reader :stdout, :stderr
@@ -30,6 +30,15 @@ module Puma
30
30
  when "*"
31
31
  sockets += @input
32
32
  @input.clear
33
+ when "c"
34
+ sockets.delete_if do |s|
35
+ if s == @ready
36
+ false
37
+ else
38
+ s.close
39
+ true
40
+ end
41
+ end
33
42
  when "!"
34
43
  return
35
44
  end
@@ -121,8 +130,14 @@ module Puma
121
130
  end
122
131
  end
123
132
 
133
+ # Close all watched sockets and clear them from being watched
134
+ def clear!
135
+ @trigger << "c"
136
+ end
137
+
124
138
  def shutdown
125
139
  @trigger << "!"
140
+ @thread.join
126
141
  end
127
142
  end
128
143
  end
@@ -261,6 +261,8 @@ module Puma
261
261
  end
262
262
  end
263
263
 
264
+ @reactor.clear! if @status == :restart
265
+
264
266
  @reactor.shutdown
265
267
  graceful_shutdown if @status == :stop
266
268
  ensure
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "puma"
5
- s.version = "1.6.2"
5
+ s.version = "1.6.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Phoenix"]
9
- s.date = "2012-08-27"
9
+ s.date = "2012-09-04"
10
10
  s.description = "Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications. It can be used with any application that supports Rack, and is considered the replacement for Webrick and Mongrel. It was designed to be the go-to server for [Rubinius](http://rubini.us), but also works well with JRuby and MRI. Puma is intended for use in both development and production environments.\n\nUnder the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool (which you can control). This allows Puma to provide real concurrency for your web application!\n\nWith Rubinius 2.0, Puma will utilize all cores on your CPU with real threads, meaning you won't have to spawn multiple processes to increase throughput. You can expect to see a similar benefit from JRuby.\n\nOn MRI, there is a Global Interpreter Lock (GIL) that ensures only one thread can be run at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently (EventMachine-based servers such as Thin turn off this ability, requiring you to use special libraries). Your mileage may vary. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like [Rubinius](http://rubini.us) or [JRuby](http://jruby.org)."
11
11
  s.email = ["evan@phx.io"]
12
12
  s.executables = ["puma", "pumactl"]
@@ -1,6 +1,8 @@
1
1
  require "rbconfig"
2
2
  require 'test/unit'
3
3
  require 'socket'
4
+ require 'timeout'
5
+ require 'net/http'
4
6
 
5
7
  require 'puma/cli'
6
8
  require 'puma/control_cli'
@@ -10,12 +12,34 @@ class TestIntegration < Test::Unit::TestCase
10
12
  @state_path = "test/test_puma.state"
11
13
  @bind_path = "test/test_server.sock"
12
14
  @control_path = "test/test_control.sock"
15
+ @tcp_port = 9998
16
+
17
+ @server = nil
13
18
  end
14
19
 
15
20
  def teardown
16
21
  File.unlink @state_path rescue nil
17
22
  File.unlink @bind_path rescue nil
18
23
  File.unlink @control_path rescue nil
24
+
25
+ if @server
26
+ Process.kill "INT", @server.pid
27
+ Process.wait @server.pid
28
+ @server.close
29
+ end
30
+ end
31
+
32
+ def server(opts)
33
+ core = "#{Gem.ruby} -rubygems -Ilib bin/puma"
34
+ cmd = "#{core} --restart-cmd '#{core}' -b tcp://127.0.0.1:#{@tcp_port} #{opts}"
35
+ @server = IO.popen(cmd, "r")
36
+
37
+ sleep 1
38
+ @server
39
+ end
40
+
41
+ def signal(which)
42
+ Process.kill which, @server.pid
19
43
  end
20
44
 
21
45
  def test_stop_via_pumactl
@@ -45,4 +69,29 @@ class TestIntegration < Test::Unit::TestCase
45
69
 
46
70
  assert_kind_of Thread, t.join(1), "server didn't stop"
47
71
  end
72
+
73
+ def test_restart_closes_keepalive_sockets
74
+ server("-q test/hello.ru")
75
+
76
+ s = TCPSocket.new "localhost", @tcp_port
77
+ s << "GET / HTTP/1.1\r\n\r\n"
78
+ true until s.gets == "\r\n"
79
+
80
+ s.readpartial(20)
81
+ signal :USR2
82
+
83
+ sleep 3
84
+
85
+ s.write "GET / HTTP/1.1\r\n\r\n"
86
+
87
+ assert_raises Errno::ECONNRESET do
88
+ Timeout.timeout(2) do
89
+ s.read(2)
90
+ end
91
+ end
92
+
93
+ s = TCPSocket.new "localhost", @tcp_port
94
+ s << "GET / HTTP/1.0\r\n\r\n"
95
+ assert_equal "Hello World", s.read.split("\r\n").last
96
+ end
48
97
  end
metadata CHANGED
@@ -1,102 +1,116 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: puma
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.3
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 6
9
- - 2
10
- version: 1.6.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Evan Phoenix
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-08-27 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rack
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 11
29
- segments:
30
- - 1
31
- - 2
32
- version: "1.2"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.2'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: rdoc
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
39
25
  none: false
40
- requirements:
26
+ requirements:
41
27
  - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 19
44
- segments:
45
- - 3
46
- - 10
47
- version: "3.10"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rdoc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.10'
48
38
  type: :development
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: rake-compiler
52
39
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
54
41
  none: false
55
- requirements:
42
+ requirements:
56
43
  - - ~>
57
- - !ruby/object:Gem::Version
58
- hash: 63
59
- segments:
60
- - 0
61
- - 8
62
- - 0
44
+ - !ruby/object:Gem::Version
45
+ version: '3.10'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake-compiler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
63
53
  version: 0.8.0
64
54
  type: :development
65
- version_requirements: *id003
66
- - !ruby/object:Gem::Dependency
67
- name: hoe
68
55
  prerelease: false
69
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: hoe
64
+ requirement: !ruby/object:Gem::Requirement
70
65
  none: false
71
- requirements:
66
+ requirements:
72
67
  - - ~>
73
- - !ruby/object:Gem::Version
74
- hash: 7
75
- segments:
76
- - 3
77
- - 0
78
- version: "3.0"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
79
70
  type: :development
80
- version_requirements: *id004
81
- description: |-
82
- Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications. It can be used with any application that supports Rack, and is considered the replacement for Webrick and Mongrel. It was designed to be the go-to server for [Rubinius](http://rubini.us), but also works well with JRuby and MRI. Puma is intended for use in both development and production environments.
83
-
84
- Under the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool (which you can control). This allows Puma to provide real concurrency for your web application!
85
-
86
- With Rubinius 2.0, Puma will utilize all cores on your CPU with real threads, meaning you won't have to spawn multiple processes to increase throughput. You can expect to see a similar benefit from JRuby.
87
-
88
- On MRI, there is a Global Interpreter Lock (GIL) that ensures only one thread can be run at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently (EventMachine-based servers such as Thin turn off this ability, requiring you to use special libraries). Your mileage may vary. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like [Rubinius](http://rubini.us) or [JRuby](http://jruby.org).
89
- email:
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
78
+ description: ! 'Puma is a simple, fast, and highly concurrent HTTP 1.1 server for
79
+ Ruby web applications. It can be used with any application that supports Rack, and
80
+ is considered the replacement for Webrick and Mongrel. It was designed to be the
81
+ go-to server for [Rubinius](http://rubini.us), but also works well with JRuby and
82
+ MRI. Puma is intended for use in both development and production environments.
83
+
84
+
85
+ Under the hood, Puma processes requests using a C-optimized Ragel extension (inherited
86
+ from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable
87
+ way. Puma then serves the request in a thread from an internal thread pool (which
88
+ you can control). This allows Puma to provide real concurrency for your web application!
89
+
90
+
91
+ With Rubinius 2.0, Puma will utilize all cores on your CPU with real threads, meaning
92
+ you won''t have to spawn multiple processes to increase throughput. You can expect
93
+ to see a similar benefit from JRuby.
94
+
95
+
96
+ On MRI, there is a Global Interpreter Lock (GIL) that ensures only one thread can
97
+ be run at a time. But if you''re doing a lot of blocking IO (such as HTTP calls
98
+ to external APIs like Twitter), Puma still improves MRI''s throughput by allowing
99
+ blocking IO to be run concurrently (EventMachine-based servers such as Thin turn
100
+ off this ability, requiring you to use special libraries). Your mileage may vary.
101
+ In order to get the best throughput, it is highly recommended that you use a Ruby
102
+ implementation with real threads like [Rubinius](http://rubini.us) or [JRuby](http://jruby.org).'
103
+ email:
90
104
  - evan@phx.io
91
- executables:
105
+ executables:
92
106
  - puma
93
107
  - pumactl
94
- extensions:
108
+ extensions:
95
109
  - ext/puma_http11/extconf.rb
96
- extra_rdoc_files:
110
+ extra_rdoc_files:
97
111
  - History.txt
98
112
  - Manifest.txt
99
- files:
113
+ files:
100
114
  - COPYING
101
115
  - Gemfile
102
116
  - Gemfile.lock
@@ -172,41 +186,32 @@ files:
172
186
  - tools/trickletest.rb
173
187
  homepage: http://puma.io
174
188
  licenses: []
175
-
176
189
  post_install_message:
177
- rdoc_options:
190
+ rdoc_options:
178
191
  - --main
179
192
  - README.md
180
- require_paths:
193
+ require_paths:
181
194
  - lib
182
- required_ruby_version: !ruby/object:Gem::Requirement
195
+ required_ruby_version: !ruby/object:Gem::Requirement
183
196
  none: false
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- hash: 57
188
- segments:
189
- - 1
190
- - 8
191
- - 7
197
+ requirements:
198
+ - - ! '>='
199
+ - !ruby/object:Gem::Version
192
200
  version: 1.8.7
193
- required_rubygems_version: !ruby/object:Gem::Requirement
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
202
  none: false
195
- requirements:
196
- - - ">="
197
- - !ruby/object:Gem::Version
198
- hash: 3
199
- segments:
200
- - 0
201
- version: "0"
203
+ requirements:
204
+ - - ! '>='
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
202
207
  requirements: []
203
-
204
208
  rubyforge_project: puma
205
209
  rubygems_version: 1.8.24
206
210
  signing_key:
207
211
  specification_version: 3
208
- summary: Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications
209
- test_files:
212
+ summary: Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web
213
+ applications
214
+ test_files:
210
215
  - test/test_app_status.rb
211
216
  - test/test_cli.rb
212
217
  - test/test_config.rb