Rails 3 - All users stuck while someone is processing - ruby-on-rails

We have a web-app here that makes hundreds of calculations with money and other very specific numbers. It has been developed in Rails 3, which I have not much experience.
Recently, I have noticed that even in Digital Ocean server, where it runs for production, whenever an user requests to open some page for example, that does any query to get data from the database, everyone else gets stuck until the processing finishes.
It just looks like rails is running on a "single-threaded" mode, similar to running the same scenario with Tomcat in development mode in Eclipse.
Is there any trick to make it work "multi-threaded"?
I don't see any reason or even logic for it to run like this, there's no sense in making everyone wait until the request of another user finishes.
Thanks in advance to everyone!

Well, I've found the solution.
To enable Rails with WEBrick to work in a "multi-threaded" way, you'll have to simply go to the config file, and add :
# Enable threaded mode
config.threadsafe!
After that, restart the server and the trick is done. It "solved" my problem, but ended up creating a thousand others, cause the application wasn't developed thinking about a "threadsafe" scenario, which means, that everytime I try to run similar requests at the same time, the application mixes up everything in memory, crashing.
Well, one problem at once!
The original from this topic is solved.

Related

How to implement auto starting and exiting daemons in rails

I'm a bit overwhelmed by mere amount a possible solutions the Rails community has created for my problem. So perhaps anyone can help me to figure out how to solve it best.
What I want to do is to write a Rails app that behaves kind of "dropbox". On the one hand it should be a web interface where I can upload and download files to my web server. This interacts with my database and all that stuff. On the other hand I have SSH access to that server and can put files there manually. Now I want this file system actions to trigger my Rails app to do the things it would do if I'd created the file via the web interface.
So I somehow write a daemon, right? There are a lot of solutions, like
daemons.rubyforge.org/
github.com/mirasrael/daemons-rails
github.com/costan/daemonz
github.com/kennethkalmer/daemon-kit
Another feature that I would like to have, is that my Rails app automatically spawns and stops my daemon as start or quit my Rails app resp. So "daemonz" seems the best solution. But as I googled further I found
github.com/FooBarWidget/daemon_controller/
which seems a lot more "high tech" and already used as I deploy with passenger. But I don't understand if it kills my daemons as I quit Rails. I suppose that is not the case and so I wonder how to implement this in my app.
The way to implement a "thing" to react to file system changes seems straight forward for me. I'd use
github.com/guard/listen/
(an alternative would be: github.com/ttilley/fssm )
But what I don't understand as this the first time I'm really faced with this protocol things is, if this spawns a server I'm able to communicate with or what kind of object I have to deal with.
The last thing, I would like to implement is a kind of worker queue so that the listening for file system changes is seperated from the the actions of my rails app. But there are so many solutions that I'm totally overwhelmed to pick one:
github.com/tobi/delayed_job/
github.com/defunkt/resque
http://backgroundrb.rubyforge.org/
And what is
http://godrb.com/
all about? How could that help me?
Has anyone hints how to solve this? Thanks a lot!
Jan
P.S. I'd like to post links to all the github projects but unfortunately I don't have enough 'reputation'
I'd definitely look into creating a process (daemon) that monitors the relevant directory. Then your Rails app can just put files into it without having to know anything about the back end, and it'll work with SSH too.
Your daemon can load the Rails environment & communicate with your database. I'd leave all the communication between them at that level.
As for making it start/stop with your rails app...are you sure? I use god (the ruby gem) to start/monitor processes. It will "daemonize" your Ruby app for you, too. If you want to, you can actually tell god to stop your directory-monitor process & then exit when Rails stops. And you can fire off god from a Rails initializer.
However, if you might find yourself using SSH or some other means to put files into that directory when rails is not running, you might look into putting a script into /etc/init.d to automatically start god when the server boots up.
HTH
I think you want something like Guard for monitoring the changes on the filesystem and performing actions when changes occur.
As for god, you should definitely look into it. It will make starting/stopping processes you depend on considerably easier. We used Bluepill for a while, but there are so many bugs, we ditched it and moved to God, which IMHO is a lot more pleasant to work with, for the mostpart.
Have you tried creating a script file eg:
startDaemon.rb
And then placing it:
config/initializers/
?

How do I stop rails from regenerating routes on every request?

I am working on a pretty large rails project with a lot of routes. If rails is in development mode the app runs extremely slowly because it has to generate the routes repeatedly. I've tested this a couple of times by removing most of the routes and our app is nearly instant in bringing up our pages rather than the 10 or so seconds it usually takes. What I'm trying to find out is how I can stop rails from regenerating the routes on every request when in development mode. Is there a way to cache it or just stop it from regenerating?
I wouldn't advise it, but set cache_classes to true in your config. You'll have to restart the server every time you want to test a code change though.
Did you get anywhere with this?
I'm a little late to the party, and I don't have a direct answer for stopping the regeneration of routes, but would you accept speeding up other parts of the development environment as a compromise? If so, it's worth checking out the Rails Development Boost gem. I've had some great speed increases from there.

