2013-03-25 21 views
5

Ich habe den folgenden Code, in dem ein WEBrick Beispiel gegabelt ist, und ich will warten, bis der webrick gestartet wird, bevor es mit dem Rest des Codes fort:Fork WEBrick und warten auf Start

require 'webrick' 

pid = fork do 
    server = WEBrick::HTTPServer.new({:Port => 3333, :BindAddress => "localhost"}) 
    trap("INT") { server.shutdown } 
    sleep 10 # here is code that take some time to setup 
    server.start 
end 
# here I want to wait till the fork is complete or the WEBrick server is started and accepts connections 
puts `curl localhost:3333 --max-time 1` # then I can talk to the webrick 
Process.kill('INT', pid) # finally the webrick should be killed 

Also wie kann ich warten bis die Gabel komplett ist, oder noch besser, bis der WEBrick bereit ist Verbindungen zu akzeptieren? Ich habe ein Stück Code gefunden, wo sie sich mit einem IO.pipe und einem Leser und einem Schreiber beschäftigen. Aber das wartet nicht bis Webrick lädt.

Leider habe ich für diesen speziellen Fall nichts gefunden. Hoffe jemand kann helfen.

Antwort

6

WEBRick::GenericServer hat einige Callback-Haken, die nicht dokumentiert sind (leider in der Tat ist die ganze webrick Bibliothek schlecht dokumentiert!), wie :StartCallback, :StopCallback, :AcceptCallback. Sie können Hooks bereitstellen, wenn Sie eine WEBRick::HTTPServer Instanz initialisieren.

So, kombiniert mit IO.pipe, können Sie Ihren Code wie folgt schreiben:

require 'webrick' 

PORT = 3333 

rd, wt = IO.pipe 

pid = fork do 
    rd.close 
    server = WEBrick::HTTPServer.new({ 
    :Port => PORT, 
    :BindAddress => "localhost", 
    :StartCallback => Proc.new { 
     wt.write(1) # write "1", signal a server start message 
     wt.close 
    } 
    }) 
    trap("INT") { server.shutdown } 
    server.start 
end 

wt.close 
rd.read(1) # read a byte for the server start signal 
rd.close 

puts `curl localhost:#{PORT} --max-time 1` # then I can talk to the webrick 
Process.kill('INT', pid) # finally the webrick should be killed 
+0

Wonderful! Ich habe nur dein 'rd.read (1) ersetzt; rd.close' mit 'raise" Server nicht gestartet "außer rd.wait (10)', so dass ich ein Timeout festlegen und einen Fehler auslösen kann. Danke für die Antwort! – 23tux