mongrel2 0.32.0 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,8 +1,44 @@
1
+ 2012-09-21 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * spec/lib/helpers.rb:
4
+ Use Loggability's spec helpers
5
+ [36f9259ea9aa] [tip]
6
+
7
+ * lib/mongrel2/request.rb:
8
+ Don't log the whole damn request in debugging
9
+ [6767558cf718]
10
+
11
+ 2012-09-18 Michael Granger <ged@FaerieMUD.org>
12
+
13
+ * .hgtags:
14
+ Added tag v0.32.0 for changeset 784babdfb85c
15
+ [d7f1ccc8c130]
16
+
17
+ * .hgsigs:
18
+ Added signature for changeset ebfb060e8c65
19
+ [784babdfb85c] [v0.32.0]
20
+
21
+ * History.rdoc, lib/mongrel2.rb:
22
+ Bump the minor version, update history.
23
+ [ebfb060e8c65]
24
+
25
+ * .hgignore:
26
+ Ignore foreman settings files
27
+ [16b910708f91]
28
+
29
+ * bin/m2sh.rb:
30
+ Add a settings command for showing "expert" settings
31
+ [09884906b249]
32
+
33
+ * .rvm.gems, Rakefile:
34
+ Updating dependencies
35
+ [7a901c95b004]
36
+
1
37
  2012-08-20 Michael Granger <ged@FaerieMUD.org>
2
38
 
3
39
  * .hgtags:
4
40
  Added tag v0.31.1 for changeset 54464cda5795
5
- [933a499629d1] [tip]
41
+ [933a499629d1]
6
42
 
7
43
  * .hgsigs:
8
44
  Added signature for changeset a66bb80de490
data/History.rdoc CHANGED
@@ -1,3 +1,10 @@
1
+ == v0.33.0 [2012-10-02] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Implement deferred signal-handling for Mongrel2::Handler
4
+ - Update the examples/
5
+ - Squelch some of the noisier debug logging
6
+
7
+
1
8
  == v0.32.0 [2012-09-18] Michael Granger <ged@FaerieMUD.org>
2
9
 
3
10
  - Add a settings command for showing "expert" settings to m2sh.rb.
@@ -18,14 +18,16 @@
18
18
  <li><a href="/hello">Hello World</a> (<a href="/source/helloworld-handler.rb">source</a>) </li>
19
19
  <li><a href="/async-upload">Async Upload Demo</a>
20
20
  (<a href="/source/async-upload.rb">source</a>) </li>
21
- <li><a href="/dump">Dump Request</a> (<a href="/source/request-dumper.rb">source</a>) </li>
22
- <li><a href="/websock-test.html">Web Socket Test</a></li>
21
+ <li><a href="/dump">Dump Request</a>
22
+ (<a href="/source/request-dumper.rb">source</a>) </li>
23
+ <li><a href="/websock-test.html">Web Socket Test</a>
24
+ (<a href="/source/ws-echo.rb">source</a>)</li>
23
25
  </ol>
24
26
  </section>
25
27
 
26
28
  <footer>
27
29
  <p>Copyright © 2011-2012 Michael Granger &lt;<a href="mailto:ged@FaerieMUD.org">ged@FaerieMUD.org</a>&gt;.</p>
28
- <p><tt>$Id: bootstrap.html,v 0b20bfda9eea 2012/05/22 00:34:22 ged $</tt></p>
30
+ <p><tt>$Id: bootstrap.html,v 4c64666f4255 2012/10/03 00:42:35 ged $</tt></p>
29
31
  </footer>
30
32
  </body>
31
33
  </html>
@@ -26,7 +26,7 @@ class AsyncUploadHandler < Mongrel2::Handler
26
26
 
27
27
 
28
28
  ### Mongrel2 async upload callback -- allow uploads to proceed.
29
- def handle_upload_start( request )
29
+ def handle_async_upload_start( request )
30
30
  self.log.info "Upload started: %s" % [ request.header.x_mongrel2_upload_start ]
31
31
  return nil # Do nothing
32
32
  end
@@ -52,12 +52,8 @@ class AsyncUploadHandler < Mongrel2::Handler
52
52
 
53
53
  ### Regular request -- show the upload form.
54
54
  def handle( request )
55
- # If it's the 'upload started' notification, use that handler method
56
- if request.upload_started?
57
- return self.handle_upload_start( request )
58
-
59
55
  # If it's a finished upload, use that handler method
60
- elsif request.upload_done?
56
+ if request.upload_done?
61
57
  return self.handle_upload_done( request )
