Non-Threaded Timeout?

Hell all,

I'm looking for a way to implement a non-threaded timeout. I am running
some Monte Carlo simulations using an external application via an OLE
interface. There are times where the external application seems to hang
up, so I'm looking for a way to detect this and continue on with my
simulation if the external application takes too long.

Any suggestions?

···

--
Thanks!
Bryan
--
Posted via http://www.ruby-forum.com/.

http://ph7spot.com/articles/system_timer

···

On Fri, Aug 8, 2008 at 7:28 PM, Bryan Richardson <btrichardson@gmail.com> wrote:

Hell all,

I'm looking for a way to implement a non-threaded timeout. I am running
some Monte Carlo simulations using an external application via an OLE
interface. There are times where the external application seems to hang
up, so I'm looking for a way to detect this and continue on with my
simulation if the external application takes too long.

something like this should be able to work, even on windows....

cfp:~ > cat a.rb
require 'timeout'

def timeout seconds, &block
   pid = Process.pid
   signaler = IO.popen "ruby -e'sleep #{ seconds }; Process.kill(:TERM.to_s, #{ pid }) rescue nil'"
   handler = Signal.trap('TERM'){ raise 'timed out...' }
   begin
     block.call
   ensure
     Process.kill 'TERM', signaler.pid rescue nil
     Signal.trap('TERM', handler)
   end
end

timeout(2){ p 'works' }
timeout(1){ sleep 2; p 'does not work' }

cfp:~ > ruby a.rb
"works"
a.rb:6:in `timeout': timed out... (RuntimeError)
         from a.rb:16:in `call'
         from a.rb:16:in `sleep'
         from a.rb:16
         from a.rb:8:in `call'
         from a.rb:8:in `timeout'
         from a.rb:16

a @ http://codeforpeople.com/

···

On Aug 8, 2008, at 7:58 AM, Bryan Richardson wrote:

Hell all,

I'm looking for a way to implement a non-threaded timeout. I am running
some Monte Carlo simulations using an external application via an OLE
interface. There are times where the external application seems to hang
up, so I'm looking for a way to detect this and continue on with my
simulation if the external application takes too long.

Any suggestions?

--
Thanks!
Bryan
--
Posted via http://www.ruby-forum.com/\.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

slightly more complete - may need tweaks for windoze....

cfp:~ > cat a.rb
Timing.out(2) do
   p 'works'
end

Timing.out(1) do
   begin
     sleep 2
   rescue Timed.out
     p 'times out'
   end
end

Timing.out(1) do
   sleep 2
   p 'blows up'
end

BEGIN {

   module Timing
     class Error < ::StandardError; end

     def Timing.out *seconds, &block
       if seconds.empty?
         return Error
       else
         seconds = Float seconds.first
       end

       pid = Process.pid
       signaler = IO.popen "ruby -e'sleep #{ seconds }; Process.kill(:TERM.to_s, #{ pid }) rescue nil'"
       thread = Thread.current
       handler = Signal.trap('TERM'){ thread.raise Error, seconds.to_s }
       begin
         block.call
       ensure
         Process.kill 'TERM', signaler.pid rescue nil
         Signal.trap('TERM', handler)
       end
     end

     ::Timed = Timing
   end

}

cfp:~ > ruby a.rb
"works"
"times out"
a.rb:34:in `out': 1.0 (Timing::Error)
         from a.rb:14:in `call'
         from a.rb:14:in `sleep'
         from a.rb:14
         from a.rb:36:in `call'
         from a.rb:36:in `out'
         from a.rb:13

a @ http://codeforpeople.com/

···

On Aug 8, 2008, at 7:58 AM, Bryan Richardson wrote:

Hell all,

I'm looking for a way to implement a non-threaded timeout. I am running
some Monte Carlo simulations using an external application via an OLE
interface. There are times where the external application seems to hang
up, so I'm looking for a way to detect this and continue on with my
simulation if the external application takes too long.

Any suggestions?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Hello Hemant,

