[ruby-list:50889] Re: Net::SSH を使ったパイプ処理

From: emo@...
Date: 2020-06-02 00:34:58 UTC
List: ruby-list #50889
On 2020/06/01 22:12, dezawa wrote:
 > 解決策では無いのですが、もしかしたらヒントになるかも、と
 >
 >  > 差分データが大きい場合は、send_data ではデータが実際には送られず、
 >  > バッファーに溜まって行き、本体のメモリが足らなくなって
 >  > 失敗しているようです。
 > のではなく、
 >
 > つど送っているのだが
 >>        while (data=sender_out.read(BUF_SIZE)) do
 > の data が使い捨てられて、つど新しい領域が確保され、GCが間に合わない
 > のでは?
 >
 > 以下つぶやき
 > data に入れずに ちょくに  channel.send_data(sender_out.read(BUF_SIZE))
 > してみる方法は領域取り直すのだろうか、、、
 > (そういう手段があるかわかりませんが)既得領域に上書きするようにできない
 > だろうか
 >                      出澤
 >

どうもご返答ありがとうございます。

Net::SSHのソースコードを追ってみたのですが、
Channel クラスのsend_data というメソッドの中では、実際にデータは送られず、
Buffer クラスのインスタンス output に追加しているだけのようです。

    249      def send_data(data)
    250        raise EOFError, "cannot send data if channel has declared 
eof" if eof?
    251        output.append(data.to_s)
    252      end


実際に送られるのは process 
メソッドを読んだ際に呼び出される、enqueue_pending_outputというメソッド内です。

    484        def enqueue_pending_output #:nodoc:
    485          return unless remote_id
    486
    487          while output.length > 0
    488            length = output.length
    489            length = remote_window_size if length > 
remote_window_size
    490            length = remote_maximum_packet_size if length > 
remote_maximum_packet_size
    491
    492            if length > 0
    493              connection.send_message(Buffer.from(:byte, 
CHANNEL_DATA, :long, remote_id, :string, output.read(length)))
    494              output.consume!
    495              @remote_window_size -= length
    496            else
    497              break
    498            end
    499          end
    500        end      end

実際にどういう動きになっているか491行目にprint 文を追加し、length, output.length, 
remote_window_sizeの値を表示してみました。


すると、以下のようになり、途中から remote_window_sizeが0になると output 
のサイズが増加一方となり、最後にはメモリが尽きてしまうようです。
この先のプログラムの動作が追えていないのですが、実行中はremote_window_size 
は減少するのみで、元に戻ることがありません。


length=32768 output.length=102400 remote_window_size=2097152
length=32768 output.length=69632 remote_window_size=2064384
length=32768 output.length=36864 remote_window_size=2031616
length=4096 output.length=4096 remote_window_size=1998848
length=32768 output.length=102400 remote_window_size=1994752
length=32768 output.length=69632 remote_window_size=1961984
length=32768 output.length=36864 remote_window_size=1929216
length=4096 output.length=4096 remote_window_size=1896448
length=32768 output.length=102400 remote_window_size=1892352
length=32768 output.length=69632 remote_window_size=1859584
length=32768 output.length=36864 remote_window_size=1826816
length=4096 output.length=4096 remote_window_size=1794048…
…
…
length=16384 output.length=69632 remote_window_size=16384
length=0 output.length=53248 remote_window_size=0
length=0 output.length=155648 remote_window_size=0
length=0 output.length=258048 remote_window_size=0
length=0 output.length=360448 remote_window_size=0
length=0 output.length=462848 remote_window_size=0
length=0 output.length=565248 remote_window_size=0
length=0 output.length=667648 remote_window_size=0
length=0 output.length=770048 remote_window_size=0
…
…




江本


In This Thread