62
58
 
63
59
  else
@@ -69,12 +69,12 @@ class Mongrel2::Connection
69
69
  self.log.debug "0mq Context is: %p" % [ ctx ]
70
70
 
71
71
  self.log.info "Connecting PULL request socket (%s)" % [ self.sub_addr ]
72
- @request_sock = ctx.socket( ZMQ::PULL )
72
+ @request_sock = ctx.socket( ZMQ::PULL )
73
73
  @request_sock.setsockopt( ZMQ::LINGER, 0 )
74
74
  @request_sock.connect( self.sub_addr )
75
75
 
76
76
  self.log.info "Connecting PUB response socket (%s)" % [ self.pub_addr ]
77
- @response_sock = ctx.socket( ZMQ::PUB )
77
+ @response_sock = ctx.socket( ZMQ::PUB )
78
78
  @response_sock.setsockopt( ZMQ::IDENTITY, self.identifier )
79
79
  @response_sock.setsockopt( ZMQ::LINGER, 0 )
80
80
  @response_sock.connect( self.pub_addr )
@@ -90,6 +90,13 @@ class Mongrel2::Handler
90
90
  log_to :mongrel2
91
91
 
92
92
 
93
+ # Signals we handle
94
+ QUEUE_SIGS = [
95
+ :INT, :TERM, :HUP, :USR1,
96
+ # :TODO: :QUIT, :WINCH, :USR2, :TTIN, :TTOU
97
+ ]
98
+
99
+
93
100
  ### Create an instance of the handler using the config from the database with
94
101
  ### the given +appid+ and run it.
95
102
  def self::run( appid )
@@ -121,6 +128,8 @@ class Mongrel2::Handler
121
128
  def initialize( app_id, send_spec, recv_spec ) # :notnew:
122
129
  @app_id = app_id
123
130
  @conn = Mongrel2::Connection.new( app_id, send_spec, recv_spec )
131
+
132
+ Thread.main[:signal_queue] = []
124
133
  end
125
134
 
126
135
 
@@ -158,7 +167,9 @@ class Mongrel2::Handler
158
167
  ### Shut down the handler.
159
168
  def shutdown
160
169
  self.log.info "Shutting down."
170
+ self.ignore_signals
161
171
  @conn.close
172
+ Mongrel2.zmq_context.close
162
173
  end
163
174
 
164
175
 
@@ -176,25 +187,35 @@ class Mongrel2::Handler
176
187
  ### Start a loop, accepting a request and handling it.
177
188
  def start_accepting_requests
178
189
  until @conn.closed?
179
- req = @conn.receive
180
- self.log.info( req.inspect )
181
- res = self.dispatch_request( req )
182
-
183
- if res
184
- self.log.info( res.inspect )
185
- @conn.reply( res ) unless @conn.closed?
186
- end
190
+ ZMQ.select([ @conn.request_sock ])
191
+ self.accept_request unless @conn.closed?
187
192
  end
188
193
  rescue ZMQ::Error => err
194
+ self.process_signal_queue
195
+
189
196
  unless @conn.closed?
190
197
  self.log.error "%p while accepting requests: %s" % [ err.class, err.message ]
191
198
  self.log.debug { err.backtrace.join("\n ") }
192
199
 
200
+ # Restart the method
193
201
  retry
194
202
  end
195
203
  end
196
204
 
197
205
 
206
+ ### Read a request from the connection and dispatch it.
207
+ def accept_request
208
+ req = @conn.receive
209
+ self.log.info( req.inspect )
210
+ res = self.dispatch_request( req )
211
+
212
+ if res
213
+ self.log.info( res.inspect )
214
+ @conn.reply( res ) unless @conn.closed?
215
+ end
216
+ end
217
+
218
+
198
219
  ### Invoke a handler method appropriate for the given +request+.
199
220
  def dispatch_request( request )
200
221
  if request.is_disconnect?
@@ -329,6 +350,10 @@ class Mongrel2::Handler
329
350
  end
330
351
 
331
352
 
353
+ #########
354
+ protected
355
+ #########
356
+
332
357
  #
333
358
  # :section: Signal Handling
334
359
  # These methods set up some behavior for starting, restarting, and stopping
@@ -336,43 +361,77 @@ class Mongrel2::Handler
336
361
  # be handled, override #set_signal_handlers with an empty method.
337
362
  #
338
363
 
