puma 2.0.0.b5 → 2.0.0.b6

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,14 @@
1
+ === 2.0.0.b6 / 2013-02-06
2
+
3
+ * 2 minor enhancements:
4
+
5
+ * Add hook for running when a worker boots
6
+ * Advertise the Configuration object for apps to use.
7
+
8
+ * 1 bug fix:
9
+
10
+ * Change directory in working during upgrade. Fixes #185
11
+
1
12
  === 2.0.0.b5 / 2013-02-05
2
13
 
3
14
  * 2 major features:
@@ -63,6 +63,7 @@ module Puma
63
63
 
64
64
  if s_env.ino == s_pwd.ino and s_env.dev == s_pwd.dev
65
65
  @restart_dir = dir
66
+ @options[:worker_directory] = dir
66
67
  end
67
68
  end
68
69
 
@@ -171,6 +172,7 @@ module Puma
171
172
  :binds => [],
172
173
  :workers => 0,
173
174
  :daemon => false,
175
+ :worker_boot => [],
174
176
  :environment => "development"
175
177
  }
176
178
 
@@ -208,6 +210,7 @@ module Puma
208
210
 
209
211
  o.on "--dir DIR", "Change to DIR before starting" do |d|
210
212
  @options[:directory] = d.to_s
213
+ @options[:worker_directory] = d.to_s
211
214
  end
212
215
 
213
216
  o.on "-e", "--environment ENVIRONMENT",
@@ -325,6 +328,10 @@ module Puma
325
328
  end
326
329
 
327
330
  @config = Puma::Configuration.new @options
331
+
332
+ # Advertise the Configuration
333
+ Puma.cli_config = @config
334
+
328
335
  @config.load
329
336
  end
330
337
 
@@ -481,7 +488,7 @@ module Puma
481
488
  end
482
489
  end
483
490
 
484
- def worker
491
+ def worker(upgrade)
485
492
  $0 = "puma: cluster worker: #{@master_pid}"
486
493
  Signal.trap "SIGINT", "IGNORE"
487
494
 
@@ -490,10 +497,24 @@ module Puma
490
497
 
491
498
  Thread.new do
492
499
  IO.select [@check_pipe]
493
- log "! Detected parent died, dieing"
500
+ log "! Detected parent died, dying"
494
501
  exit! 1
495
502
  end
496
503
 
504
+ # Be sure to change the directory again before loading
505
+ # the app. This way we can pick up new code.
506
+ if upgrade
507
+ if dir = @options[:worker_directory]
508
+ log "+ Changing to #{dir}"
509
+ Dir.chdir dir
510
+ end
511
+ end
512
+
513
+ # Invoke any worker boot hooks so they can get
514
+ # things in shape before booting the app.
515
+ hooks = @options[:worker_boot]
516
+ hooks.each { |h| h.call }
517
+
497
518
  min_t = @options[:min_threads]
498
519
  max_t = @options[:max_threads]
499
520
 
@@ -560,8 +581,10 @@ module Puma
560
581
  def spawn_workers
561
582
  diff = @options[:workers] - @workers.size
562
583
 
584
+ upgrade = (@phased_state == :waiting)
585
+
563
586
  diff.times do
564
- pid = fork { worker }
587
+ pid = fork { worker(upgrade) }
565
588
  debug "Spawned worker: #{pid}"
566
589
  @workers << Worker.new(pid, @phase)
567
590
  end
@@ -680,7 +703,7 @@ module Puma
680
703
 
681
704
  if req == "b"
682
705
  pid = read.gets.to_i
683
- w = @workers.find { |w| w.pid == pid }
706
+ w = @workers.find { |x| x.pid == pid }
684
707
  if w
685
708
  w.boot!
686
709
  log "- Worker #{pid} booted, phase: #{w.phase}"
@@ -1,4 +1,14 @@
1
1
  module Puma
