【发布时间】:2015-04-03 20:35:40
【问题描述】:
我有以下型号:
class User < ActiveRecord::Base
def send_message(content)
MessagePoro.new(content).deliver!
end
def self.send_to_all(content)
threads = []
all.each do |user|
threads << Thread.new do
user.send_message(content)
end
end
threads.each(&:join)
end
end
MessagePoro 模型可以很简单,例如app/models/message_poro.rb:
class MessagePoro
def initialize(content)
# ...
end
def deliver!
# ...
end
end
现在,当我有例如100 个用户,我正在运行 User.send_to_all("test") 我有时会遇到这些错误:
RuntimeError: Circular dependency detected while autoloading constant MessagePoro
或:
wrong number of arguments (1 for 0)
我想这一定是因为没有加载 MessagePoro 并且所有线程都尝试同时加载它,或者类似的东西。由于这些错误仅在某些时候发生,我很确定只有在存在“竞争条件”或与线程有关的情况下才会发生。我曾尝试在启动 Threads 之前初始化 MessagePoro,并且我玩过 eager_loading,但问题似乎仍然存在。 我还能尝试什么来缓解这个问题?
【问题讨论】:
-
在自动加载之前尝试手动要求它
-
您能详细说明一下吗?就像在线程开始之前调用 MessagePoro.new 一样?万一这正在修复它,我仍然对潜在问题感到好奇
-
没有。目前你有基本的 Rails 自动加载设置。如果您首先在代码中的某处调用 MessagePoro,它将根据某些约定要求它(例如 MyModule::MessagePoro 应该在 autoload_path/my_module/message_poro.rb 中)。但您可以尝试手动要求它 require 'path/to/message_poro'。
-
你使用的是什么 ruby 版本?
-
我在使用 eager_loading、Ruby 2.1 和 Rails 4.1 和 4.2 时遇到了同样的问题
标签: multithreading ruby-on-rails-4 eager-loading