如何在Rails中实现顺序处理?

时间:2016-11-23 12:37:06

标签: ruby-on-rails ruby multithreading activerecord rails-activejob

我有一项必须以顺序方式执行的任务。数据库写作很简陋。

问题是我很难在Rails 5中实现它。

我正在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 线程/连接存在问题 - 它以某种方式被阻止。但为什么呢?

我已尝试锁定文件:

ActiveJob

我得到了同样奇怪的行为。我在Controller而不是ActiveRecord尝试过相同的操作。同样:ActiveJob查询死锁。

你们知道在Rails应用程序中以顺序方式执行任务的方法吗?创建关键部分的正确方法?

也许有$file队列适配器是单线程的,没有上下文切换等?我不想在我的简单应用程序中添加redis或其他内容。

1 个答案:

答案 0 :(得分:1)

在使用ActiveJob(或任何异步作业框架)时,您可能实现此目的的唯一方法是将作业分解为多个单独的作业,其中第一项工作将下一项工作列为另一项工作。或者您必须通过其他数据存储中的作业存储进度状态,因此每个作业都可以检查以前的作业是否已完成。

互斥锁无法正常工作,因为作业可以在不同的进程/线程中运行,也可以在完全不同的时间运行,具体取决于您的资源。