From: shibata.hiroshi@... Date: 2014-07-11T06:47:32+00:00 Subject: [ruby-dev:48393] [ruby-trunk - misc #9981] Net::SMTP#send_message が大量の write(2) を発行する Issue #9981 has been updated by Hiroshi SHIBATA. どなたか SMTP にお詳しい方はいらっしゃいませんか. ---------------------------------------- misc #9981: Net::SMTP#send_message が大量の write(2) を発行する https://bugs.ruby-lang.org/issues/9981#change-47699 * Author: Masahiro Tomita * Status: Open * Priority: Normal * Assignee: * Category: * Target version: ---------------------------------------- `Net::SMTP#send_message` でメールを送信すると1行毎に write(2) が発行されます。 1MB のバイナリデータを添付すると、18000回以上 write することになります。 1048576(byte) * 4/3 (Base64化) / 76 (1行あたりの長さ) = 18396 行 SMTP の DATA 命令後はひたすらデータを送り続ければいいだけなので行ごとに write するよりもバッファリングした方がいいと思います。 ```diff diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index 5fd4f8e..64e536a 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -901,10 +901,17 @@ module Net end res = critical { check_continue get_response('DATA') - if msgstr - @socket.write_message msgstr - else - @socket.write_message_by_block(&block) + socket_sync_bak = @socket.io.sync + begin + @socket.io.sync = false + if msgstr + @socket.write_message msgstr + else + @socket.write_message_by_block(&block) + end + ensure + @socket.io.flush + @socket.io.sync = socket_sync_bak end recv_response() } ``` これで write(2) が 350回程度になりました。 -- https://bugs.ruby-lang.org/