How to implement auto starting and exiting daemons in rails - ruby-on-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/
?

Related

Rails 3 - All users stuck while someone is processing

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.

Is loading a route via cron, curl and the whenever gem going to cause problems?

I have need to periodically run a background task in my rails app. I've done some research and it seems that there is not a standard way to do this.
I don't want to generate a new app context so a runner seems to be out of the question. I'd prefer not to run my own thread handler if I don't have to. (It looks like this may be the most promising option at this point other than the below).
Using the whenever gem I am doing the following in schedule.rb:
every 15.minutes do
command "curl http://127.0.0.1:3000/periodic"
end
This feels a little like a hack, but I can't find anything that is more straightforward than this -- Everything else I can find seems like a lot of effort for something seemingly basic.
I should note that this is an internal project and will be behind a firewall, and headless automated middleware, so there is low expectation that a user will ever be accessing this project directly.
Am I missing something or is background processing or timed events really just not supported out of the box with rails?
After some research, Amadan's suggestion of a railtie may get me what I want here. As an ideal solution it isn't perfect, though depending on the context (i.e. a publicly accessible rails project) this is the way to go. For the project I am working on it's a little heavy handed, as I'm doing a rails app that is a bridge between two systems, running headless, with no user input behind a firewall.

Rails Deployment 101

I am about to deploy my 1st Rails app. I am stuck as I don't know what exactly I need to do. I know about Heroku, AWS, Capistrano and the like, but don't know exactly what they do, and what their benefits are.
I kinda know some things, but all are blurry and ambiguous since I have no formal training and learn as I go. So basically I need someone to explain the general anatomy of Rails deployment.
Something like: 'To make any app working on the web you need the following components... Ways to make this component work with Rails are following. Alternatives are these. These are pros and cons.' Not into too much detail, but general and comprehensive 101 guide.
The reason you may be confused is that there are a number of ways to do it. :D
Heroku provides one of the easiest solutions for basic deployments. You don't need capistrano, just git. (they provide a toolset to assist). Just git push heroku master. Also nice is that a simple deployment on heroku is free; you can pay for more power when you actually need it.
But if you need a little extra functionality that heroku can't provide, you have to host elsewhere, such as a private virtual host.
Capistrano is a set of recipes that help build a deployment environment, sort of like rake tasks. It does so in a very organized manner and allows for easy rollbacks. You define the hosts, their roles, and then the recipes use ssh and scp to set up the evironment. (the server also has to be ready to accept rails applications, through something like passenger)
The Rails and Ruby World(s) are pretty noisy, so I understand your confusion.
At the end of the day, you need your rails app on a server.
Now, even the term server can be a little confusing, because it is generally associated with
A remote machine
A program handling HTTP requests.
(for example webrick or thin which you start when you are developing on your computer and type rails s)
In your case you actually want a remote computer (hooked up to the net) which is running a program called a server to process HTTP requests and forward these to your app which in turn produces a request...
Heroku will help you out with that. (However Heroku adds several layers of abstraction to the mix. So it is not like you have one computer sitting somewhere in the heroku office, serving your application.) Heroku is dead simple to setup with git and rails.
And in the end all that is need to get your app to the "remote server" is a simple git push.
Read the beginner articles on https://devcenter.heroku.com/
I would also suggest for now: Forget about Capistrano.
Oh and you can think of AWS (or probably S3) as some sort of external hard drive, which your app can use to store larger pieces of data (like images, videos etc.)
I have a deployment guide with a good shell script which support Nginx + RVM + Unicorn: deploy_rails

Ways to monitor Workling instances in a Rails app

I'm currently using Workling with Starling on a rails app. Although I like Workling, I find it kinda hard to monitor.
To make matters worse, I have a couple of Workling instances. Workling is running with the :multiple set to 'true' (inside workling_client).
I can see the pid for each instance and such, but I want to know if they're actually doing some work, and find out if I need more (or even less) instances running.
Do you guys have any suggestions of tools, hacks or anything that could help me on this one?
I monitor Workling with monit. It gives you CPU% at any given point in time. If you want to have a look how much load they have had over time then you could use Munin instead as I believe it can give you some graphs via some plugins to it that can tell you a number of things about what you are monitoring. Sorry I can't be more specific as I haven't used Munin.

Are you using AWSDBProxy? Is there a performance hit when scaling out?

It seems that the only tutorials out there talking about using Amazon's SimpleDB in a rails site are using AWSDBProxy... Personally, I find this counter-intuitive to scaling out, considering the server layout of a typical Rails site below (using AWSDBProxy):
Plugin here: http://agilewebdevelopment.com/plugins/aws_sdb_proxy
Image here: http://www.freeimagehosting.net/uploads/91be4e0617.png
As you can see, even if we add more mongrels, we have two problems.
We have a single point of failure far less stable than our load balancer
We have to force all our information through this one WEBrick server
The solution is, of course, to add more AWSDBProxies... but why not then just use the following code in say, a class, skipping the proxy all together?
service = AwsSdb::Service.new(Logger.new(nil),
CONFIG['aws_access_key_id'],
CONFIG['aws_secret_access_key'])
service.query(domain, query)
So what I'm getting at, is if you are using AWSDBProxy, what are you justifications for it? And if you are indeed using it, what is your performance like? If you have hard numbers, this would be even more appreciated!
I'm not using it, nor have I ever heard of it, but this is what I would think are reasonable reasons.
You're running your main app server on EC2, so the chance of Internet FAIL doesn't really affect you more than once.
You run one proxy on each of your app servers. So it's connection going down is no worse than it's connection(s) to the database going down.
Because it can be done. This is as good a reason as any in an open source project. Sometimes it takes building a thing before you know whether said thing is a good/bad idea.
You don't have the traffic levels to need a load balancer. Then your diagram squashes down to a line, if not a single machine.

Resources