如何知道我不使用mongodb操作阻止Ruby eventmachine
我正在开发一个基于eventmachine的应用程序,它定期轮询MongoDB存储文档的更改 简化的代码段可能如下所示:如何知道我不使用mongodb操作阻止Ruby eventmachine,ruby,mongodb,asynchronous,eventmachine,Ruby,Mongodb,Asynchronous,Eventmachine,我正在开发一个基于eventmachine的应用程序,它定期轮询MongoDB存储文档的更改 简化的代码段可能如下所示: require 'rubygems' require 'eventmachine' require 'em-mongo' require 'bson' EM.run { @db = EM::Mongo::Connection.new('localhost').db('foo_development') @posts = @db.collectio
require 'rubygems'
require 'eventmachine'
require 'em-mongo'
require 'bson'
EM.run {
@db = EM::Mongo::Connection.new('localhost').db('foo_development')
@posts = @db.collection('posts')
@comments = @db.collection('comments')
def handle_changed_posts
EM.next_tick do
cursor = @posts.find(state: 'changed')
resp = cursor.defer_as_a
resp.callback do |documents|
handle_comments documents.map{|h| h["comment_id"]}.map(&:to_s) unless documents.length == 0
end
resp.errback do |err|
raise *err
end
end
end
def handle_comments comment_ids
meta_product_ids.each do |id|
cursor = @comments.find({_id: BSON::ObjectId(id)})
resp = cursor.defer_as_a
resp.callback do |documents|
magic_value = documents.first['weight'].to_i * documents.first['importance'].to_i
end
resp.errback do |err|
raise *err
end
end
end
EM.add_periodic_timer(1) do
puts "alive: #{Time.now.to_i}"
end
EM.add_periodic_timer(5) do
handle_changed_posts
end
}
因此EM每5秒迭代一次所有帖子,并选择修改过的帖子。对于每个更改的帖子,它将注释id存储在一个数组中。完成后,该数组被传递给句柄\u comments
,该句柄加载每个注释并进行一些计算
现在我在理解上有一些困难:
handle\u changed\u posts
方法,这很好,除非POST数量增加,并且计算所需时间超过5秒,然后再次计划相同的运行。那样的话,我很快就会有问题了。如何避免这种情况我一直不愿意在这里回答,因为到目前为止我还没有mongo的经验,但考虑到没有人回答,这里的一些东西是一般EM的东西,我可能能够帮助:
resp.callback
和resp.errback
中的handle\u changed\u posts
似乎很适合链接下一次扫描),可以使用add\u timer
或next\u tick
时间的差异。现在
到下一次{Time.now}
,进行基准测试,然后在差异超过阈值时跟踪可能的罪魁祸首。模拟慢速查询(?)和许多并行连接是一个好主意为了扩展bbozo的答案,特别是关于第二个问题,当您运行代码时,您没有时间不阻塞循环。根据我的经验,当我们谈论“非阻塞”代码时,我们真正的意思是“不会阻塞很长的代码”。通常,这些都是非常短的时间段(小于一毫秒),但它们在执行时仍然会阻塞 此外,
下一步真正做的事情就是说“做这个,但不要现在”。正如bbozo所提到的,您真正想要做的是将您的处理分成多个刻度,这样每个迭代块的时间就越短越好
要使用您自己的基准测试,如果20000条记录需要大约3秒的时间来处理,那么4000条记录应该需要大约0.6秒。这足够短,通常不会影响你的1秒心跳。您可以将其进一步拆分,以减少阻塞量并使反应器运行更平稳,但这实际上取决于您需要从反应器获得多少并发性