Hi, I am developing a web based game in which people try to guess the concealed word in a collaborative manner. As you already take for granted, I use ruby on rails on the server side. But I have a problem, I synchronize the method which arranges games and informs the users using a Mutex. Though I didn''t tested heavily, it seemed to work on the development server. But when I deployed the project onto the production server, it seems that it''s not functioning (or there may be some other problem) On the development, I use a mongrel server, which I start on the command line (script/server -b bla bla -p 3000) On the production server, I use Passenger with the default settings. First I suspected that this problem is originating because Passenger was spawning processes and they are not sharing the mutex. But I checked the documentation but couldn''t find a mention of it. And in this link (http://m.onkey.org/2008/10/23/thread-safety-for-your-rails) it says that it''s OK to use Mutexes (though not mentioning the multiprocess passenger). What do you think the problem is about? I am posting a code snippet which exemplifies my usage of Mutexes. Here is the relevant versions: Production: Passenger: 2.2.2 Apache: 2.2.8-1ubuntu0.9 About your application''s environment Ruby version 1.8.6 (x86_64-linux) RubyGems version 1.3.1 Rack version 1.0 bundled Rails version 2.3.2 Active Record version 2.3.2 Action Pack version 2.3.2 Active Resource version 2.3.2 Action Mailer version 2.3.2 Active Support version 2.3.2 Edge Rails revision unknown Application root XXXX Environment development Database adapter mysql Development: About your application''s environment Ruby version 1.8.7 (i486-linux) RubyGems version 1.3.1 Rack version 1.0 bundled Rails version 2.3.2 Active Record version 2.3.2 Action Pack version 2.3.2 Active Resource version 2.3.2 Action Mailer version 2.3.2 Active Support version 2.3.2 Edge Rails revision unknown Application root XXXX Environment development Database adapter mysql Database schema version 20090701025248 Here is the code: def GameControl @@semaphore = Mutex.new def GameControl.start_game(user, singlegame = false) @@semaphore.synchronize { do the stuff here which I want to be processed by only one at a time. } end end -- Posted via http://www.ruby-forum.com/.
Onur Gungor
2009-Jul-04 20:31 UTC
Using Mutex''es in a Rails app (WAS: How to Synchronize?)
Hi, I don''t really know whether it''s appropriate to re-post a message. But I think I asked my question in a proper way, and would like to re-post to eliminate the chance of missing the right people for this question. Here is the original message: ----- Onur Gungor wrote: Hi, I am developing a web based game in which people try to guess the concealed word in a collaborative manner. As you already take for granted, I use ruby on rails on the server side. But I have a problem, I synchronize the method which arranges games and informs the users using a Mutex. Though I didn''t tested heavily, it seemed to work on the development server. But when I deployed the project onto the production server, it seems that it''s not functioning (or there may be some other problem) On the development, I use a mongrel server, which I start on the command line (script/server -b bla bla -p 3000) On the production server, I use Passenger with the default settings. First I suspected that this problem is originating because Passenger was spawning processes and they are not sharing the mutex. But I checked the documentation but couldn''t find a mention of it. And in this link (http://m.onkey.org/2008/10/23/thread-safety-for-your-rails) it says that it''s OK to use Mutexes (though not mentioning the multiprocess passenger). What do you think the problem is about? I am posting a code snippet which exemplifies my usage of Mutexes. Here is the relevant versions: Production: Passenger: 2.2.2 Apache: 2.2.8-1ubuntu0.9 About your application''s environment Ruby version 1.8.6 (x86_64-linux) RubyGems version 1.3.1 Rack version 1.0 bundled Rails version 2.3.2 Active Record version 2.3.2 Action Pack version 2.3.2 Active Resource version 2.3.2 Action Mailer version 2.3.2 Active Support version 2.3.2 Edge Rails revision unknown Application root XXXX Environment development Database adapter mysql Development: About your application''s environment Ruby version 1.8.7 (i486-linux) RubyGems version 1.3.1 Rack version 1.0 bundled Rails version 2.3.2 Active Record version 2.3.2 Action Pack version 2.3.2 Active Resource version 2.3.2 Action Mailer version 2.3.2 Active Support version 2.3.2 Edge Rails revision unknown Application root XXXX Environment development Database adapter mysql Database schema version 20090701025248 Here is the code: def GameControl @@semaphore = Mutex.new def GameControl.start_game(user, singlegame = false) @@semaphore.synchronize { do the stuff here which I want to be processed by only one at a time. } end end -- Posted via http://www.ruby-forum.com/.
On Jul 2, 11:10 am, Onur Gungor <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > First I suspected that this problem is originating because Passenger was > spawning processes and they are not sharing the mutex. But I checked the > documentation but couldn''t find a mention of it. And in this link > (http://m.onkey.org/2008/10/23/thread-safety-for-your-rails) it says > that it''s OK to use Mutexes (though not mentioning the multiprocess > passenger). >Mutexes aren''t for cross process synchronisation (unlike a mutex in windows which can be shared across processes). Fred
Frederick Cheung wrote:> On Jul 2, 11:10�am, Onur Gungor <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: >> >> First I suspected that this problem is originating because Passenger was >> spawning processes and they are not sharing the mutex. But I checked the >> documentation but couldn''t find a mention of it. And in this link >> (http://m.onkey.org/2008/10/23/thread-safety-for-your-rails) it says >> that it''s OK to use Mutexes (though not mentioning the multiprocess >> passenger). >> > > Mutexes aren''t for cross process synchronisation (unlike a mutex in > windows which can be shared across processes). > > FredOK. Then it means Mutex''es don''t work in a multi-process Passenger setup. But then how can I synchronize this method''s usage? I am very new to web development so I just heard about database locking. Simply, how should I use the ActiveRecord::Transactions::ClassMethods#transaction and ActiveRecord::Base#lock!? Would it be OK to create a model and its corresponding table for just locking? i.e. Lock model and locks table. Then use them like this: Lock.transaction do lock = Lock.find(1) lock.lock! # do my stuff which should be done by only one process at a time. end Thanks, Onur -- Posted via http://www.ruby-forum.com/.
On Jul 5, 12:04 pm, Onur Gungor <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> OK. Then it means Mutex''es don''t work in a multi-process Passenger > setup. > > But then how can I synchronize this method''s usage? I am very new to web > development so I just heard about database locking. > > Simply, how should I use the > ActiveRecord::Transactions::ClassMethods#transaction and > ActiveRecord::Base#lock!? > > Would it be OK to create a model and its corresponding table for just > locking? i.e. Lock model and locks table.That or rails'' optimistic locking might be useful. I would usually shy away from creating a Lock model, it just seems a bit artificial. I would probably stick a locked_by_foo column on the appropriate model and use that to tell whether a particular object is being updated (and use optimistic locking in conjunction with that) Fred> > Then use them like this: > > Lock.transaction do > > lock = Lock.find(1) > lock.lock! > > # do my stuff which should be done by only one process at a time. > > end > > Thanks, > Onur > -- > Posted viahttp://www.ruby-forum.com/.
Onur Gungor wrote: [...]> > But then how can I synchronize this method''s usage? I am very new to web > development so I just heard about database locking. > > Simply, how should I use the > ActiveRecord::Transactions::ClassMethods#transaction and > ActiveRecord::Base#lock!? > > Would it be OK to create a model and its corresponding table for just > locking? i.e. Lock model and locks table.That would be pointless. If you wrap your DB operations in a transaction, you will automatically get the appropriate locks -- and the DB will keep track of them, so you don''t have to. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
>> >> Would it be OK to create a model and its corresponding table for just >> locking? i.e. Lock model and locks table. > > That would be pointless. If you wrap your DB operations in a > transaction, you will automatically get the appropriate locks -- and the > DB will keep track of them, so you don''t have to. > > Best, > -- > Marnen Laibow-Koser > http://www.marnen.org > marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.orgYes, I got your point. But I think that the situation is not that clear. I don''t know a single model to have a transaction open and be safe after. So you might be right if I had a design which kept that in mind right from the beginning. But -at least as a workaround- I need something like that. A moment ago, I found this: http://kseebaldt.blogspot.com/2007/11/synchronizing-using-active-record.html This is pretty much the functionality I require. I think I will use this. Didn''t anybody require anything like this? Thanks Onur -- Posted via http://www.ruby-forum.com/.
Frederick Cheung wrote:> On Jul 5, 12:04�pm, Onur Gungor <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: >> Would it be OK to create a model and its corresponding table for just >> locking? i.e. Lock model and locks table. > > That or rails'' optimistic locking might be useful. I would usually shy > away from creating a Lock model, it just seems a bit artificial. I > would probably stick a locked_by_foo column on the appropriate model > and use that to tell whether a particular object is being updated (and > use optimistic locking in conjunction with that) > > FredThanks for your response, But as I told in my post replying Marnen, I just don''t know which objects to lock (or because there are several of them). So I will use the Lock model approach for now. Thanks for all your answers, Best Onur -- Posted via http://www.ruby-forum.com/.
Onur Gungor wrote: [...]> > But I think that the situation is not that clear. I don''t know a single > model to have a transaction open and be safe after.That sentence is unclear, but I think you''re saying that the transaction doesn''t fit neatly into any one model. Right? If so, then don''t worry: it doesn''t have to. Transactions affect the whole DB connection, not just one table. If you need to create a separate class to house a multitable transaction, you can do that, but there''s no need to make that class inherit from ActiveRecord or give it a DB table.> > So you might be right if I had a design which kept that in mind right > from the beginning.If your code is telling you that it needs to be refactored, then refactor it instead of kludging around it!> But -at least as a workaround- I need something like > that.Take the time to do it right if possible rather than relying on workarounds.> > A moment ago, I found this: > > http://kseebaldt.blogspot.com/2007/11/synchronizing-using-active-record.html > > This is pretty much the functionality I require. > > I think I will use this.I''ll look at that. But if that comes from November 2007 as the URL implies, it is liable to be out of date: I believe the current Rails version at that time was 1.2.6.> > Didn''t anybody require anything like this? > > Thanks > OnurBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.