[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