Best way to run rails with long delays

I'm writing a Rails web service that interacts with various pieces of hardware scattered throughout the country.
When a call is made to the web service, the Rails app then attempts to contact the appropriate piece of hardware, get the needed information, and reply to the web client. The time between the client's call and the reply may be up to 10 seconds, depending upon lots of factors.
I do not want to split the web service call in two (ask for information, answer immediately with a pending reply, then force another api call to get the actual results).
I basically see two options. Either run JRuby and use multithreading or else run several regular Ruby instances and hope that not many people try to use the service at a time. JRuby seems like the much better solution, but it still doesn't seem to be mainstream and have out of the box support at Heroku and EngineYard. The multiple instance solution seems like a total kludge.
1) Am I right about my two options? Is there a better one I'm missing?
2) Is there an easy deployment option for JRuby?
I do not want to split the web service call in two (ask for information, answer immediately with a pending reply, then force another api call to get the actual results).
From an engineering perspective, this seems like it would be the best alternative.
Why don't you want to do it?
There's a third option: If you host your Rails app with Passenger and enable global queueing, you can do this transparently. I have some actions that take several minutes, with no issues (caveat: some browsers may time out, but that may not be a concern for you).
If you're worried about browser timeout, or you cannot control the deployment environment, you may want to process it in the background:
User requests data
You enter request into a queue
Your web service returns a "ticket" identifier to check the progress
A background process processes the jobs in the queue
The user polls back, referencing the "ticket" id
As far as hosting in JRuby, I've deployed a couple of small internal applications using the glassfish gem, but I'm not sure how much I would trust it for customer-facing apps. Just make sure you run config.threadsafe! in production.rb. I've heard good things about Trinidad, too.
You can also run the web service call in a delayed background job so that it's not hogging up a web-server and can even be run on a separate physical box. This is also a much more scaleable approach. If you make the web call using AJAX then you can ping the server every second or two to see if your results are ready, that way your client is not held in limbo while the results are being calculated and the request does not time out.

Development environment query on some models very slow

I am scratching my head over for this issue for last few weeks.
My local rails dev environment has been so slow for some reasons. I have production environment working as quick as a bullet on the servers. But with the same code, my dev environment is taking so slow and I have decided to dig into that further.
I have found that the problem exists with two of my main models. I could identify it with Console in the terminal.
Admin.last
#(super quick, no records there)
Club.last
#(super quick, about 1400 records there)
User.last
#(super slow, about 3 seconds. but no records in there yet!!!!)
Site.last
#(super slow,about 3 seconds, too.. but this one has about 4000 records)
Admin and User has almost the same number and type of fields except User has a photo (using Paperclip). But paperclip is working fine with Club anyway.
Any help will be appreciated.
Thanks.
EDIT: I have found more precise issue there. In both User and Site models, I have this reference which is slowing things down on my dev env.
include ActionController::UrlWriter
I know we should not use URL in the model level. But I have to use it. The question now is why the heck it's slow to use it only on Dev env, not on production?
Thanks.
In the development environment code is reloaded after each request and not cached. This means you can make changes to the code and just refresh the page and not have to refresh the server.
In production mode routes/models are cached as these are less likely to be edited between requests without a server restart.
it's because your URL are reload in each time. So take some times. In production there are no reload of your route.

Rails app stuck

I am running a rails app on Dreamhost.
Today, a strange thing happened.
A page is almost loaded (it seems to be fully loaded but the status is not 'Done') and after that, the app didn't respond on any page.
I checked out the log and even the log was not complete.
How do I know it?
There are 3 missing images on the problem page and the log showed only 2 missing images and stopped there.
So I guess that something happened between the 2nd and the 3rd missing images.
I couldn't even start 'script/console production'.
After 14 minutes, it began to behave normally.
I asked the hosting company and they said that the process was killed due to over-use of memory.
Probably something was running heavily during the period.
The same thing happened one more time.
I had to kill the process to unlock the stucked app.
Passenger version is 2.2.4 and rails version is 2.3.2.
I am afraid that I can't give more specific info.
What do you guess cause such a problem?
Thanks.
Sam
As theIV stated, look at the last action called. Start this up locally and try to go through what was happening on the server to see if it's reproducable, or if you just get any sort of general hiccups. I've run Rails apps on Dreamhost for a while, and have not experienced this before, so I would guess that it's not Dreamhosts fault, but there is no 100% on that.
Good luck!
This sounds pretty app specific. I would start by looking at what action was last hit before the process started hoggin' and then work backwards from there to see if there are any calls that might be doing something you weren't expecting. Other than that, no clue. :(
Try using NewRelic RPM or TuneUp Lite to see what process is chunking most of your memory. You can run them locally but it would be better to test it on production.

Resources