23 July 2007

Timeout a ruby system call

I was rather disappointed that I could not set a timeout on a system call. This is especially a problem because of the very poor threading model that ruby currently has. But, at least there is a way to get the job done. The following is a method I wrote to make a system call and then kill it if the timeout is reached.

require 'timeout'
class System
def self.system_with_timeout(timeout, *args)
if ( (pid = fork) == nil )
#child process
@@logger.debug(args.join(' '))
exec(*args)
else
success = false
#parent process
begin
#TODO if the process fails return false
success = Timeout::timeout(timeout){ Process.waitpid(pid) }
rescue Timeout::Error
@@logger.error "***** Timeout error"
Process.kill("HUP", pid)
Process.detach(pid)
end
success
end
end
end

3 comments:

Anonymous said...

thanks a lot! this helped me out after a whole day of frustration..

Paul said...

Thanks! It's a solution I was looking for!

Carlos Alberto Werberich said...

Amazing... thanks a lot!