Walter
2006-May-23 13:59 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
Hi, I am trying to run Mongrel on win32 to serve an internal rails application. We are accessing legacy data, and some transactions can take 5 to 10 seconds. This is holding up every other request. The -n does not seem to be supported on Win32. Am I missing something, or should I look elsewhere to serve my Rails app on win32? Thanks, Walt -- No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.1.392 / Virus Database: 268.7.0/345 - Release Date: 5/22/2006
Rick Olson
2006-May-23 14:04 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
On 5/23/06, Walter <Walter at mwsewall.com> wrote:> Hi, > > I am trying to run Mongrel on win32 to serve an internal rails application. > > We are accessing legacy data, and some transactions can take 5 to 10 seconds. This is holding up every other request. The -n does not seem to be supported on Win32. > > Am I missing something, or should I look elsewhere to serve my Rails app on win32? > > > Thanks, > > WaltRails is not thread-safe, so mongrel locks it. You could implement these tasks in a custom mongrel handler, or look into ezra''s backgrounddrb plugin. http://www.brainspl.at/articles/2006/05/15/backgoundrb-initial-release -- Rick Olson http://techno-weenie.net
Walter
2006-May-23 14:15 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
> Rails is not thread-safe, so mongrel locks it. You could implement > these tasks in a custom mongrel handler, or look into ezra''s > backgrounddrb plugin. > > http://www.brainspl.at/articles/2006/05/15/backgoundrb-initial-release > > -- > Rick Olson > http://techno-weenie.net >I realize that mongrel is not thread safe, I was hoping mongrel might spawn a few processes and serve them in the background to emulate what I wanted. I have looked at the backgrounddrb plug-in and will use that for things like statement generation, and very long running tasks. The problem is I am accessing a system that I cannot change (for the time being) and the length of time for the queries are directly proportional to how much data each customer may have. So most queries are fast enough, but some customers have so much data that they bog things down. I would have to make everything a remote call, more work and overhead than I am looking for. On top of that I cannot change the indexes or table structure (we are accessing tables that another program accesses). At some point we will build a new system from scratch to address these issues, but for the time being I am stuck with what I have. Anyone know of a simple win32 web proxy that can deal with multiple mongrel servers? Thanks, Walt -- No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.1.392 / Virus Database: 268.7.0/345 - Release Date: 5/22/2006
Luis Lavena
2006-May-23 14:41 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
On 5/23/06, Walter <Walter at mwsewall.com> wrote: [...]> I realize that mongrel is not thread safe, I was hoping mongrel might spawn a few processes and serve them in the background to emulate what I wanted. >Rails is not thread-safe.> I have looked at the backgrounddrb plug-in and will use that for things like statement generation, and very long running tasks. The problem is I am accessing a system that I cannot change (for the time being) and the length of time for the queries are directly proportional to how much data each customer may have. So most queries are fast enough, but some customers have so much data that they bog things down. I would have to make everything a remote call, more work and overhead than I am looking for. > > On top of that I cannot change the indexes or table structure (we are accessing tables that another program accesses). At some point we will build a new system from scratch to address these issues, but for the time being I am stuck with what I have. >The idea of the BackgroundDrb is that you perform these task out-of-bound from the webserver/dispatcher/rails, so it could handle other request and also you could "query" the status of the bulk process. No matter how many processors you spawn (even if the -n param was available in win32 service)... 1 Controller call would hang the whole server until it return, thats why the suggestion of using BackgroundDRb. If your lengthly process need parse or perform actions using the model, I will comment that something isn''t in the right place. Using Apache or Lighttpd will require you use FCGI, which also mean that you will need to "synchronize" your transactions to the DB to avoid corrupt data.> Anyone know of a simple win32 web proxy that can deal with multiple mongrel servers?Couldn''t find one, thats why start working on it, but still a lot of work to do. Regards, -- Luis Lavena Multimedia systems - Leaders are made, they are not born. They are made by hard effort, which is the price which all of us must pay to achieve any goal that is worthwhile. Vince Lombardi
Kevin C
2006-May-24 00:13 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
I''m confused here. Does this not-thread-safe mean we can only run ONE mongrel for ONE app on ONE server? Can we start another mongrel for the same app on the same server but on a different port (and serve through proxy)? I suppose we can run another mongrel for the same app on another server. -- Kevin Chen http://www.realmatic.com
Wilson Bilkovich
2006-May-24 00:33 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
On 5/23/06, Kevin C <born70s at gmail.com> wrote:> I''m confused here. > > Does this not-thread-safe mean we can only run ONE mongrel for ONE app > on ONE server? Can we start another mongrel for the same app on the > same server but on a different port (and serve through proxy)? > > I suppose we can run another mongrel for the same app on another server. >Mongrel is fine, and happy running 100 copies on one server. Rails itself is not thread-safe, and that means you need one Mongrel (or FastCGI instance, or WEBrick, or whatever) per Rails process. If you want to run three Rails apps, you need three somethings (preferably Mongrels).
Zed Shaw
2006-May-24 01:03 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
On Tue, 2006-05-23 at 17:13 -0700, Kevin C wrote:> I''m confused here. > > Does this not-thread-safe mean we can only run ONE mongrel for ONE app > on ONE server? Can we start another mongrel for the same app on the > same server but on a different port (and serve through proxy)? > > I suppose we can run another mongrel for the same app on another server. >Short explanation: Yes, this is normally what you have to do to get a good production setup going. Here''s the long explanation that should help you understand what''s going on. First, the Mongrel way: 1) Mongrel is thread safe as far as it will run any registered handlers in threads and make sure that multiple threads have their own resources. 2) Mongrel HttpHandler objects are connected to URIs, but there''s only one per each URI. This means that they run fast since there''s no object creation, but that they are very old school and a pain to develop for, only useful for people who really need the speed. 3) Mongrel handlers are run in order using a processing chain. Let''s say you register 4 handlers to "/": uri "/", :handler => AuthenticationFilter.new uri "/", :handler => DoFastStuffHandler.new uri "/", :handler => StatisticsFilter.new uri "/", :handler => DeflateFilter.new What happens is that each of these is run in order with the same HttpRequest and HttpResponse objects, they get their turn, and then the final results are sent back to the user. (NOTE: Filter and Handler are both HttpHandler classes, just named differently for clarity). 4) When your handler runs, any instance variables (@foo) are reused by all the threads. You have to work to guard these yourself. It''s much like old-school Java servlet programming. This is done for speed only, and most people won''t be writing handlers unless they are uber advanced. OK, so now how does rails fit into things? The problem with Rails is that it''s got so much code generation and automagic going on that it''s really difficult to make it thread safe. Things would be different if Ruby could ensure that it''s code generation and class loading were atomic, but it can''t. Because of this Rails has to be locked while it''s processing. So, let''s say you hit a Rails action with one thread, then this is what happens: 1) RailsHandler first checks if the request could be page cached or is a file. a) If it is then the DirHandler takes over instead. THIS IS FAST AND NOT LOCKED. Done, next request. 2) RailsHandler determines that this isn''t a file and isn''t page cached, so it must run the Rails Dispatcher to service the request. 3) LOCK!!! But only the call to Dispatcher, the rest of Mongrel keeps trucking. 4) Wait hours for everyone''s IO.popen to a perl script that talks to ten databases to produce a full index of the internet and then image map it to generate a CAPTCHA. 5) While the above is happening, #1 and #2 still keep going processing clients. Mongrel is threaded so it happily queues clients up that are all waiting at #3. 6) UNLOCK. #4 completes THE FIGHT BEGINS! Whichever client stuck at #3 gets the lock will then continue and you''re back at #3. 7) Continue until your IO.popen kills server. Incidentally, the results of the Rails request are sent back to the client *after* the lock is released. Rails actually spits its junk to a StringIO so that it can get done without worrying about socket crap, and then Mongrel deals with the IO and threads from there. (I''m mentioning IO.popen because it''s incredibly evil, don''t use it or fork). Now, what this generally means is if you have page caching turned on and most of your rails requests are pretty snappy, then you can most likely handle quite a few concurrent users without any problems. As long as clients get in and get out of the #3 through #6 LOCK/UNLOCK region you''re set. It also means that you only pay a lock penalty for Rails to run it''s action and generate results to a StrinIO. Mongrel handles all the socket garbage in a threaded way. The problem comes when folks expect Rails to be an operating system. They have it spawning processes, managing tons of files, generating maps and reports and latex output and putting them through pre-press operations that take 10 minutes. When this happens you have 3 choices: 1) Only let one person use the application. 2) Start a bunch of Mongrels listening on various ports (on various machines) and use pound, pen, balance, lighttpd, litespeed, or apache to proxy requests for a "fronting" machine to the N backends. 3) Rewrite your stuff to use BackgroundDRB or some other custom off-load worker server, and use a nice AJAX "Job in progress..." set of actions to keep things snapppy. Best part about this is you can actually shove a large portion of the status out into a Mongrel handler (now you know why I covered it). Now, why doesn''t Mongrel do forking you may ask? All my tests found that the fork available in Ruby just isn''t reliable. It causes IO to get dropped, sockets to go away, files get closed at weird times, and it''s just generally bad news. Also, fork isn''t really well supported on win32. Nope, it''s just loads easier to use mongrel_cluster to manage a ton of systems, or to setup a bunch of win32 services that listen on different ports. Well, hope that long answer helped you out. -- Zed A. Shaw http://www.zedshaw.com/ http://mongrel.rubyforge.org/
scott burton
2006-May-24 16:09 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
Sounds like a Mongrel/Rails performance post on http://mongrel.rubyforge.org/ waiting to happen :) On 5/23/06, Zed Shaw <zedshaw at zedshaw.com> wrote:> > On Tue, 2006-05-23 at 17:13 -0700, Kevin C wrote: > > I''m confused here. > > > > Does this not-thread-safe mean we can only run ONE mongrel for ONE app > > on ONE server? Can we start another mongrel for the same app on the > > same server but on a different port (and serve through proxy)? > > > > I suppose we can run another mongrel for the same app on another server. > > > > Short explanation: Yes, this is normally what you have to do to get a > good production setup going. > > Here''s the long explanation that should help you understand what''s going > on. First, the Mongrel way: > > 1) Mongrel is thread safe as far as it will run any registered handlers > in threads and make sure that multiple threads have their own resources. > 2) Mongrel HttpHandler objects are connected to URIs, but there''s only > one per each URI. This means that they run fast since there''s no object > creation, but that they are very old school and a pain to develop for, > only useful for people who really need the speed. > 3) Mongrel handlers are run in order using a processing chain. Let''s > say you register 4 handlers to "/": > uri "/", :handler => AuthenticationFilter.new > uri "/", :handler => DoFastStuffHandler.new > uri "/", :handler => StatisticsFilter.new > uri "/", :handler => DeflateFilter.new > > What happens is that each of these is run in order with the same > HttpRequest and HttpResponse objects, they get their turn, and then the > final results are sent back to the user. (NOTE: Filter and Handler are > both HttpHandler classes, just named differently for clarity). > 4) When your handler runs, any instance variables (@foo) are reused by > all the threads. You have to work to guard these yourself. It''s much > like old-school Java servlet programming. This is done for speed only, > and most people won''t be writing handlers unless they are uber advanced. > > OK, so now how does rails fit into things? The problem with Rails is > that it''s got so much code generation and automagic going on that it''s > really difficult to make it thread safe. Things would be different if > Ruby could ensure that it''s code generation and class loading were > atomic, but it can''t. Because of this Rails has to be locked while it''s > processing. > > So, let''s say you hit a Rails action with one thread, then this is what > happens: > > 1) RailsHandler first checks if the request could be page cached or is a > file. > a) If it is then the DirHandler takes over instead. THIS IS FAST > AND NOT LOCKED. Done, next request. > 2) RailsHandler determines that this isn''t a file and isn''t page cached, > so it must run the Rails Dispatcher to service the request. > 3) LOCK!!! But only the call to Dispatcher, the rest of Mongrel keeps > trucking. > 4) Wait hours for everyone''s IO.popen to a perl script that talks to ten > databases to produce a full index of the internet and then image map it > to generate a CAPTCHA. > 5) While the above is happening, #1 and #2 still keep going processing > clients. Mongrel is threaded so it happily queues clients up that are > all waiting at #3. > 6) UNLOCK. #4 completes THE FIGHT BEGINS! Whichever client stuck at #3 > gets the lock will then continue and you''re back at #3. > 7) Continue until your IO.popen kills server. Incidentally, the results > of the Rails request are sent back to the client *after* the lock is > released. Rails actually spits its junk to a StringIO so that it can > get done without worrying about socket crap, and then Mongrel deals with > the IO and threads from there. > > (I''m mentioning IO.popen because it''s incredibly evil, don''t use it or > fork). > > Now, what this generally means is if you have page caching turned on and > most of your rails requests are pretty snappy, then you can most likely > handle quite a few concurrent users without any problems. As long as > clients get in and get out of the #3 through #6 LOCK/UNLOCK region > you''re set. It also means that you only pay a lock penalty for Rails to > run it''s action and generate results to a StrinIO. Mongrel handles all > the socket garbage in a threaded way. > > The problem comes when folks expect Rails to be an operating system. > They have it spawning processes, managing tons of files, generating maps > and reports and latex output and putting them through pre-press > operations that take 10 minutes. When this happens you have 3 choices: > > 1) Only let one person use the application. > 2) Start a bunch of Mongrels listening on various ports (on various > machines) and use pound, pen, balance, lighttpd, litespeed, or apache to > proxy requests for a "fronting" machine to the N backends. > 3) Rewrite your stuff to use BackgroundDRB or some other custom off-load > worker server, and use a nice AJAX "Job in progress..." set of actions > to keep things snapppy. Best part about this is you can actually shove > a large portion of the status out into a Mongrel handler (now you know > why I covered it). > > Now, why doesn''t Mongrel do forking you may ask? All my tests found > that the fork available in Ruby just isn''t reliable. It causes IO to > get dropped, sockets to go away, files get closed at weird times, and > it''s just generally bad news. Also, fork isn''t really well supported on > win32. Nope, it''s just loads easier to use mongrel_cluster to manage a > ton of systems, or to setup a bunch of win32 services that listen on > different ports. > > Well, hope that long answer helped you out. > > > -- > Zed A. Shaw > http://www.zedshaw.com/ > http://mongrel.rubyforge.org/ > > > _______________________________________________ > Mongrel-users mailing list > Mongrel-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/mongrel-users >-- I was thinking of the immortal words of Socrates, when he said, "I drank what?" -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/mongrel-users/attachments/20060524/4611121f/attachment-0001.htm
Kevin C
2006-May-24 16:44 UTC
[Mongrel] Can Win32 service more than one rails request at a time?
Zed, Thanks for your explanation, it clears lots of confusion.> 2) Start a bunch of Mongrels listening on various ports (on various > machines) and use pound, pen, balance, lighttpd, litespeed, or apache to > proxy requests for a "fronting" machine to the N backends.Can I launch multiple Mongrels on vairous ports on the same server(not various servers) and proxy by apache? I guess the LOCK only applies to threads within the same mongrel process, each Mongrel holds its own and don''t step on each other, right? -- Kevin Chen http://www.realmatic.com