2017-02-17 5 views
3

ここでNode.jsの開発者はRubyで作業する必要があるので、私はRubyの多くの概念をかなり新しくしています。Rubyのメモリ変換ストリームでは?

私は、S3から非常に大きな区切りのJSONファイルをダウンロードし、データを変換してS3に戻して、ディスクに何も書き込まずにメモリにすべて格納しなければならないというケースがあります。

はノードでは、私はこのような何かを行うことができます:彼らが来ると同時にS3にそれらを置くようその場でオブジェクトを変換します

s3DownloadStream('my-file').pipe(transformStream).pipe(backToS3Stream) 

Rubyで同じ動作を達成するための適切な行動計画を見つけるのが難しいです。私はIO.pipeとCelluloid :: IOを可能なオプションとして見てきましたが、まだこれを行うことができるようには思えません。

+0

これは役に立ちます:https://aws.amazon.com/blogs/developer/downloading-objects-from-amazon-s3-using-the-aws-sdk-for-ruby/ –

+0

@AlexandreAngelim私はそれを見ましたポストが、大きなファイルをディスクにダウンロードするか、メモリIOにダウンロードするかのように思えます。そのポストでは、変換を介してダウンロードをパイプして同時にs3に戻ることができるということについては何も見ていませんでした。私はforkやThread.newを使わなければならないと思っていますが、似たようなことをしている人の実例を得ることを望んでいます。 – aloisbarreras

+0

上記のリンクはあなたのほとんどのところであなたを得ます。 「ブロックの使用」のコードを見てください。各チャンクをファイルに書き込むのではなく、チャンクを処理してからS3に結果をアップロードします(マルチパートアップロードAPIを使用します)。 –

答えて

0

RubyにはNodeのストリームと直接の類似点はありませんが、Enumerableイテレータフレームワークがあり、その中にLazyオプションがあります。怠惰な列挙子は、毎回完了までに実行されるものとは異なり、必要に応じてデータを出力するだけです。

遅延チェーンを設定すると、ビットごとに評価されますが、一度に評価されることはありません。

だからあなたのコードは次のようになります。あなたが個別にチェーンをどのように各値の波紋を見ることができます

input = ('a'..'z') 

input.lazy.map do |i| 
    puts 'i=%s' % i 

    i.upcase 
end.each do |j| 
    puts ' j=%s' % j 
end 

s3_download('my-file').lazy.map do |...| 
    # transform stream 
end.each do |...| 
    # pipe back to S3 
end 

ここにあなたが上に構築することができます簡単な例です。もしそうでない場合lazyを削除すると、最初のループが完了してバッファリングされ、次に2番目のループが完了して処理されます。

ノードストリームはこれよりもはるかに複雑です。一時停止/再開、操作をブロックせずに延期するなど、機能面で重複があります。 Rubyは、あなたが繊維や糸のようなものを使うのに時間を費やすなら、これを行うことができますが、それはたくさんの作業です。

関連する問題