[Backgroundrb-devel] lost connection 2.0

hemant gethemant at gmail.com
Thu Jan 3 10:48:38 EST 2008


Just sync with trunk, I have merged all the fixes and its fixed now.


On Jan 3, 2008 7:52 PM, Joost Hietbrink (YelloYello)
<joost at yelloyello.com> wrote:
>
>  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
>
>
>
>
>
>
>



-- 
Let them talk of their oriental summer climes of everlasting
conservatories; give me the privilege of making my own summer with my
own coals.

http://gnufied.org


More information about the Backgroundrb-devel mailing list