ruby-on-rails - 使用 sidekiq 为 activerecord 类编写 worker

标签 ruby-on-rails activerecord sidekiq

我有两个模型类如下:

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

到目前为止,我有这么多代码。无法弄清楚如何对 worker 进行编码:

class FileInfoObserver < ActiveRecord::Observer
  def after_save(file_info)        
    if file_info.status.eql? 2
       FileProcessingJob.perform_async(file_info.id)    
    end
  end
end

worker 如下:

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

这是正确的做法吗?如何启用重试机制?这段代码是线程安全的吗?

最佳答案

对于重试机制,

只需在“include Sidekiq::Worker”之后添加这一行

sidekiq_options queue: :default, retry: 1

它似乎不是多线程网络服务器环境。所以这里不用担心线程安全。

多线程网络服务器环境示例:
How get best performance rails requests parallel sidekiq worker

关于ruby-on-rails - 使用 sidekiq 为 activerecord 类编写 worker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24407304/

相关文章:

ruby-on-rails - ActiveAdmine register_page 和 Controller

ruby-on-rails - 无法在 Windows 10 中安装 tiny_tds

ruby-on-rails - rails + docker + sidekiq + 在 127.0.0.1:6379 上连接到 Redis 时出错(Errno::ECONNREFUSED)

ruby-on-rails - 对于多个 sidekiq 进程,sidekiq 和 postgres 的 activerecord 连接池大小是否合适?

ruby-on-rails - 如何使用 ruby​​ 方法 .present?

ruby-on-rails - Heroku 上的 ActiveRecord PGError 不是本地的

mysql - Rails 选择子查询(没有 finder_sql,如果可能)

ruby-on-rails - Rails find_by_sql - 从字面上使用 "?"而不是作为绑定(bind)变量?

activerecord - Active Record 加入最近的关联对象属性

ruby-on-rails - Sidekiq 卡住应用程序