我正在尝试一次优化/多线程构建大量的模型(300+),试图加快创建这个表的速度,以便在Rails 4应用程序中保存到数据库中。
我试着用备注变量之类的东西在线程之外移动对对象等的引用,但是我不知道还应该尝试什么。
我所拥有的代码如下所示,我试图将多线程的代码保持在尽可能小的范围内,但是我仍然会遇到循环依赖错误和/或创建所有的记录。任何帮助都是非常感谢的。
示例1:
def create
@checklist = Checklist.new(checklist_params)
respond_to do |format|
if @checklist.save
tasks = Task.where(:active => true)
checklist_date_as_time = Time.parse(@checklist.date.to_s).at_beginning_of_day
checklist_id = @checklist.id.to_i
threads = []
ActiveRecord::Base.transaction do
tasks.each do |task|
time = task.start_time
begin
threads << Thread.new do
complete_time = checklist_date_as_time + time.hour.hours + time.min.minutes
task.responses.build( task_start_time: complete_time, must_complete_by: complete_time + task.time_window, checklist_id: checklist_id, task_id: task.id)
end
end while (time += task.frequency.minutes) < task.end_time
threads.map(&:join)
task.save
end
end
format.html { redirect_to @checklist, notice: 'Checklist was successfully created.' }
format.json { render :show, status: :created, location: @checklist }
else
format.html { render :new }
format.json { render json: @checklist.errors, status: :unprocessable_entity }
end
end发布于 2015-12-07 07:46:52
艾尔不是“线程安全”。这意味着在线程之间共享时,单个记录实例的行为/正确性不会由框架定义/保证。
对于您的问题,最简单的答案是在一个后台线程中执行整个tasks = ...; ActiveRecord::Base.transaction do ...工作(比如DelayedJob之类的框架可能会有所帮助),这样“繁重”的计算就不会成为响应周期的一部分。
还请注意,使用多个线程可能会导致您利用多个连接-从而实质上耗尽AR pool。这还意味着(取决于在task.responses.build期间发生了什么),使用ActiveRecord::Base.transaction { ... }所期望的意图可能不正确(因为涉及多个连接对象)。
https://stackoverflow.com/questions/34074401
复制相似问题