【发布时间】:2014-08-01 18:37:28
【问题描述】:
我有两个模型类如下:
class FileInfo < ActiveRecord::Base
STATUS = {:UNAPPROVED => 1, :APPROVED => 2, :PROCESSED => 3 }
attr_accessible :id, :status
validates :status, :inclusion => {:in => STATUS.values}
end
FileInfo 有 id 和 status 字段。每个文件可以有多个FileEntry 类型的文件条目(行)。 FileEntry 有 id、file_info_id(FileInfo 的外键)和状态字段。
class FileEntry < ActiveRecord::Base
STATUS = {:UNAPPROVED => 1, :READY => 2 , :SENT => 3 }
attr_accessible :id, :file_info_id, :status, :reason
validates :status, :inclusion => {:in => STATUS.values}
end
我想写一个worker来异步处理状态字段为APPROVED(FileInfo模型)的所有文件。每个线程都应处理状态为READY 的特定文件的所有文件条目。一旦为该文件处理了所有条目,该线程应该完成。假设状态为UNAPPROVED 的文件条目也将变为READY。
处理完每个条目后,其状态应更新为SENT。一旦所有文件条目都具有特定文件的SENT 状态,则将该文件的状态更新为PROCESSED。
到目前为止,我有这么多代码。无法弄清楚如何对工人进行编码:
class FileInfoObserver < ActiveRecord::Observer
def after_save(file_info)
if file_info.status.eql? 2
FileProcessingJob.perform_async(file_info.id)
end
end
end
工人如下:
class FileProcessingJob
include Sidekiq::Worker
def perform(file_id)
puts "job"
flag =1
while flag==1
count = 0
FileEntry.where("file_info_id = #{file_id}").find_each do |file_entry|
if(file_entry.status == 2)
puts "update" //Some PUT request, instead wrote a puts statement
FileEntry.update(file_entry.id, :status => 3)
elsif(file_entry.status == 0 || file_entry.status ==1)
count = count + 1
end
end
if(count == 0)
flag = 0
end
end
end
end
这是正确的做法吗?如何启用重试机制?这段代码是线程安全的吗?
【问题讨论】:
-
有人可以对此发表评论吗?对我来说看起来不错。我们如何确保线程安全? FileRow 可以分批更新而不是一次更新吗?
-
FileRow是什么?是FileEntry? -
哦,我的错。它是文件条目。我已经编辑过了。
标签: ruby-on-rails activerecord sidekiq