How to subprocess timeout in Ruby

I want to check that the process is working, so I run:

cmd = "my unix command" results = `#{cmd}` 

How to add a timeout to a team so that if it takes more than x seconds, I can assume that it does not work?

+4
source share
4 answers

Ruby ships witrh Timeout module .

 require 'timeout' res = "" status = Timeout::timeout(5) {res = `#{cmd}`} rescue Timeout::Error # a bit of experimenting: res = nil status = Timeout::timeout(1) {res = `sleep 2`} rescue Timeout::Error p res # nil p status # Timeout::Error res = nil status = Timeout::timeout(3) {res = `sleep 2`} rescue Timeout::Error p res # "" p status # "" 
+7
source

Put it on a thread, try another thread in x seconds, and then delete the first if it has not already been executed.

 process_thread = Thread.new do `sleep 6` # the command you want to run end timeout_thread = Thread.new do sleep 4 # the timeout if process_thread.alive? process_thread.kill $stderr.puts "Timeout" end end process_thread.join timeout_thread.kill 

steenslag is nicer though :) This is a low-tech route.

+1
source

A simpler way with a stream:

 p = Thread.new{ #exec here } if p.join( period_in_seconds ).nil? then #here thread p is still working p.kill else #here thread p completed before 'period_in_seconds' end 
0
source

Beware of previous answers, if the child process uses sudo, you cannot kill the child, and you will create zombie processes.

You will need to periodically run Process :: waitpid (-1, Process :: WNOHANG) to collect exit status for children and clear process tables (thus clearing zombies)

0
source

Source: https://habr.com/ru/post/1416222/


All Articles