在Ruby中的内存转换流?

时间:2017-02-17 01:54:27

标签: ruby amazon-s3 aws-sdk-ruby

这里的Node.js开发人员必须使用Ruby,所以我对Ruby中的很多概念都很陌生,可以使用一些帮助。

我的用例是我必须从S3下载非常大的换行符分隔的JSON文件,转换数据并将其放回S3,所有这些都在内存中,而无需将任何内容写入磁盘。

在Node中,我可以这样做:

<ListView  ScrollViewer.HorizontalScrollBarVisibility="Auto" >                    
  <ListView.View>
    <GridView>
        <GridViewColumn Width="100" />               
        <GridViewColumn Width="130" />               
        <GridViewColumn Width="130" />           
    </GridView>
  </ListView.View>
</ListView>

它会在进入时动态转换对象并同时将它们放到S3中。

我无法找到一个好的行动计划来实现Ruby中的相同行为。我已经看到IO.pipe和Celluloid :: IO作为可能的选项,但他们似乎仍然不会像他们能够做到这一点。

1 个答案:

答案 0 :(得分:0)

Ruby没有与Node中的流直接类似,但它具有Enumerable迭代器框架,并且通过Lazy选项。懒惰的枚举器是仅在必要时发出数据的枚举器,与每次运行完成的其他枚举器不同。

如果您设置了一个惰性链,它将逐位评估,而不是一次性评估。

所以你的代码看起来像是:

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

这是一个可以构建的简单示例:

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

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

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

您可以看到每个值如何分别在链中涟漪。如果删除lazy并非如此,则第一个循环运行完成,缓冲到一个数组,然后第二个循环启动并处理完成。

节点流比这更复杂,它们可以执行暂停/恢复,延迟操作而不阻塞等等,因此在功能方面只有很多重叠。如果你花时间使用纤维和线程之类的东西,Ruby可以做到这一点,但这是很多工作。