user3752649
user3752649

Reputation: 67

Writing worker using sidekiq for activerecord class

I have two model classes as follows:

class FileInfo < ActiveRecord::Base
  STATUS = {:UNAPPROVED => 1, :APPROVED => 2, :PROCESSED => 3 }
  attr_accessible :id, :status
  validates :status, :inclusion => {:in => STATUS.values}    
end

FileInfo has id and status fields. Each file can multiple file-entries (rows) of the type FileEntry. FileEntry has id, file_info_id (foreign key of FileInfo) and status fields.

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

I want to write a worker to asynchronously process all files whose status field is APPROVED (FileInfo model). Each of the thread should process all file-entries for that particular file whose status is READY. The thread should finish once all the entries are processed for that file. Assuming that File-entries having status UNAPPROVED will also become READY.

Once each entry is processed, its status should be updated as SENT. Once all the file-entries all have SENT status for a particular file, update that file's status as PROCESSED.

I have code this much so far. Not able to figure out how to code the 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

The worker is as follows:

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

Is this correct way of doing it? How to enable retry mechanism? Is this code thread-safe?

Upvotes: 3

Views: 1024

Answers (1)

Ranjithkumar Ravi
Ranjithkumar Ravi

Reputation: 3492

For retry mechanism,

Just add this line, after "include Sidekiq::Worker"

sidekiq_options queue: :default, retry: 1

Seems its not a multithreaded web-server environment. So don't worry about thread-safety here.

Sample for multithreaded web-server environment:
How get best performance rails requests parallel sidekiq worker

Upvotes: 1

Related Questions