Overwrite active_record find?

Hey!

i need to overwrite active record find to synchronize database access

You need to say super(*args). alias_method_chain is usually a more
prudent choice for this sort of stuff (and i assume you know that this
won't accomplish anything if you're using a pack of mongrels or
whatever - I suppose it would work if you had a single multithreaded
script, but I'm still not sure what the point would be)

Fred

Frederick Cheung wrote:

You need to say super(*args). alias_method_chain is usually a more prudent choice for this sort of stuff (and i assume you know that this won't accomplish anything if you're using a pack of mongrels or whatever - I suppose it would work if you had a single multithreaded script, but I'm still not sure what the point would be)

Fred

Problem is I'm using active_record without rails on a application that includes a mini http server (built on top of webrick) and a background task. Both operate on the same sqlite db. Because of concurrency issues with sql I'm trying to synchronize access to the database.

Iven with super(*args) i still get the error:

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1227:in `find_initial': undefined method `first' for nil:NilClass (NoMethodError)         from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1514:in `send'         from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1514:in `find_by_requesttype_and_requeststatus'

Frederick Cheung wrote:

You need to say super(*args). alias_method_chain is usually a more prudent choice for this sort of stuff (and i assume you know that
this won't accomplish anything if you're using a pack of mongrels or whatever - I suppose it would work if you had a single multithreaded script, but I'm still not sure what the point would be)

Fred

Problem is I'm using active_record without rails on a application that includes a mini http server (built on top of webrick) and a background task. Both operate on the same sqlite db. Because of concurrency
issues with sql I'm trying to synchronize access to the database.

Iven with super(*args) i still get the error:

Should have been obvious - it looks like you're not returning the
right value (ie the result) from find_by_sql. Also bear in mind that
find will call find_by_sql in some cases, so make sure whatever
locking mechanism you're using will support that. I've got a hint of a
doubt that by background task you mean a separate process, in which
case you're out of luck (because each process would have its own lock).

Fred

Frederick Cheung wrote:

Should have been obvious - it looks like you're not returning the right value (ie the result) from find_by_sql. Also bear in mind that find will call find_by_sql in some cases, so make sure whatever locking mechanism you're using will support that. I've got a hint of a doubt that by background task you mean a separate process, in which case you're out of luck (because each process would have its own lock).

I switched the locking mechanism to thread.exclusive, because a mutex doesn't work because find is calling find_by_sql. Added the returns.

def self.find(*args)            begin                 #@@semaphore.synchronize {                     Thread.exclusive {                         #puts "find"                         return super(args)

                    }                 #}             rescue                 puts "error: "+$!                # @@semaphore.unlock             end         end

        def self.find_by_sql(sql)            begin                 #@@semaphore.synchronize {                     Thread.exclusive {                       #puts "find_by_sql"                       return super(sql)                     }                 #}             rescue                 puts "error: "+$!                # @@semaphore.unlock             end         end

By background task is a second thread, not a seperate process, so the locking mechanism should work.

Is every find call using find_by_sql to retrieve data? Would it be enough to syncronize just find_by_sql then?

thx

Frederick Cheung wrote:

Should have been obvious - it looks like you're not returning the right value (ie the result) from find_by_sql. Also bear in mind that find will call find_by_sql in some cases, so make sure whatever locking mechanism you're using will support that. I've got a hint
of a doubt that by background task you mean a separate process, in which case you're out of luck (because each process would have its own
lock).

I switched the locking mechanism to thread.exclusive, because a mutex doesn't work because find is calling find_by_sql. Added the returns.

By background task is a second thread, not a seperate process, so the locking mechanism should work.

Is every find call using find_by_sql to retrieve data? Would it be enough to syncronize just find_by_sql then?

Almost all. a find with an :include doesn't in rails 2.0.2. This sort
of thing could change in the future though.

Fred

FWIW you can just use super [with no args] if it’s going to use the same arguments passed to the method. This works even if you modify the arguments like:

def label(object_name, method, text = nil, options = {}) text ||= method.to_s.titleize super end

RSL