トップ «前の日記(2004-01-18 (Sun)) 最新 次の日記(2004-01-22 (Thu))» 編集   RSS 1.0 FEED  

Journal InTime


2004-01-21 (Wed) [長年日記]

_ Net::IMAPでclosed streamエラー

mobileimapで以下のようなエラーが出るというレポートをいただいた。

closed stream
/usr/local/lib/ruby/1.8/net/imap.rb:1013:in `write'
/usr/local/lib/ruby/1.8/net/imap.rb:1013:in `print'
/usr/local/lib/ruby/1.8/net/imap.rb:1013:in `put_line'
/usr/local/lib/ruby/1.8/net/imap.rb:986:in `send_command'
/usr/local/lib/ruby/1.8/net/imap.rb:980:in `synchronize'
/usr/local/lib/ruby/1.8/net/imap.rb:998:in `send_command'
/usr/local/lib/ruby/1.8/net/imap.rb:311:in `logout'
...

Net::IMAPのせいではないか、ということだけど、そうに違いない。 ごめんなさい。

でも、上記のバックトレースだけでは状況がよくわからない。

Net::IMAPはスレッドを使ってるのだが、Rubyだとメイン以外のスレッド が例外で落ちた時にデフォルトでは何もおこならい(Javaとかはどうなんだっけ) ので、バックトレースの情報があんまり有用でないことがある(本当の問 題はバックトレースが出てくるより前の、別スレッドの挙動にあるため)。 こういう時は、Thread.abort_on_exception = trueとすると原因 がわかることが多い。 *1 *2

あと、Rubyのスレッドではまりやすいのは、Cで実装したメソッドの中で ブロックしてしまうと(関係ないスレッドもふくめて)全部の処理が止まっ てしまうことだ。 たとえば、データベースのトランザクションなんかでデッドロックに陥 ると、どうしようもなくなる。 *3

Tags: Ruby

*1  あとでこの場合はこの話はあんまり関係ないことがわかった。 ensureでNet::IMAP#logoutを呼んでいて、そこで更に例外がおきていた ので、原因がわかりにくくなっていたようだ。 こういうのもありがち。

*2  結局、原因はenvelopeやbodyがNILになっているメッセージのparseに失 敗したせいだとわかった。CVSのHEADでは修正済。

*3  postgresだったら、PGconn#aync_execを使えば大丈夫そうだ。

_ Changes

rubyの変更点を日本語で読みたい時は <URL:http://rrr.jin.gr.jp/rwiki?cmd=view;name=ruby-cvs> を見ればいいらしい。 *1

Tags: Ruby

*1  というか、書かなきゃ。