Asynchronously running a ruby script from ruby - ruby

Based on an external redis queue, I want a Sinatra application to run a script like this:
ruby fetch_vin.rb vin_number_123
This will fire up watir-webdriver and report to the queue appropriately. When the script is finished, everything but the Sinatra app should close.
It seems however that Thread, as well as exec and spawn are all blocking when ran from inside ruby.
How do I fire & forget?

You can use Process#spawn:
pid = Process.spawn("ruby fetch_vin.rb vin_number_123")
Process.detach(pid)
I think the bit you were missing was calling detach after the process was spawned. This will detach and let both processes continue to run. Will work for any command, not just a ruby script.
See Process Ruby Docs for more details.

Related

Ruby Process.daemon: turning on/off

I am trying to daemonize a Ruby script, running on 2.1.1.
My daemon part of the code is like this:
case ARGV[0]
when "-start"
puts "TweetSearcher started."
Process.daemon
when "-stop"
Process.kill(9,Process.pid)
else
puts "Lacks arguments. Use -start/-stop"
abort
end
However, it looks like that the Process.kill(9,Process.pid) is not killing what I wanted to. I want to kill a previous "ruby tweetsearcher.rb -start", already running in background.
How do I proceed?
Typically, the PID is stored in a file that is then read to stop it.
Calling Process.kill(9,Process.pid) kills the "stopper" process itself, rather than the one it's trying to stop.
Here's a guide to writing daemons in Ruby: http://codeincomplete.com/posts/2014/9/15/ruby_daemons/
As you can see, it's not a trivial process.
Here is another blog that suggests that you should not try to daemonize at all, but instead rely on a process monitoring system to take care of those concerns: https://www.mikeperham.com/2014/09/22/dont-daemonize-your-daemons/

How can I create a monit process for a Ruby program?

I have these rake tasks that will occasionally fail. I want to use monit to monitor them and to restart them if necessary.
I have read the other ruby/monit threads on StackOverflow. My case is different in that these programs require my Rails environment in order to work. That's why I have them as rake tasks now.
Here is one of the tasks I need to monitor, in it's entirety:
task(process_updates: :environment) do
`echo "#{Process.pid}" > #{Rails.root}/log/process_alerts.pid`
`echo "#{Process.ppid}" > #{Rails.root}/log/process_alerts.ppid`
SynchronizationService::process_alerts
end
My question is, do I leave this as a rake task, since SynchronizationService::process_alerts requires the Rails environment to work? Or is there some other wrapper I should invoke and then just run some *.rb file?
Monit can check for running pid, since you're creating pid when you run task you can create a monit config which should look something like this:
check process alerts with pidfile RAILSROOT/log/process_alerts.pid
start program = "cd PATH_TO_APP; rake YOURTASK" with timeout 120 seconds
alert your#mail.com on { nonexist, timeout }
Of course RAILSROOT, PATH_TO_APP, YOURTASK should correspond to your paths/rake task.
Monit then will check for running process in system using the pidfile value and will start the process using start program command if it can't find running process.

How do I spawn a new process to do a task in Ruby?

I would like to write a Ruby script that runs a daemon Ruby process, so that I can do something like the following:
$ task start
Started...
# start a daemon to do useful work; don't block
# Some time later:
$ task end
Finished.
What's the best way to go about this?
Use the Process.daemon method when you want your process to detach from the terminal and stop being able to send output. To end the process, you will have to send it a signal. Most programs handle this by using a file that contains the PID.

Ruby background service

I have a TCPclient written on Ruby. I want to use it in background. Currently it has a loop:
loop do
end
So i can run a client, and it works forever.
Is there a way to run in as a service, and write a pid to file, then i'll able to kill that process by pid?
The daemons gem is made just for this.
You can use the unix system for that :
ruby myfile.rb && echo $! > my_file.pid

Spawn a background process in Ruby

I'm writing a ruby bootstrapping script for a school project, and part of this bootstrapping process is to start a couple of background processes (which are written and function properly). What I'd like to do is something along the lines of:
`/path/to/daemon1 &`
`/path/to/daemon2 &`
`/path/to/daemon3 &`
However, that blocks on the first call to execute daemon1. I've seen references to a Process.spawn method, but that seems to be a 1.9+ feature, and I'm limited to Ruby 1.8.
I've also tried to execute these daemons from different threads, but I'd like my bootstrap script to be able to exit.
So how can I start these background processes so that my bootstrap script doesn't block and can exit (but still have the daemons running in the background)?
As long as you are working on a POSIX OS you can use fork and exec.
fork = Create a subprocess
exec = Replace current process with another process
You then need to inform that your main-process is not interested in the created subprocesses via Process.detach.
job1 = fork do
exec "/path/to/daemon01"
end
Process.detach(job1)
...
better way to pseudo-deamonize:
`((/path/to/deamon1 &)&)`
will drop the process into it's own shell.
best way to actually daemonize:
`service daemon1 start`
and make sure the server/user has permission to start the actual daemon. check out 'deamonize' tool for linux to set up your deamon.

Resources