Actually, after taking a closer look at the timeout method distributed
with Ruby, I don’t understand why it doesn’t work for me… can anyone
explain that to me? To me, it looks like it’s doing exactly the same
thing Ara suggested doing with signal traps, but with threads instead.
So how come it doesn’t work?
Actually, after taking a closer look at the timeout method distributed
with Ruby, I don’t understand why it doesn’t work for me… can anyone
explain that to me? To me, it looks like it’s doing exactly the same
thing Ara suggested doing with signal traps, but with threads instead.
So how come it doesn’t work?
with ruby, only one thread runs at once because they are green
trheads. so if you do something that blocks your entire process, like
and OLE call, you block all threads. this is mainly a windows issue.
Signal.list.keys.each do |key|
puts key
unless key == ‘KILL’
timeout(2, key) { p ‘works’ }
timeout(1, key) { sleep 2; p ‘does not work’ }
end
end
and it produced the following output:
ruby timeout_test.rb
TERM
“works”
“does not work”
SEGV
“works”
“does not work”
KILL
EXIT
“works”
“does not work”
INT
“works”
“does not work”
FPE
“works”
“does not work”
ABRT
“works”
“does not work”
ILL
“works”
“does not work”
Exit code: 0
–
Thanks!
Bryan
Ara Howard wrote:
did you try the ‘INT’ signal? there are only a few signals supports
in windows between process and i forget which is which. in any case,
even if that exact code will not work the principle will: that of
setting up an external process to do something to your (potentially
blocked) process. in fact it’s the only way out when you consider
ruby’s thread impl.
If I kill the external application that I’m using the OLE/COM
interface to talk to while my Ruby program is running, I get a
WIN32OLERuntimeError in my Ruby program. Thus, since
Process.kill(‘KILL’, ) does seem to work on Windows (I did test
this), I figured I could make my timeout method look like this:
def timeout(sec, pid)
begin
watchdog = IO.popen “ruby -e ‘sleep(#{sec});
Process.kill(:KILL.to_s, #{pid}) rescue nil’”
yield
ensure
Process.kill(‘KILL’, watchdog.pid) rescue nil
end
end
and I could call it like this:
@sim = WIN32OLE.new ‘PwrWorld.SimulatorAuto’
…
begin
timeout(20, @sim.ProcessID) do @sim.RunScriptCommand(‘SolvePrimalLP()’)
end
rescue WIN32OLERuntimeError
rescue myself from the external application hanging up… i.e.
However, it seems as though when creating the watchdog in the timeout
method IO.popen sometimes blocks execution. I can’t tell if it’s due
to the external (OLE) application blocking or something else. If I
don’t use the timeout method the OLE application blocks at a different
time in the simulation, so I’m thinking it’s not due to the OLE
application blocking…
However, it seems as though when creating the watchdog in the timeout
method IO.popen sometimes blocks execution. I can’t tell if it’s due
to the external (OLE) application blocking or something else. If I
don’t use the timeout method the OLE application blocks at a different
time in the simulation, so I’m thinking it’s not due to the OLE
application blocking…
can you prove that it’s popen blocking? seems very strange…
At this point I can’t say I’ve proven it… about the only thing I’ve
done is stick logging commands around the creation of the watchdog.
The log statement before gets logged, the one after does not.
However, I’m not exactly sure how log4r works either so who knows if
the OLE stuff is jacking with it also!
can you prove that it’s popen blocking? seems very strange…
I’m just jumping into the middle of the thread, so apologies if
I’ve missed something; but …
popen blocks ALL ruby threads on windows. This has been the bane
of my existence for the past eight years.
The problem is due to Microsoft’s venerable design strategy: You are
lost in a twisty little maze of API’s, all incompatible.
On Windows, the “file handle” returned by popen is not a “socket”,
and therefore is incompatible with “select”.
/me raises a cup of hemlock in toast to Redmond
Note: Now that 1.9 ruby uses native threads, it should be possible
to implement a nonblocking popen. However, last time I tested 1.9
for this behavior, it still blocked. (This was several months ago.)