[Backgroundrb-devel] lost connection 2.0

Joost Hietbrink (YelloYello) joost at yelloyello.com
Thu Jan 3 09:22:40 EST 2008


The problem has occurred again... :( (with the 'thread_fix.tar.gz' version).
Should we set 'allow_concurrency' in the environment? Because we didn't 
do that yet..

Joost

hemant wrote:
> Hi Joost,
>
> I am attaching a version of plugin that fixes issues with mysql lost
> connections. Can you try and let me know, how were the results.
>
>
> On Dec 30, 2007 2:25 AM, Joost Hietbrink <joost at yelloyello.com> wrote:
>   
>>  This is the 'main' worker we created.. The problem is still occurring.. I
>> did not yet put the config things in environment.rb (like I said on:
>> http://rubyforge.org/pipermail/backgroundrb-devel/2007-December/001233.html)..
>> so maybe that fixes it?
>>
>>  Hope you can help..
>>
>>
>>  hemant wrote:
>>  Hi Joost,
>>
>> On Dec 28, 2007 5:25 PM, Joost Hietbrink (YelloYello)
>> <joost at yelloyello.com> wrote:
>>
>>
>>  The rails_model_worker.rb contains a module that fetches an object from the
>> database.
>>  We pass parameters to the worker (like classname & id (eg. Place and
>> 12312)) and fetch the object again in the worker (using this module method).
>>
>>  The lost connection occurs when we try to fetch the object (record) again
>> (in the worker..using the included module method).
>>
>>  The old BackgroundRb did not support sending ActiveRecord objects to the
>> worker (thats why we refetch it)..does the new version??
>>
>>  We now also installed libmysql-ruby1.8 (see:
>> http://wiki.rubyonrails.org/rails/pages/Mysql%2BConnection%2BProblems) so
>> maybe this fixes the problem..but we have to wait some time to see.. :)
>>
>>
>>  Sorry for late reply. But If you can send me the worker code, I will
>> try to fix it.
>> There seems to be some problems with AR in threaded environment. I
>> just want to make sure, none remain unfixed.
>>
>>
>>
>>
>> module RailsModelWorker
>> # Methods to be implemented in subclass
>>
>>   # execute_job should implement the work you want to be done, it is called
>> with the instance of the
>>   # rails model object, a boolean stating whether more jobs are already
>> waiting
>>   # (which can be used to postpone some general work to the last job in the
>> queue),
>>   # and a hash containing any extra arguments (which is validated to be a
>> hash before the call)
>>   # obj is not nil when entering this call
>> #  def execute_job(obj, pending_jobs, args)
>> #    raise NotImplementedError, "execute_job is an abstract method"
>> #  end
>>
>>   # parse_args can be optionally implemented, use it to set @var's which you
>> use in execute_job
>>   # it should accept an hash of arguments (which is validated to be a hash
>> before the call)
>> #  def parse_args(args)
>> #    raise NotImplementedError, "parse_args is an abstract method"
>> #  end
>>
>> # General methods
>>
>>   def create(args)
>>     log("new worker created")
>>     register_status(:booting)
>>     @job_queue = Array.new
>>
>>     if args.nil?
>>       errlog("weird: args argument of do_work is nil!")
>>     elsif !args.is_a?(Hash)
>>       errlog("weird: args argument of do_work is not a Hash")
>>     elsif !args.has_key?(:record_type)
>>       errlog("weird: args argument of do_work does not contain
>> :record_type")
>>     else
>>       @record_type = args[:record_type]
>>     end
>>
>>     if args.has_key?(:args) && args[:args].is_a?(Hash)
>>       parse_args(args[:args]) if defined?(parse_args)
>>     end
>>
>>     # This method is called in it's own new thread when you
>>     # call new worker. args is set to :args
>>     register_status(:running)
>>     @timer = add_periodic_timer(5) do
>>       if @job_queue.nil? || !@job_queue.is_a?(Array)
>>         register_status(:dead)
>>         cancel_timer(@timer) if !@timer.nil?
>>         errlog("weird: our job_queue object is nil or not Array
>> #{@job_queue}")
>>       else
>>         start_work() if @job_queue.size > 0
>>       end
>>     end
>>   end
>>
>>   def request_work(params)
>>     log("work requested")
>>     id = params[:id]
>>     args = params[:args]
>>     if id.blank?
>>       errlog("weird: id argument of request_indexing is nil")
>>     elsif @job_queue.nil? || !@job_queue.is_a?(Array)
>>       errlog("weird: our job_queue object is nil or not Array
>> #{@job_queue}")
>>     elsif args.nil? || !args.is_a?(Hash)
>>       errlog("weird: our args argument is nil or not Hash #{args}")
>>     else
>>       @job_queue.each do |job|
>>         job[:pending_jobs] = true
>>       end
>>       @request_time = Time.now
>>       @job_queue << { :object_id => id, :request_time => @request_time,
>> :args => args}
>> # TODO: map this to the new backgroundrb
>> #      results[:last_request_at] = @request_time
>>     end
>>   end
>>
>>   def start_work()
>>     result = false
>>     begin
>>       if @job_queue.nil? || !@job_queue.is_a?(Array)
>>         raise "weird: our job_queue object is nil or not Array
>> #{@job_queue}"
>>       end
>>       job = @job_queue.shift
>>       if job.nil? || !job.is_a?(Hash)
>>         raise "weird: our current job is not a Hash or nil: #{job}"
>>       elsif job[:object_id].nil?
>>         raise "weird: we got a nil object_id"
>>       elsif job[:args].nil?
>>         raise "weird: we got a nil args"
>>       elsif @record_type.nil?
>>         raise "weird: we can't do work because @record_type is nil"
>>       end
>>       log("Fetch rails object..")
>>       for i in 1..10 do
>>         obj = refetch_record(job[:object_id])
>>         if obj.nil?
>>           raise "Failed to retrieve object" if i == 10
>>           sleep(1)
>>           next
>>         end
>>         break
>>       end
>>       log("Start work..")
>>       execute_job(obj, job[:pending_jobs], job[:args]) if
>> defined?(execute_job)
>>       log("Work done..")
>>       result = true
>>     rescue StandardError => e
>>       errlog("Work failed.. Exception raised: #{e}")
>>       #TODO: email about any exception thrown by execute_job. Something like
>> this but with correct stubs
>>       # if RAILS_ENV == 'production'
>>         # request_stub = ActionController::AbstractRequest.new
>>         # request_stub.instance_eval('@env={}')
>>         # controller_stub = ApplicationController.new
>>         # ExceptionNotifier.deliver_exception_notification(exception,
>> controller_stub, request_stub, {})
>>       # end
>>     end
>>     # Sets the global results hash to contain last result for this index
>>     # Access it using: worker.results.to_hash[:success]
>> # TODO: map this to the new backgroundrb
>> #        results[:last_success_at] = job[:request_time] if result
>> #        results[:success] = result
>>     return result
>>   end
>>
>>   def refetch_record(id)
>>     result = nil
>>     begin
>>       result = @record_type.constantize.find(id)
>>     rescue NameError => e
>>       raise "Cannot get object of non existing model #{@record_type},
>> exception #{e.to_s}"
>>     end
>>     return result
>>   end
>>
>>   # Write to log/backgroundrb.log with class-name as prefix
>>   def log(s, type='info')
>>     logger.info("#{Time.now.strftime("%Y%m%d-%H:%M:%S")} (#{type})
>> #{self.class}: #{s}")
>>   end
>>   def errlog(s)
>>     log(s, 'error')
>>   end
>>   def debuglog(s)
>>     log(s, 'debug')
>>   end
>>   def warnlog(s)
>>     log(s, 'warning')
>>   end
>> end
>>
>>     
>
>
>
>   

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/backgroundrb-devel/attachments/20080103/c22f937a/attachment.html 


More information about the Backgroundrb-devel mailing list