@kyanny's blog

My thoughts, my life. Views/opinions are my own.

プログラム内から起動した外部プロセスが利用可能になるまで TCPSocket.open で待つ

https://github.com/kyanny/playground/blob/gh-pages/tcpsocket-open/wait_port_open_close.rb

プログラム内から子プロセスとして Rack アプリケーションを起動し HTTP リクエストを送りたい、という場合に、 Rack アプリケーションが起動し終わって localhost:9292 への HTTP リクエストを受け付けられるようになるまでには少し時間がかかる。適切なウェイトをはさまないと Rack アプリケーションがまだ起動してないのにプログラム本体の処理が進んでしまって HTTP リクエストを送ってしまう。

だいたい sleep で適当に三秒くらい待ってたけど、もっと効率よく最短の時間だけ待つようにできないかと思って TCPSocket.open でポートが利用可能になったか調べる方法を思いついたので試してみたらいい感じだった。

# wait until rack server launch
loop do
  begin
    TCPSocket.open('localhost', 9292)
    break
  rescue
  end
end

これはポートが利用可能になるまで待つほう。ポートに繋がらないと例外が出るので rescue で無視する。ポートに繋がったら break して無限ループを抜ける。

# wait until rack server shutdown
loop do
  begin
    TCPSocket.open('localhost', 9292)
  rescue
    break
  end
end

これは逆にポートが利用できなくなるまで待つほう。 Rack アプリケーションを kill するとシャットダウンにも少し時間がかかる。シグナルを送れていれば Rack アプリケーションのシャットダウンより前にプログラム本体が終了しても問題ないけど、シェルに戻ってからプロンプトに Stopping ... とか表示されるとかっこわるい。シャットダウンを待ってからプログラム終了するほうがかっこいい気がする。