rails threads / contexts / fastcgi - can someone explain ???


Would someone be able to explain how ruby class/object contexts work from the point of view of a deployed rails application using FASTCGI and noting there are multiple Ruby processes running (say on dreamhost for example). Some questions to help clarify what I'm trying to understand:

a) how do incoming URL requests get spread across the multiple Ruby processes (let's say there are 5 processes)?

The front end webserver balances between the fcgi listeners. On dreamhost this would be apache doing that I believe.

b) What component organising/manages this? (e.g. plugin in apache?)

see above

c) is there any 'stickness' that occurs? i.e. where a request from person A that goes to ruby process 2 the first time will go to process 2 again for the next person A request (I assume no?)

Not with apache and usually not with fcgi. some front end proxies allow this like pound or nginx. Its called sticky session adn it makes sure a clients request always goes to the same backend.

With rails I don't think this is a good idea. You need to code your rails apps so that any backend can answer a request.

d) is there any sharing of contexts between the ruby processes? i.e. Can a ruby class variable be "seen" across processes?

No the ruby processes are totally independent. you can share state through the database or via a drb server or memcached.

e) is there any equivalent to the java static class variable (which can be accessed from any user request coming in which is being hosted within the same web-container on the same JVM)? I understand there isn't an equivalent in ruby?

I'm not familiar with Java enough to know what this means exactly. But I don't think rails has what you want here. Can you explain what you want to do with this and then I can help?

f) does the running ruby process handle multiple simultaneous user requests at the same time? i.e. is it operating in a multi-threaded mode?

No each request to rails gets gaurded with mutex. So each of your rails processes will only serve one request at a time and new requests will queue up waiting their turn. So you need to watch out if your users are dong huge file uploads. If you have three fcgi's and people try to upload 5 huge files at the same time, two of them will queue up and wait until one of the other uploads is done.

g) If so (for last question) is there any scope for collisions when using class variables (@@variable), or is each user request (i.e. each HTTP request) totally isolated from every other request at the ruby/rails application level? (of course the database would be shared). i.e. could both users/requests share the same class variable somehow??

On each request, your models and controllers are instantiated and go from there. @@classvars can get confusing because they are visible throughout the entire inheritance tree from where they are defined. So you can use these but think it thru carefully if you do as it can get confusing and if you don't do it right it can cause leakages between sessions.

h) what non-database caching raw ruby techniques are there for same caching a bunch of constants stored in a properties type file - perhaps put the properties/configuration setting in a ruby file itself as constants. Is it effectively already "cached" once it is "require"ed via ruby then holding it in memory? or does ruby re-load that file each time?

If you put a constant in environment.rb it will only load on bootup and will stay in memory until the procees is killed.

i) what would be simplest / rudimentory way to load/cache a bunch of properties/configuration parameters for an application? (would it be as per my suggestion in item h)

I would make a yaml config file and then load the contents of that into a constant in environment.rb. That works great for certain things. Of course you don't want to store a huge amount of data thins way but for config options it works great.

Signed Still a bit confused about ruby/rails contexts :slight_smile:

No worries, its a bit difficult to figure out on your own. But once you follow a few guidelines it will become clear.

Thanks in advance

You're welcome!

Cheers- -Ezra

Thanks heaps Ezra & Ryan for answering. I’ll respond below:

e) Equivalent to Java Static Class

  • I didn’t explain that well my question, but it was really what does the language offer itself in terms of shared in-memory data across any/all requests.

  • Ryan points out there is really no equivalent

  • RYAN: When you mentioned in-memory cache options I guess you were referring to some external operating system support? What did you have in mind for a unix installation?

f) running ruby process handle multiple simultaneous requests

  • EZRA: Tks. Do you whether a typical apache/fastcgi setup will detect the “I don’t have enough running ruby processes” and start new ones? In particular I’m using dreamhost at the moment for hosting & wondering whether I need to configure anything here myself, or request it from the hosting provider.

g) scope for collisions when using class variables (@@variable)

  • Ezra: I’d love to understand what you meant by “think it thru carefully if you do as it can get confusing and if you don’t do it right it can cause leakages between sessions” ( i.e. re use of class variables) - are you able to expand?

i) way to load/cache a bunch of properties/configuration parameters

  • Tks
  • I was considering usage for simple localisation, and have a couple of different files each with say 5 to 10 pages of key,value pairs. How do this sound re size? The only other way would be to hit the database each time in fact no? i.e. is there any in-between approach that ruby/rails offers (e.g. lazy-loading type support that is then cached?)

Thanks again Greg