小编Gua*_*Joe的帖子

Sidekiq在工人完成后没有释放内存

我有大约六个执行JSON爬行的Sidekiq工作者.根据端点的数据集大小,它们在1分钟到4小时之间完成.特别是,观看长达4小时的长时间,我看到随着时间的推移,内存会略有增加.

这不是问题,直到我想再次安排相同的工作人员工作.内存没有被释放并堆积起来,直到我遇到Linux OOM Killer,摆脱了我的Sidekiq进程.

内存泄漏?我在ObjectSpace中观察了不同对象的数量:

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 }
Run Code Online (Sandbox Code Playgroud)

那里没有真正的增加,哈希,数组等的集合保持不变,垃圾收集器一扫而空,并gc.stat[:count]告诉我,垃圾收集器也在工作.

即使在工作人员完成之后,例如我得到[完成]记录并且没有工人正忙,但内存不会被释放.这是什么原因?我可以对此做点什么吗?写一个终结者?

目前唯一的解决方案:重启Sidekiq进程.

我在Ruby 2.0.0上使用Ruby MRI.


对于JSON解析,我使用Yajl,因此是C绑定.我需要它,因为它似乎是唯一能够正确实现流式读写的快速JSON解析器.

ruby memory-leaks memory-management out-of-memory sidekiq

30
推荐指数
1
解决办法
9277
查看次数

如何从控制器存根参数?

对于我的测试,我需要一个控制器,我可以设置自己的参数.使用参数我指的是调用时获得的参数controller.params

{"action"=>"show",
 "controller"=>"merchants",
 "wine_id"=>"1",
 "id"=>"346343"}
Run Code Online (Sandbox Code Playgroud)

问题是,我不知道在这里存在什么正确的存根方式.有三种情况:

  • controller.request.env['action_dispatch.request.path_parameters']
  • controller.params
  • controller.url_options[:_recall]

在所有三个中都存储了相同的信息,但是设置这些值的接口方式是什么?

rspec ruby-on-rails ruby-on-rails-4

9
推荐指数
1
解决办法
5403
查看次数

基于流的解析和编写JSON

我从1,000个批次的服务器中获取大约20,000个数据集.每个数据集都是JSON对象.坚持这使得大约350 MB的未压缩明文.

我的内存限制为1GB.因此,我将每个1,000个JSON对象作为数组写入附加模式的原始JSON文件中.

结果是一个包含20个JSON数组的文件,需要进行聚合.无论如何我需要触摸它们,因为我想添加元数据.通常Ruby Yajl Parser可以这样做:

raw_file = File.new(path_to_raw_file, 'r')
json_file = File.new(path_to_json_file, 'w')

datasets = []
parser = Yajl::Parser.new
parser.on_parse_complete = Proc.new { |o| datasets += o }

parser.parse(datasets)

hash = { date: Time.now, datasets: datasets }
Yajl::Encoder.encode(hash, json_file)
Run Code Online (Sandbox Code Playgroud)

这个解决方案的问题在哪里?问题是仍然将整个JSON解析为内存,我必须避免.

基本上我需要的是一个解决方案,它从IO对象解析JSON并同时将它们编码到另一个IO对象.

我假设Yajl提供了这个,但我没有找到方法,它的API也没有给出任何提示,所以我猜不是.是否有支持此功能的JSON Parser库?还有其他解决方案吗?


我能想到的唯一解决方案就是使用这些IO.seek功能.写的所有数据集阵列此起彼伏[...][...][...],每个数组后,我找回到开始并覆盖][,,有效手动连接的阵列.

ruby memory io parsing json

6
推荐指数
1
解决办法
1950
查看次数

在一组正分数上绘制排名

我有一个积极的分数列表:

[98.5, 85, 50, 50, 23, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)

我想为这些分数分配排名:

[1, 2, 3, 3, 4, 5, 5, 5]
Run Code Online (Sandbox Code Playgroud)

当两个连续分数具有相同的值时,它们获得相同的等级.知道如何以功能性方式解决这个问题吗?

(发布在Haskell和Ruby中,因为我认为这两种解决方案都是可行的并且可以移植)

ruby haskell

4
推荐指数
2
解决办法
1593
查看次数

配置Mongoid关系以返回已排序的对象

我有两个关系为1-n的课程.像这样:

class Band
  include Mongoid::Document
  has_many :members
end

class Member
  include Mongoid::Document
  field :name, type: String
  field :joined, type: Date
  belongs_to :band
end
Run Code Online (Sandbox Code Playgroud)

现在,当我打电话时,band.members我得到了成员对象.我想要的是,如果我打电话band.members.last来获得加入最后一个的成员.我通过定义基于以下的<=>方法Member和排序来实现这一点joined:

band.members.sort.last
Run Code Online (Sandbox Code Playgroud)

如何将此行为设为默认值?我不想避免额外的排序调用.这是可能的,如果可以,怎么样?

ruby dsl queryinterface mongodb mongoid

1
推荐指数
1
解决办法
1440
查看次数