[Backgroundrb-devel] When to use Mutex::synchronize?

Ezra Zygmuntowicz ezmobius at gmail.com
Wed Jul 12 11:37:52 EDT 2006


On Jul 11, 2006, at 10:37 PM, Ben Johnson wrote:

> I have a simple question when to the synchronize method in the  
> Mutex class.
>
> Now that backgroundrb has allow_concurrency = true there is no need  
> to synchronize database calls in threads.
>
> The question I have is lets say I have a simple method in my worker  
> as follows:
>
> def some_method
> 	SomeModel.find_all each do |obj|
> 		obj.some_count += 1
> 		obj.save!
> 	end
> end
>
> It accesses the database, but is not in a thread. Since this is a  
> single process running in the background, if that method gets  
> called simultaneously will the database lose connection? Will I get  
> unexpected results? For instance, if 500 people access  
> www.somedomain.com/controller/method which calls that method in the  
> backgroundrb process will it screw everything up?
>
> Basically do I need to wrap that in a synchronize method? Like this:
>
> def some_method
> 	@mutex_obj.snchronize do
> 		SomeModel.find_all each do |obj|
> 			obj.some_count += 1
> 			obj.save!
> 		end
> 	end
> end
>
> Thanks a lot for your help.
>
> Thank You,
> Ben Johnson
> E: bjohnson at contuitive.com
>

Ben-

	It all depends on what you want to happen. If you only want one call  
to that method at a time to be running then yes you will want to  
synchronize access to that method. You will need to create your own  
mutex object. Also I will answer your other question at the same time  
here as it looks like they are related. You asked:

"Can I not do things with the models in my initialize method? I have  
this:

def initialize(args)
	super args

	i = 0
	Event.find_all do |event|
		@lock = i
		i += 1
	end
end
"

Yes you can use your db models in initialize but you must do it  
slightly differently then you have done here. This is also where you  
would create a mutex for your worker to use to guard certain actions.


class BenWorker < BackgrounDRb::Rails

   def initialize(args)
     @mymutex = Mutex.new
     Event.find_all do |event|
	@lock = i
	i += 1
     end
     super
   end

  def some_method
	@mymutex.snchronize do
		SomeModel.find_all each do |obj|
			obj.some_count += 1
			obj.save!
		end
	end
end


end


	So you must do whatever it is you need to do in initialize before  
you call super. ANd call super without any args. Because when you  
call super it spins off the thread to start running do_work inside  
of. Now since your some_method method is making changes to the db  
then yes you should synchronize access to it or else you will get  
undefined results. If the method was just checking for progress or  
doing something that just reads state and doesn't change it then you  
can probably get away without a mutex. Just think about what you are  
doing carefully. The more mutex locking you build the slower and more  
complex things get. Multi threading is hard stuff ;)

Cheers-
-Ezra

>




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


More information about the Backgroundrb-devel mailing list