On Jun 16, 2008, at 10:41 AM, Ema Fuma wrote:
I’m under Windows but I would like to use the same script on Linux.
Basically it’s just
-launch an external executable that write it’s progress on stdout
-parse the stdout line by line
-if there’s no new line for more than 10 sec close the external exe
it’s nearly impossible to do this on windows reliably. this are just
too many failure conditions, for instance say the child program does
gb = 2 ** 30
huge = ‘*’ * gb
STDOUT.write huge
and the parent does
buf = child.gets
both processes will hang. the child because it fills the pipe, the
parent because it never sees a newline. you’d think this could be
solved by using timeout, but it cannot (on windows) because ruby’s
threads schedule with select and therefore many/most io operations
will block the scheduler - causing a hang.
there is some hope for using socketpair and a tcp server in a cross
platoform manner, rough idea here:
http://pastie.org/173246
but this doesn’t address issues like stderr or zombie processes.
anyhow, i’m not saying it can’t be done on windows, but it’s very
non-trival to combine pipes, timeout, and process management in a
robust fashion.
one idea might be to launch and external process to signal yourself
before reading, something like this:
signaler = Thread.new do
system “ruby -e’ sleep 10; Process.kill(:HUP.to_s,
#{ Process.pid })”
end
begin
child.gets
rescue SignalException
…
end
however signals are very limited on windows and i’ve no idea if even
the signal handlers would fire once a process is blocked - worth
trying though… it’s definitely going to take something creative on
your end. one other thought is to spawn and external reaper before
reading, one which would kill the external exe for you
reaper = Thread.new
system “ruby -e’ sleep 10; Process.kill -9, #{ child.pid }'”
end
and then, in the parent arrange to schedule this before each read, and
kill it afterwards…
i’d be interested to hear other’s thoughts on the issue (dan berger in
the house?) as i’m no windows expert.
regards.
a @ http://codeforpeople.com/