【发布时间】:2016-11-23 12:37:05
【问题描述】:
我有一项任务必须按顺序执行。主要是写数据库。
问题是我很难在 Rails 5 中实现它。
我在 ActiveJob 任务中实现它。首先我尝试了互斥锁:
class EventLoadJob < ApplicationJob
MUTEX = Mutex.new
rescue_from(StandardError) do |exception|
puts exception.to_s
end
def perform
MUTEX.synchronize
SomeModel.new.save!
end
end
end
但这会导致死锁。假设:一个线程在临界区内,另一个在临界区入口处等待。所以数据库查询的第一个线程块。它永远等待查询。我想ActiveRecord 线程/连接存在问题 - 它以某种方式被阻塞。但为什么呢?
我已经尝试过锁定文件:
class EventLoadJob < ApplicationJob
rescue_from(StandardError) do |exception|
puts exception.to_s
end
def perform
File.open(Rails.root.join('tmp', 'event_mutex'), File::RDWR|File::CREAT, 0644) do |file|
file.flock(File::LOCK_EX)
SomeModel.new.save!
file.flock(File::LOCK_UN)
end
end
end
我也遇到了同样的奇怪行为。我在 Controller 而不是ActiveJob 中尝试了相同的方法。相同:ActiveRecord 查询处的死锁。
你们知道在 Rails 应用程序中按顺序执行任务的方法吗?创建临界区的正确方法?
也许有ActiveJob 队列适配器,它是单线程的,没有上下文切换等?我不想在我的简单应用中添加 redis 或其他东西。
【问题讨论】:
标签: ruby-on-rails ruby multithreading activerecord rails-activejob