[Backgroundrb-devel] thread_pooling sleeping

hemant gethemant at gmail.com
Wed Dec 19 16:08:15 EST 2007


On Dec 19, 2007 10:58 PM, Jason LaPier <jason.lapier at gmail.com> wrote:
>
> On Dec 19, 2007 1:18 AM, hemant <gethemant at gmail.com> wrote:
> >
> > Hi Jason,
> >
> > Looks like there is an exception being thrown thats not handled in
> > your code. Here is my sample worker code, similar to yours. I also got
> > similar behaviour as you described, but then i set
> > "Thread.abort_on_exception = true" and also ran backgroundrb in
> > foreground mode(see README file for details).
> >
> > And then it turned out, there was an exception being thrown in my code
> > and hence it was not going beyond first stage. Also, you don't need to
> > protect register_status() with mutex, but rather you should protect
> > status variable with a mutex as demonstrated below.
> >
> >
> > class ErrorWorker < BackgrounDRb::MetaWorker
> >   set_worker_name :error_worker
> >   attr_accessor :worker_status
> >   def create(args = nil)
> >     @worker_status = { }
> >     @status_mutex = Mutex.new
> >     register_status(@worker_status)
> >     Thread.abort_on_exception = true
> >   end
> >
> >   def do_task(user_id)
> >     thread_pool.defer(user_id) do |user_id|
> >       save_status(user_id,:progress,"Started")
> >       t_user = World.find_by_id(user_id)
> >       t_user.change_message
> >       logger.info "message changed"
> >       save_status(user_id,:progress,"message_changed")
> >       t_user.change_name
> >       logger.info "name changed"
> >       save_status(user_id,:progress,"name changed")
> >       t_user.save
> >     end
> >   end
> >
> >   def save_status(user_id,key,data)
> >     @status_mutex.synchronize do
> >       @worker_status[user_id] = { :key => key, :data => data}
> >     end
> >     register_status(@worker_status)
> >     logger.info "status synced for user #{user_id} #{key} #{data}"
> >   end
> > end
> >
> > To stress test I did this:
> >
> > require File.join(File.dirname(__FILE__) + "/../config/environment")
> > p MiddleMan.ask_status(:worker => :error_worker)
> >
> > (7..200).to_a.each do |world_id|
> >   MiddleMan.ask_work(:worker => :error_worker, :worker_method =>
> > :do_task, :data => world_id)
> >   p MiddleMan.ask_status(:worker => :error_worker)
> > end
> >
> > and it worked flawlessly.
> >
> > See if this helps.
> >
>
> Ok, awesome - thanks very much for your help. With the
> abort_on_exception flag and the foreground logging, I was able to
> track down the problem. If you try something like:
>
> def do_task(some_user_id)
>   logger.info "do_task: some_user_id: #{some_user_id.class}"
>   logger.info "starting task - defer to the thread pool"
>
>   thread_pool.defer(some_user_id) do |user_id|
>     logger.info "user_id (in pool): #{user_id.class}"
>     # and the rest of it
>   end
> end
>
> You'll see in the log:
> do_task: some_user_id: Fixnum
> starting task - defer to the thread pool
> user_id (in pool): Array
>
> So some_user_id is being converted to [user_id] for the block. Calling
> AR's find method with an array gives you back an array (which was the
> source of my original exception - trying to act on an Array as if it
> were a User object). When you use User.find_by_id in your example, AR
> is taking just the first element in the array and doing a find on
> that.
>
> I suspect that's a bug in thread_pool, or at least if it's not, it's a
> little confusing syntactically. Now that I know how it works, I've got
> my code working, so if it's not a bug, no problem :)
>
>

Glad that you solved the problem. Yes the block is getting passed
value as an Array is a bug and its fixed now.
Whats more now, if your block throws an exception which you are not
handling, it will be handled by bdrb and logged in backgroundrb.log.

Sync with latest code for all this goodness.


-- 
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