@@ -12,6 +12,7 @@ module Puma
1212 installed : false ,
1313 boot_emitted : false ,
1414 shutdown_emitted : false ,
15+ handler_pending_started : false ,
1516 start_info : {
1617 mode : nil ,
1718 puma_version : nil ,
@@ -158,6 +159,7 @@ def state_reset!
158159 STATE [ :boot_emitted ] = false
159160 STATE [ :shutdown_emitted ] = false
160161 STATE [ :started_emitted ] = false
162+ STATE [ :handler_pending_started ] = false
161163 STATE [ :start_info ] = {
162164 mode : nil ,
163165 puma_version : nil ,
@@ -223,7 +225,9 @@ def process_line(line)
223225
224226 if ( m = l . match ( /^\* ?\s *Listening on (.+)$/ ) )
225227 si = T . cast ( STATE [ :start_info ] , T ::Hash [ Symbol , T . untyped ] )
226- si [ :listening ] << T . must ( m [ 1 ] )
228+ list = T . cast ( si [ :listening ] , T ::Array [ T . untyped ] )
229+ address = T . must ( m [ 1 ] )
230+ list << address unless list . include? ( address )
227231 # Emit started when we see the first listening address
228232 if !STATE [ :started_emitted ]
229233 emit_started!
@@ -258,7 +262,7 @@ def process_line(line)
258262 emit_started!
259263 STATE [ :started_emitted ] = true
260264 end
261- return true
265+ return false
262266 end
263267
264268 if l . start_with? ( "- Gracefully stopping" )
@@ -309,6 +313,7 @@ def emit_started!
309313 timestamp : Time . now
310314 )
311315 LogStruct . info ( log )
316+ STATE [ :handler_pending_started ] = false
312317 # Only use LogStruct; SemanticLogger routes to STDOUT in test
313318 end
314319
@@ -393,43 +398,75 @@ def log(str)
393398 module RackHandlerPatch
394399 extend T ::Sig
395400
396- sig { params ( app : T . untyped , options : T . untyped ) . returns ( T . untyped ) }
397- def run ( app , options )
398- # Emit started once per process
401+ sig do
402+ params (
403+ app : T . untyped ,
404+ args : T . untyped ,
405+ block : T . nilable ( T . proc . returns ( T . untyped ) )
406+ ) . returns ( T . untyped )
407+ end
408+ def run ( app , *args , &block )
409+ rest = args
410+ options = T . let ( { } , T ::Hash [ T . untyped , T . untyped ] )
411+ rest . each do |value |
412+ next unless value . is_a? ( Hash )
413+ options . merge! ( value )
414+ end
415+
399416 begin
417+ si = T . cast ( ::LogStruct ::Integrations ::Puma ::STATE [ :start_info ] , T ::Hash [ Symbol , T . untyped ] )
418+ si [ :mode ] ||= "single"
419+ si [ :environment ] ||= ( ( defined? ( ::Rails ) && ::Rails . respond_to? ( :env ) ) ? ::Rails . env : nil )
420+ si [ :pid ] ||= Process . pid
421+ si [ :listening ] ||= [ ]
400422 port = T . let ( nil , T . untyped )
401423 host = T . let ( nil , T . untyped )
402424 if options . respond_to? ( :[] )
403425 port = options [ :Port ] || options [ "Port" ] || options [ :port ] || options [ "port" ]
404426 host = options [ :Host ] || options [ "Host" ] || options [ :host ] || options [ "host" ]
405427 end
406- addr = if port
428+ if port
429+ list = T . cast ( si [ :listening ] , T ::Array [ T . untyped ] )
430+ list . clear
407431 h = ( host && host != "0.0.0.0" ) ? host : "127.0.0.1"
408- [ "tcp://#{ h } :#{ port } " ]
432+ list << "tcp://#{ h } :#{ port } "
409433 end
410- started = ::LogStruct ::Log ::Puma ::Started . new (
411- mode : "single" ,
412- environment : ( defined? ( ::Rails ) && ::Rails . respond_to? ( :env ) ) ? ::Rails . env : nil ,
413- process_id : Process . pid ,
414- listening_addresses : addr
415- )
416- ::LogStruct . info ( started )
434+ state = ::LogStruct ::Integrations ::Puma ::STATE
435+ state [ :handler_pending_started ] = true unless state [ :started_emitted ]
417436 rescue => e
418437 ::LogStruct ::Integrations ::Puma . handle_integration_error ( e )
419438 end
420439
421440 begin
422441 Kernel . at_exit do
423- shutdown = ::LogStruct ::Log ::Puma ::Shutdown . new ( process_id : Process . pid )
424- ::LogStruct . info ( shutdown )
442+ unless ::LogStruct ::Integrations ::Puma ::STATE [ :shutdown_emitted ]
443+ ::LogStruct ::Integrations ::Puma . emit_shutdown! ( "Exiting" )
444+ ::LogStruct ::Integrations ::Puma ::STATE [ :shutdown_emitted ] = true
445+ end
425446 rescue => e
426447 ::LogStruct ::Integrations ::Puma . handle_integration_error ( e )
427448 end
428449 rescue => e
429450 ::LogStruct ::Integrations ::Puma . handle_integration_error ( e )
430451 end
431452
432- super
453+ begin
454+ result = super ( app , **options , &block )
455+ ensure
456+ state = ::LogStruct ::Integrations ::Puma ::STATE
457+ if state [ :handler_pending_started ] && !state [ :started_emitted ]
458+ begin
459+ ::LogStruct ::Integrations ::Puma . emit_started!
460+ state [ :started_emitted ] = true
461+ rescue => e
462+ ::LogStruct ::Integrations ::Puma . handle_integration_error ( e )
463+ ensure
464+ state [ :handler_pending_started ] = false
465+ end
466+ end
467+ end
468+
469+ result
433470 end
434471 end
435472
0 commit comments