Title: Issue starting backgroundrb server (with Oracle)
Hi Matt,
  I had the same problem as you. The link you referenced pinpoints the problem exactly with Oracle. It may be
that a newer version of Rails fixes the problem, I don't know. I am using Rails 2.1.2 and I had the same problem.

To fix this, I patched my copy of brdb_job_queue.rb located at vendor/plugins/backgroundrb/lib/backgroundrb/brdb_job_queue.rb
using the solution in the link (select all relevant records, then use the first one in the list). I have only used this
with Oracle and am running on linux.

I have attached the file,maybe it will help.

Regards,
Don

Stone, Matthew A wrote:
Hello All,

I’ve recently started trying to use backgroundrb and I’m running into an issue with starting the server.  I’m running OSX (leopard) and rails 2.0.2 with an oracle database.  
When I run ./script/backgroundrb start I get the following error:
/Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract_adapter.rb:150:in `log': OCIError: ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.: select * from (select raw_sql_.*, rownum raw_rnum_ from (SELECT * FROM event_tracking.bdrb_job_queues   WHERE ( worker_name = 'upload_invitees_worker' AND taken = 0 AND scheduled_at <= '2009-03-19 13:38:04' ) ) raw_sql_ where rownum <= 1) where raw_rnum_ > 0 FOR UPDATE (ActiveRecord::StatementInvalid)

I’ve read in a few places that when using Oracle it may be a good idea to remove the lines that say allow_concurrency = true, and I’ve done that.

Also, I saw that there may be an issue with oracle adapter with a SELECT ... FOR UPDATE statement locking rows here: http://kseebaldt.blogspot.com/2007/11/synchronizing-using-active-record.html   The comment points to this occurring with backgroundrb.

I would appreciate any help that you all can provide.

Thanks,
Matt Stone

_______________________________________________ Backgroundrb-devel mailing list [email protected] http://rubyforge.org/mailman/listinfo/backgroundrb-devel


# Model for storing jobs/tasks persisted to the database

class BdrbJobQueue < ActiveRecord::Base
  validates_uniqueness_of :job_key,:scope => [:worker_name,:worker_key]
  # find next task from the table
  def self.find_next(worker_name,worker_key = nil)
    returned_job = nil
    transaction do
      unless worker_key
        #use ruby time stamps for time calculations as db might have different 
times than what is calculated by ruby/rails
        # Made fix to work with oracle
        # t_job = find(:first,:conditions => [" worker_name = ? AND taken = ? 
AND scheduled_at <= ? ", worker_name, 0, Time.now.utc ],:lock => true)
        jobs = find(:all,:conditions => [" worker_name = ? AND taken = ? AND 
scheduled_at <= ? ", worker_name, 0, Time.now.utc ],:lock => true)
      else
        jobs = find(:all,:conditions => [" worker_name = ? AND taken = ? AND 
worker_key = ? AND scheduled_at <= ? ", worker_name, 0, worker_key, 
Time.now.utc ],:lock => true)
      end
      t_job = nil
      if jobs.size > 0
        t_job = jobs.first
        if t_job
          t_job.taken = 1
          t_job.started_at = Time.now.utc
          t_job.save
          returned_job = t_job
        end  
      end
    end
    returned_job
  end

  # release a job and mark it to be unfinished and free.
  # useful, if inside a worker, processing of this job failed and you want it 
to process later
  def release_job
    self.class.transaction do
      self.taken = 0
      self.started_at = nil
      self.save
    end
  end

  # insert a new job for processing. jobs added will be automatically picked by 
the appropriate worker
  def self.insert_job(options = { })
    transaction do
      options.merge!(:submitted_at => Time.now.utc,:finished => 0,:taken => 0)
      t_job = new(options)
      t_job.save
    end
  end

  # remove a job from table
  def self.remove_job(options = { })
    transaction do
      #Made fix to work with oracle
      tjobs =  find(:all, :conditions => options.merge(:finished => 0,:taken => 
0),:lock => true)
      if tjobs.size > 0
        t_job_id = tjobs.first  
        delete(t_job_id)
      end
    end
  end

  # Mark a job as finished
  def finish!
    self.class.transaction do
      self.finished = 1
      self.finished_at = Time.now.utc
      self.job_key = "finished_#{Time.now.utc.to_i}_#{job_key}"
      self.save
    end
    Thread.current[:persistent_job_id] = nil
    Thread.current[:job_key] = nil
    nil
  end
end
_______________________________________________
Backgroundrb-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/backgroundrb-devel

Reply via email to