339
- ### Set up signal handlers for SIGINT, SIGTERM, SIGINT, and SIGUSR1 that will call the
340
- ### #on_hangup_signal, #on_termination_signal, #on_interrupt_signal, and
341
- ### #on_user1_signal methods, respectively.
364
+ ### Set up signal handlers for common signals that will shut down, restart, etc.
342
365
  def set_signal_handlers
343
- Signal.trap( :HUP, &self.method(:on_hangup_signal) )
344
- Signal.trap( :TERM, &self.method(:on_termination_signal) )
345
- Signal.trap( :INT, &self.method(:on_interrupt_signal) )
346
- Signal.trap( :USR1, &self.method(:on_user1_signal) )
366
+ self.log.debug "Setting up deferred signal handlers."
367
+ QUEUE_SIGS.each do |sig|
368
+ Signal.trap( sig ) { Thread.main[:signal_queue] << sig }
369
+ end
347
370
  end
348
371
 
349
372
 
350
- ### Restore the default signal handlers
373
+ ### Set all signal handlers to ignore.
374
+ def ignore_signals
375
+ self.log.debug "Ignoring signals."
376
+ QUEUE_SIGS.each do |sig|
377
+ Signal.trap( sig, :IGNORE )
378
+ end
379
+ end
380
+
381
+
382
+ ### Set the signal handlers back to their defaults.
351
383
  def restore_signal_handlers
352
- Signal.trap( :HUP, :DEFAULT )
353
- Signal.trap( :TERM, :DEFAULT )
354
- Signal.trap( :INT, :DEFAULT )
355
- Signal.trap( :USR1, :DEFAULT )
384
+ self.log.debug "Restoring default signal handlers."
385
+ QUEUE_SIGS.each do |sig|
386
+ Signal.trap( sig, :DEFAULT )
387
+ end
356
388
  end
357
389
 
390
+ ### Handle any queued signals.
391
+ def process_signal_queue
392
+ # Look for any signals that arrived and handle them
393
+ while sig = Thread.main[:signal_queue].shift
394
+ self.handle_signal( sig )
395
+ end
396
+ end
397
+
398
+
399
+ ### Handle signals.
400
+ def handle_signal( sig )
401
+ self.log.debug "Handling signal %s" % [ sig ]
402
+ case sig
403
+ when :INT, :TERM
404
+ self.on_termination_signal( sig )
405
+
406
+ when :HUP
407
+ self.on_hangup_signal( sig )
408
+
409
+ when :USR1
410
+ self.on_user1_signal( sig )
411
+
412
+ else
413
+ self.log.warn "Unhandled signal %s" % [ sig ]
414
+ end
358
415
 
359
- ### Handle a HUP signal. The default is to restart the handler.
360
- def on_hangup_signal( signo )
361
- self.log.warn "Hangup: reconnecting."
362
- self.restart
363
416
  end
364
417
 
365
418
 
366
419
  ### Handle a TERM signal. Shuts the handler down after handling any current request/s. Also
367
420
  ### aliased to #on_interrupt_signal.
368
421
  def on_termination_signal( signo )
369
- self.log.warn "Halting on signal #{signo} (Thread: %p vs. main: %p)" %
370
- [ Thread.current, Thread.main ]
422
+ self.log.warn "Terminated (%p)" % [ signo ]
371
423
  self.shutdown
372
424
  end
373
425
  alias_method :on_interrupt_signal, :on_termination_signal
374
426
 
375
427
 
428
+ ### Handle a HUP signal. The default is to restart the handler.
429
+ def on_hangup_signal( signo )
430
+ self.log.warn "Hangup (%p)" % [ signo ]
431
+ self.restart
432
+ end
433
+
434
+
376
435
  ### Handle a USR1 signal. Writes a message to the log by default.
377
436
  def on_user1_signal( signo )
378
437
  self.log.info "Checkpoint: User signal."
@@ -27,8 +27,8 @@ class Mongrel2::Request
27
27
  ### request object.
28
28
  def self::parse( raw_request )
29
29
  sender, conn_id, path, rest = raw_request.split( ' ', 4 )
30
- self.log.debug "Parsing request for %p from %s:%s (rest: %p)" %
31
- [ path, sender, conn_id, rest ]
30
+ self.log.debug "Parsing request for %p from %s:%s (rest: %p...)" %
31
+ [ path, sender, conn_id, rest[0,20] ]
32
32
 
33
33
  # Extract the headers and the body, ignore the rest
34
34
  headers, rest = TNetstring.parse( rest )
