Feature #9981

Net::SMTP#send_message が大量の write(2) を発行する

Added by Masahiro Tomita about 1 year ago. Updated 12 months ago.

[ruby-dev:48329]
Status:Closed
Priority:Normal
Assignee:Motohiro KOSAKI

Description

Net::SMTP#send_message でメールを送信すると1行毎に write(2) が発行されます。
1MB のバイナリデータを添付すると、18000回以上 write することになります。

1048576(byte) * 4/3 (Base64化) / 76 (1行あたりの長さ) = 18396 行

SMTP の DATA 命令後はひたすらデータを送り続ければいいだけなので行ごとに write するよりもバッファリングした方がいいと思います。

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回程度になりました。

Associated revisions

Revision 46793
Added by Motohiro KOSAKI 12 months ago

  • lib/net/smtp.rb (Net::SMTP#data): enable buffering while 'data' send for optimizing Net::SMTP#send_message. [misc #9981] patch by Masahiro Tomita.

Revision 46793
Added by Motohiro KOSAKI 12 months ago

  • lib/net/smtp.rb (Net::SMTP#data): enable buffering while 'data' send for optimizing Net::SMTP#send_message. [misc #9981] patch by Masahiro Tomita.

History

#1 Updated by Hiroshi SHIBATA 12 months ago

どなたか SMTP にお詳しい方はいらっしゃいませんか.

#2 Updated by Takahiro Kambe 12 months ago

In message redmine.journal-47699.20140711064732.e1bfc429d603f917@ruby-lang.org
on Fri, 11 Jul 2014 06:47:32 +0000,
shibata.hiroshi@gmail.com wrote:

Issue #9981 has been updated by Hiroshi SHIBATA.

どなたか SMTP にお詳しい方はいらっしゃいませんか.
詳しいかどうかはさておき、

SMTP の DATA 命令後はひたすらデータを送り続ければいいだけなので行ごと
に write するよりもバッファリングした方がいいと思います。
DATAを送ったとは、その通りなので問題ないはずです。
DATAの終わりの".\r\n"を送った後でないと、サーバーも応答を返せませんか
ら。

--
神戸 隆博 / Takahiro Kambe

#3 Updated by Motohiro KOSAKI 12 months ago

  • Tracker changed from Misc to Feature
  • Status changed from Open to Assigned
  • Assignee set to Motohiro KOSAKI

コードは問題なさそうに見えるし、賛成意見もついているし、メンテナがいないモジュールのようなので、
代理コミットしときますね。

#4 Updated by Hiroshi SHIBATA 12 months ago

  • Status changed from Assigned to Closed

Also available in: Atom PDF