2
+
3
+ # The CLI exports it's Configuration object here to allow
4
+ # apps to pick it up. An app needs to use it conditionally though
5
+ # since it is not set if the app is launched via another
6
+ # mechanism than the CLI class.
7
+
8
+ class << self
9
+ attr_accessor :cli_config
10
+ end
11
+
2
12
  class Configuration
3
13
  DefaultRackup = "config.ru"
4
14
 
@@ -44,26 +54,39 @@ module Puma
44
54
  end
45
55
  end
46
56
 
57
+ # Injects the Configuration object into the env
58
+ class ConfigMiddleware
59
+ def initialize(config, app)
60
+ @config = config
61
+ @app = app
62
+ end
63
+
64
+ def call(env)
65
+ env[Const::PUMA_CONFIG] = @config
66
+ @app.call(env)
67
+ end
68
+ end
69
+
47
70
  # Load the specified rackup file, pull an options from
48
71
  # the rackup file, and set @app.
49
72
  #
50
73
  def app
51
- if app = @options[:app]
52
- return app
53
- end
74
+ app = @options[:app]
54
75
 
55
- path = @options[:rackup] || DefaultRackup
76
+ unless app
77
+ path = @options[:rackup] || DefaultRackup
56
78
 
57
- unless File.exists?(path)
58
- raise "Missing rackup file '#{path}'"
59
- end
79
+ unless File.exists?(path)
80
+ raise "Missing rackup file '#{path}'"
81
+ end
60
82
 
61
- app, options = Rack::Builder.parse_file path
62
- @options.merge! options
83
+ app, options = Rack::Builder.parse_file path
84
+ @options.merge! options
63
85
 
64
- options.each do |key,val|
65
- if key.to_s[0,4] == "bind"
66
- @options[:binds] << val
86
+ options.each do |key,val|
87
+ if key.to_s[0,4] == "bind"
88
+ @options[:binds] << val
89
+ end
67
90
  end
68
91
  end
69
92
 
@@ -72,7 +95,7 @@ module Puma
72
95
  app = Rack::CommonLogger.new(app, logger)
73
96
  end
74
97
 
75
- return app
98
+ return ConfigMiddleware.new(self, app)
76
99
  end
77
100
 
78
101
  def setup_random_token
@@ -242,6 +265,15 @@ module Puma
242
265
  @options[:workers] = count.to_i
243
266
  end
244
267
 
268
+ # *Cluster mode only* Code to run when a worker boots to setup
269
+ # the process before booting the app.
270
+ #
271
+ # This can be called multiple times to add hooks.
272
+ #
273
+ def on_worker_boot(&block)
274
+ @options[:worker_boot] << block
275
+ end
276
+
245
277
  # The directory to operate out of.
246
278
  def directory(dir)
247
279
  @options[:directory] = dir.to_s
@@ -28,7 +28,7 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.0.0.b5".freeze
31
+ PUMA_VERSION = VERSION = "2.0.0.b6".freeze
32
32
 
33
33
  FAST_TRACK_KA_TIMEOUT = 0.2
34
34
 
@@ -119,6 +119,7 @@ module Puma
119
119
  RACK_URL_SCHEME = "rack.url_scheme".freeze
120
120
  RACK_AFTER_REPLY = "rack.after_reply".freeze
121
121
  PUMA_SOCKET = "puma.socket".freeze
122
+ PUMA_CONFIG = "puma.config".freeze
122
123
 
123
124
  HTTP = "http".freeze
124
125
  HTTPS = "https".freeze
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "puma"
5
- s.version = "2.0.0.b5"
5
+ s.version = "2.0.0.b6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Phoenix"]
9
- s.date = "2013-02-06"
9
+ s.date = "2013-02-07"
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"]
@@ -11,6 +11,6 @@ class TestConfigFile < Test::Unit::TestCase
11
11
 
12
12
  app = conf.app
13
13
 
14
- assert_equal [200, {}, ["embedded app"]], app.call(nil)
14
+ assert_equal [200, {}, ["embedded app"]], app.call({})
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.b5
4
+ version: 2.0.0.b6
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-06 00:00:00.000000000 Z
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack