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

On Fri, Aug 8, 2008 at 7:28 PM, Bryan R.
[email protected] 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.

http://ph7spot.com/articles/system_timer

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 K. wrote:

http://ph7spot.com/articles/system_timer

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?

Bryan R. 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?

On 8/8/08, Bryan R. [email protected] 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.

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();

On 8/8/08, Bryan R. [email protected] 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.

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…

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 S. 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();

what about starting another thread to monitor my results variable… i
still don’t fully understand the scope of variables when a thread is
started.


bryan

Bryan R. wrote:

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

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

Hi Joel,

RunScriptCommand is a OLE/COM call, so it’s not going over TCP. I would
say it’s definately a lower-level C call.


Bryan

Joel VanderWerf wrote:

I don’t know much about ole… is RunScriptCommand blocking on a tcp
socket call? If so, it should be possible to wrap a timeout block around
RunScriptCommand. The timeout block starts another thread. If the
timeout fires, the blocked call will be interrupted (ruby’s thread
scheduler works well if threads are blocked on socket ops, but not
arbitrary C functions). You can rescue and clean up the socket.

Bryan R. wrote:

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…’

I don’t know much about ole… is RunScriptCommand blocking on a tcp
socket call? If so, it should be possible to wrap a timeout block around
RunScriptCommand. The timeout block starts another thread. If the
timeout fires, the blocked call will be interrupted (ruby’s thread
scheduler works well if threads are blocked on socket ops, but not
arbitrary C functions). You can rescue and clean up the socket.

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

Any suggestions?


Thanks!
Bryan

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

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 R. wrote:

Any suggestions?
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 5:41 PM, Joel VanderWerf wrote:

Ah, so then ruby threads are not going to help at all. The whole
ruby interpreter will be blocked by OLE.

signals should still work though - even on windows…

a @ http://codeforpeople.com/

Bryan R. wrote:

Hi Joel,

RunScriptCommand is a OLE/COM call, so it’s not going over TCP. I would
say it’s definately a lower-level C call.

Ah, so then ruby threads are not going to help at all. The whole ruby
interpreter will be blocked by OLE.

On Aug 8, 2008, at 8:46 PM, Bryan R. 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.

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/

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…

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…

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


Thanks!
Bryan

Ara Howard wrote:

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

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

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/