Launching a process from inside a controller in rails - ruby-on-rails

I want to start a process from inside a controller.
I've tried the usual
pid = fork do
code
end
Process.detach(pid)
But nothing is happening. When I try with eval(code) in the fork block the code runs but it's the actual rails server/puma running it. This means that when I kill the process I also shut down the whole server.
I had some code before that I lost that worked and I'm nearly sure it used exec or eval or something like this that created a process(and therefore returned a pid to be able to kill it later) and I remember checking with ps that it was run by something of rails but not the actual whole server.
Why isn't the fork do block enough for it to work? What's the way to do it?
And, for non-testing purposes and actual implementation, how can I make it run totally independent from the rails server?

You can execute a shell command from inside your Rails controller using exec.
I hope you are looking for the same. The process you start on the system will be totally independent of the Rails server and will be visible under ps command if it is running when you hit the command.
Documentation: http://ruby-doc.org/core-2.5.1/Kernel.html#method-i-exec

Related

Spring server: Timeout error

I am trying to run a cron-task using Rails schedule.rb file. The task invokes a function written in ruby. The function runs perfectly fine. However when trying to run as a cron I get this error.
Starting Spring server with `/home/ubuntu/.rvm/gems/ruby-2.4.0/gems/spring-2.0.2/bin/spring server --background` timed out after 20 seconds
Spring(2.0.2) is installed and working perfectly.
Any idea how to solve this?
If the command works outside of cron, but not in the crontab, the problem is almost certainly that the command isn't picking up some necessary environment variable setting. There are several ways to get around the problem, but the simplest and best is to wrap your command in a shell script.
For initial testing, you can simply source your login environment:
. ~/.bash_profile
But eventually you'll want to just set the variables you need and not include anything extra. For more information, see Define your own job types.

Running node.js code from Rails application

I am trying to integrate some node.js code with my Rails application. Basically its a js file with some code that process will keep running in background.
I have followed the following steps:
Added code in root of rails app in some test_node.js file.
Now what I do is pass a value to my system using exec function of ruby, e.g exec "node test_node.js".
This works perfectly fine but it chop my server from processing any requests.
To pass it to background i tried using nohup e.g: exec "nohup node test_node.js".
When I run this code my server crashes.
I am Rails developer and never worked on node app so have no idea if I taking it right way or not.
exec replaces the currently running process with a new one. Thus, to run something in the background you should fork and exec in the child.
fork { exec('node', 'test_node.js', ...) }
nohup is not needed.
See also Ruby, Difference between exec, system and %x() or Backticks

Use linux script to make a continuous rake task running (start, stop etc)

I have a rake task which parses a streaming API and enters data into database. The streaming API is live feed and the rake task should run continuously for the live data to enter the database. The rake task once called will run continuously and parse the data. Now i have started the rake task and it is running. The problem is that if i close the terminal or reboot the server, the rake task wil be stopped. So, i want a script in linux (something like the one used to start, or stop apache server), which does the following:
1. start the rake task by calling rake command (rake parse:stream) from the RAILS-ROOT (application directory of Rails app)
2. stop the rake task by killing the process.
3. start the rake task automatically when the server reboots.
i am not familiar to linux scripts and i dont know where to start. i am using ubuntu server. can anyone help me?
Here's an article that might help you also. It discussed various options for managing Ruby applications and their related processes:
http://michaelvanrooijen.com/articles/2011/06/08-managing-and-monitoring-your-ruby-application-with-foreman-and-upstart/
You need to run your script as a daemon. When I create this kind of startup scripts I usually make 2 files, one that stays in /etc/init.d and handles the start/stop/status/restart commands and another one that actually does the job and gets called by the first script.
Here is one solution, and although the daemon script is written in perl, you want to run some command lines only, so daemonizing a perl script could do your job easily.
If you want, there are also ruby gems for daemonizing scripts, so you can write a script in ruby that does the rake tasks.
And if you want to go hardcore, there are solutions for writing bash scripts that can daemonize, but I'm not sure I would recommend a solution like that; at least I find them pretty difficult to use.
Take a look at how Github's Resque project does it.
Essentially they create tasks for starting/restarting/stopping a particular task, in this case resque:work. Note that the restart_workers task simply invokes the other tasks, stop and start. It should be really easy to change this for what you want.

Delayed Jobs on Rails 2: any better way to run workers?

I finally got the DelayedJobs plugin working for Rails 2, and it does indeed work fine...as long as I run:
rake jobs:work
Just like the readme says, to be fair.
BUT, this doesn't fit my requirements...what kind of background task requires you to have a shell open, and a command running? That'd be like having to say script/server to run my rails app, and never getting that -d option so it'll keep running even after I close my shell.
Is there ANY way to keep the workers getting processed in the backgroun, or in daemon mode, or whatever?
I had a ray of hope when I saw the
You can also run by writing a simple
#script/job_runner#, and invoking it
externally:
Line in the readme...but...that just does the exact same thing the rake task does, you just call it a different way.
What I want:
I want to start my rails app, then start whatever will process the workers, and have BOTH of them run invisibly in the background, without the need for me to babysit it and keep the shell that started it running.
(My server is something I SSH into, so I don't want to have that shell that SSHed into it running 24/7 (especially since I like to turn off my local computer now and again)).
Is there any way to acomplish this?
You can make any *nix command run on the background by appending an & to its end:
rake jobs:work &
Just make sure you exit the shell (or use the disown command) to detach the process from your login session... Otherwise, if your session disconnects, the processes you own will be killed with it.
Perhaps Beanstalkd and Stalker?
Beanstalk is a fast and easy way to queue background tasks. Stalker provides a nice wrapper interface for creating these jobs.
See the railscast on it for more information
Edit:
You could also run that rake task as a cronjob which would mean the server would run it periodically without you needing to be logged in
Use the collectiveidea fork of delayed_job... It's more actively developed and has support for running the jobs in a daemon without any extra messing about.
My capistrano script calls
RAILS_ENV=production script/delayed_job start

Daemon Start at the application bootup

I have a daemon that should run behind my rails app doing db modifications.I implemented that daemon using ruby daemons gem. I want to start that daemon at the start of my app. Whenever my app starts, I need to start that daemon.
How can I do this..?
If you must start it during Rails initialization:
Create a ruby file that will start the daemon. Say invoke_daemon.rb
Put this file in config/initializers/invoke_daemon.rb
However if it isn't mandatory, I would suggest creating a binary executable or a rake task and manually starting it through command line. This way it runs as a separate process. You can simply add it to your deployment scripts for production boxes and on development box run it manually. A few examples would be searchd, the search daemon for sphinx and thinking_sphinx:delayed_delta rake task from thinking_sphinx.
For your knowledge you have to take look of
Rails Life cycle
I have just implemented this thing. I have implemented on Windows7.
I have created one batch file let's say my_batch.bat, which contains ruby command i.e. ruby my_daemon.rb file.
In addition, to execute this file when my app starts , I have just added one statement in environment.rb file which executes that batch file. i.e. system ("my_batch.bat").
But I am not sure that this is a good way to implement this task.

Resources