Okt*_*tav 3 ruby ruby-on-rails-3
我有一个非常简单的设置来测试rails3 ActiveSupport::Notifications.通过阅读文档,该ActiveSupport::Notifications.subscribe位应该异步执行它的操作.显然事实并非如此.
例:
ActiveSupport::Notifications.subscribe "some.channel" do |name, start, finish, id, payload|
# do expensive task
sleep(10)
end
ActiveSupport::Notifications.instrument "some.channel" #=> will return 10 seconds later
Run Code Online (Sandbox Code Playgroud)
我的印象是ActiveSupport::Notifications.instrument "some.channel"会马上回来让昂贵的任务做昂贵的事情.否则,我可以直接调用昂贵的任务,而无需使用订户.
该文档还指出可能有多个订阅者.在这种情况下,我会被阻止,直到所有其他订阅者执行他们的代码.
这是正确的吗?如果是,有人可以解释http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html上的这一行是什么意思吗?
The block will be called asynchronously whenever someone instruments “render”:
你是对的.ActiveSupport::Notifications.instrument不会异步/同时调用订阅者或任何类型的订阅者.
如果您遵循代码,您将发现#instrument调用指导者,并且指导者调用通知程序.通知程序是一个实例ActiveSupport::Notifications::Fanout,它通过以下#publish方法向所有侦听器发送通知:
def publish(name, *args)
listeners_for(name).each { |s| s.publish(name, *args) }
end
Run Code Online (Sandbox Code Playgroud)
所述#publish收听者/订户的方法,没有任一异步:
def publish(message, *args)
@delegate.call(message, *args)
end
Run Code Online (Sandbox Code Playgroud)
所有这一切都是调用订户提供的块.同步.
那么为什么文档要求The block will be called asynchronously whenever someone instruments “render”和Notifications ships with a queue implementation that consumes and publish events to log subscribers in a thread?
看起来原始实现是异步的,他们忘了更新文档.如果查看fanout.rb的更改历史记录,可以看到2010年的一些提交,其中实现已更改为同步队列.线程实现可能过于复杂且容易出错.你甚至可以看到遗留下来的痕迹:
# This is a sync queue, so there is no waiting.
def wait
end
Run Code Online (Sandbox Code Playgroud)
这似乎是提交docrails的一个很好的候选人.
在任何情况下,即使实现是异步的,您也可能希望任何长时间运行的代码进入队列(例如resque)并由后台工作程序处理.这样,您的webapp工作进程就不会处理长时间运行的任务,而不是处理请求.
更新:发现11个月前的提交,删除有关通知为异步的错误信息.但是,队列在线程中运行的错误信息仍然存在.
更新2:我致力于 docrails修复有关在线程中运行的队列的信息.
更新3:我的提交已合并到官方文档中.
| 归档时间: |
|
| 查看次数: |
1835 次 |
| 最近记录: |