Thanks for responding. I am running my application on Windows (the
external app I'm interfacing with is Windows-only), so I'm not sure if
this will help me out... unless it can be configured to not use threads.
I haven't tried timeout.rb because I'm under the impression (from
documentation) that it uses threads and I can't use threads in the Monte
Carlo simulation.

···

--
Thanks!
Bryan

Hemant Kumar wrote:

http://ph7spot.com/articles/system_timer

--
Posted via http://www.ruby-forum.com/\.

Wow... thanks! I need to come up to speed a little more on Signals and
such, but I think I get the gist of your suggested code. I never even
considered doing it this way.

···

--
Thanks again!
Bryan

Ara Howard wrote:

slightly more complete - may need tweaks for windoze....

--
Posted via http://www.ruby-forum.com/\.

Hi Ara,

I tried the code you suggested on my Windows box and the test fails. I
assume it has something similar to do with your two posts below:

http://objectmix.com/ruby/321533-portable-signals.html
http://groups.google.com/group/ruby-talk-google/browse_frm/thread/e8478acbffe804cb

Any suggestions on how to make this work on Windows?

···

--
Thanks!
Bryan

Ara Howard wrote:

something like this should be able to work, even on windows....

--
Posted via http://www.ruby-forum.com/\.

Bryan Richardson wrote:

Hello Hemant,

Thanks for responding. I am running my application on Windows (the external app I'm interfacing with is Windows-only), so I'm not sure if this will help me out... unless it can be configured to not use threads. I haven't tried timeout.rb because I'm under the impression (from documentation) that it uses threads and I can't use threads in the Monte Carlo simulation.

Why can't you use threads to drive your Monte Carlo simulation?

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

it's not perfect to be sure, but i don't think anything else will be able to work on windows due the ruby's current threading model.

cheers.

a @ http://codeforpeople.com/

···

On Aug 8, 2008, at 8:46 PM, Bryan Richardson wrote:

Wow... thanks! I need to come up to speed a little more on Signals and
such, but I think I get the gist of your suggested code. I never even
considered doing it this way.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

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.

cheers.

a @ http://codeforpeople.com/

···

On Aug 11, 2008, at 7:32 AM, Bryan Richardson wrote:

Hi Ara,

I tried the code you suggested on my Windows box and the test fails. I
assume it has something similar to do with your two posts below:

http://objectmix.com/ruby/321533-portable-signals.html
http://groups.google.com/group/ruby-talk-google/browse_frm/thread/e8478acbffe804cb

Any suggestions on how to make this work on Windows?

--
Thanks!
Bryan

Ara Howard wrote:

something like this should be able to work, even on windows....

--
Posted via http://www.ruby-forum.com/\.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Hi Joel,

Well, for one thing, I'm short on time and haven't designed it to work
that way. :slight_smile: Also, the Ruby interface I've developed for accessing the
external application via the OLE interface has been designed as a
Singleton and I don't know how well that would work with threads...
without a lot of work synchronizing things and such.

···

--
Thanks!
Bryan

Joel VanderWerf wrote:

Why can't you use threads to drive your Monte Carlo simulation?

--
Posted via http://www.ruby-forum.com/\.

Hi Ara,

I agree that the *principal* of the idea is about the only one to pursue
on Windows. I tried the following code:

def timeout seconds, key, &block
pid = Process.pid
signaler = IO.popen "ruby -e'sleep #{ seconds };
Process.kill(:#{key}.to_s, #{ pid }) rescue nil'"
handler = Signal.trap(key){ raise 'timed out...' }
begin
  block.call
ensure
  Process.kill key, signaler.pid rescue nil
  Signal.trap(key, handler)
end
end

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.

--
Posted via http://www.ruby-forum.com/\.

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?

···

--
Thanks!
Bryan
--
Posted via http://www.ruby-forum.com/.

I'm probably very confused, but isn't the the OLE interface
asynchronous already?
Aren't you already waiting until it is done?

The following example runs excel until I close it from the menu, or 30
seconds, whichever comes first. I'd think you could apply the same
thing to your app, especially if your simulation closes itself.

-Adam

···

On 8/8/08, Bryan Richardson <btrichardson@gmail.com> wrote:

I'm looking for a way to implement a non-threaded timeout

  Also, the Ruby interface I've developed for accessing the
external application via the OLE interface has been designed as a
Singleton and I don't know how well that would work with threads...
without a lot of work synchronizing things and such.

-------------------------------------------------------------------------------------
excel = WIN32OLE.new("excel.application")
excel['Visible'] = TRUE;
t = Time.now
while ((Time.now - t) < IT_SHOULD_NEVER_RUN_THIS_LONG)
  break if !excel.Visible #using Visible to check if it is running
                                  #there is probably a better test.
  sleep(1)
end
excel.Quit();

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.

a @ http://codeforpeople.com/

···

On Aug 11, 2008, at 4:48 PM, Bryan Richardson wrote:

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?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Hi Adam,

Well, now I think I'm confused too! :slight_smile:

I do not believe the OLE interface is asynchronous, as I do wait for
results from it before moving on. Therefore, yes I am waiting until it
is done. However, if the program on the other end of the OLE connection
hangs, I'd like to move on by killing the interface and starting a new
one.

The code you suggested seems like a good way to go, however I don't know
what I would test to see if it's still responding. I'll look into that.

···

--
Thanks!
Bryan

Adam Shelly wrote:

I'm probably very confused, but isn't the the OLE interface
asynchronous already?
Aren't you already waiting until it is done?

The following example runs excel until I close it from the menu, or 30
seconds, whichever comes first. I'd think you could apply the same
thing to your app, especially if your simulation closes itself.

-Adam
-------------------------------------------------------------------------------------
excel = WIN32OLE.new("excel.application")
excel['Visible'] = TRUE;
t = Time.now
while ((Time.now - t) < IT_SHOULD_NEVER_RUN_THIS_LONG)
  break if !excel.Visible #using Visible to check if it is running
                                  #there is probably a better test.
  sleep(1)
end
excel.Quit();

--
Posted via http://www.ruby-forum.com/\.

Got it. Thanks for taking the time to explain it to me.

···

--
Bryan

On Mon, Aug 11, 2008 at 7:07 PM, ara.t.howard <ara.t.howard@gmail.com> wrote:

On Aug 11, 2008, at 4:48 PM, Bryan Richardson wrote:

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.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
h.h. the 14th dalai lama

How exactly do you wait for results? Do you test some property?
Can't you use that test as your loop sentinel?
`break if !monty.Results.empty?` or something like that...

···

On 8/8/08, Bryan Richardson <btrichardson@gmail.com> wrote:

I do not believe the OLE interface is asynchronous, as I do wait for
results from it before moving on. Therefore, yes I am waiting until it
is done.
The code you suggested seems like a good way to go, however I don't know
what I would test to see if it's still responding.

Alright, so here's what I've now been trying:

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', <pid>) 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.
reinitialize @sim
end

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...

Any ideas?!

···

--
Thanks!
Bryan

hi adam,

i don't test a property because the ole interface is not asynchronous.
my code looks like this -

do stuff...
result = @sim.RunScriptCommand('SolvePrimalLP()')
do stuff...

when the ole application hangs i never get to the second 'do stuff...'

···

--
bryan

Adam Shelly wrote:

How exactly do you wait for results? Do you test some property?
Can't you use that test as your loop sentinel?
`break if !monty.Results.empty?` or something like that...

--
Posted via http://www.ruby-forum.com/\.