data/lib/mongrel2.rb CHANGED
@@ -20,10 +20,10 @@ module Mongrel2
20
20
  abort "\n\n>>> Mongrel2 requires Ruby 1.9.2 or later. <<<\n\n" if RUBY_VERSION < '1.9.2'
21
21
 
22
22
  # Library version constant
23
- VERSION = '0.32.0'
23
+ VERSION = '0.33.0'
24
24
 
25
25
  # Version-control revision constant
26
- REVISION = %q$Revision: ebfb060e8c65 $
26
+ REVISION = %q$Revision: 8703559eacf1 $
27
27
 
28
28
 
29
29
  require 'mongrel2/constants'
data/spec/lib/helpers.rb CHANGED
@@ -39,6 +39,8 @@ require 'mongrel2'
39
39
  require 'mongrel2/config'
40
40
  require 'mongrel2/testing'
41
41
 
42
+ require 'loggability/spechelpers'
43
+
42
44
  require 'sequel'
43
45
  require 'sequel/model'
44
46
 
@@ -60,30 +62,6 @@ module Mongrel2::SpecHelpers
60
62
  end
61
63
 
62
64
 
63
- ### Reset the logging subsystem to its default state.
64
- def reset_logging
65
- Loggability.formatter = nil
66
- Loggability.output_to( $stderr )
67
- Loggability.level = :fatal
68
- end
69
-
70
-
71
- ### Alter the output of the default log formatter to be pretty in SpecMate output
72
- def setup_logging( level=:fatal )
73
-
74
- # Only do this when executing from a spec in TextMate
75
- if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
76
- logarray = []
77
- Thread.current['logger-output'] = logarray
78
- Loggability.output_to( logarray )
79
- Loggability.format_as( :html )
80
- Loggability.level = :debug
81
- else
82
- Loggability.level = level
83
- end
84
- end
85
-
86
-
87
65
  ### Set up a Mongrel2 configuration database in memory.
88
66
  def setup_config_db
89
67
  Mongrel2::Config.db ||= Mongrel2::Config.in_memory_db
@@ -254,6 +232,7 @@ RSpec.configure do |c|
254
232
  c.include( Mongrel2::TestConstants )
255
233
  c.include( Mongrel2::SpecHelpers )
256
234
  c.include( Mongrel2::Matchers )
235
+ c.include( Loggability::SpecHelpers )
257
236
 
258
237
  c.include( Mongrel2::Config::DSL )
259
238
  end
@@ -58,13 +58,15 @@ describe Mongrel2::Handler do
58
58
 
59
59
  # Ensure 0MQ never actually gets called
60
60
  before( :each ) do
61
- @ctx = double( "0mq context" )
62
- @request_sock = double( "request socket", :setsockopt => nil, :connect => nil, :close => nil )
63
- @response_sock = double( "response socket", :setsockopt => nil, :connect => nil, :close => nil )
61
+ @ctx = double( '0mq context', close: nil )
62
+ @request_sock = double( "request socket", setsockopt: nil, connect: nil, close: nil )
63
+ @response_sock = double( "response socket", setsockopt: nil, connect: nil, close: nil )
64
64
 
65
65
  @ctx.stub( :socket ).with( ZMQ::PULL ).and_return( @request_sock )
66
66
  @ctx.stub( :socket ).with( ZMQ::PUB ).and_return( @response_sock )
67
67
 
68
+ ZMQ.stub( :select ).and_return([ [@request_sock], [], [] ])
69
+
68
70
  Mongrel2.instance_variable_set( :@zmq_ctx, @ctx )
69
71
  end
70
72
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongrel2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.33.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -36,7 +36,7 @@ cert_chain:
36
36
  YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
37
37
  Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
38
38
  cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
- date: 2012-09-18 00:00:00.000000000 Z
39
+ date: 2012-10-03 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
metadata.gz.sig CHANGED
@@ -1,3 +1,3 @@
1
- A8�@��2�W}�a0�TG�]�>���F��\��K���"�B��:�3�bEcs��^����
2
- ��q:�={�~@�c��!w���[��5�t��qX���j
3
- j��=֪���$�4��`�Jkh�o��Q-]`|��g��?lGW_?0��is&K��h��#?�
1
+ 7�=�Սq��~5گ<����Hz/����P����{t�����
2
+ �$ÂF��s'>�w��
3
+  ��^�j�@*Y'+�;<���^���v�+h��9fc2[*s��og3y���jd@�Z����1��E?��W4�������'���ʬ"��*�O