I am a veteran programmer but still am trying to learn Ruby. In the
language I have been using for over 25 years input has an option to
terminate after x number of seconds, something that seems to be missing
in Ruby. I use this ability to log off sessions when the user leaves
the computer for a time along with other purposes.
Is it possible in Ruby to use two threads for input, one for reading
from the selected source and the second that would terminate the first
thread if it hadn’t completed in the specified amount of time? The main
program would start the first thread and feed the PID to the second
thread along with the number of seconds, or milliseconds, to sleep. The
second thread would then see if the first thread is still alive when it
wakes up and if so terminate it. Either way the second thread would
exit after the number of seconds given.
On Mon, Dec 18, 2006 at 08:55:10AM +0900, Michael W. Ryder wrote:
second thread would then see if the first thread is still alive when it
wakes up and if so terminate it. Either way the second thread would
exit after the number of seconds given.
Check out Timeout in the standard lib.
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html
also, try the highline gem for help in dealing with input in general
Timeout:timeout creates a new thread with a time limit. Is would not
be to hard to hack it up to make a way to be able to keep reseting that
timer if you didn’t want the overhead of continually creating new
threads.
One approach would be to implement a rescue and then retry if you have
received input. Here is my quick attempt. The thread which calls
timeout is responsible to keep setting Thread.current[:timeout] = false
whenever it receives input
def timeout(sec, exception=Error)
return yield if sec == nil or sec.zero?
raise ThreadError, “timeout within critical session” if
Thread.critical
begin
x = Thread.current
y = Thread.start {
begin
until x[:timeout]
x[:timeout] = true
sleep sec
end
x.raise exception, “execution expired” if x.alive?
end
}
yield sec
# return true
ensure
y.kill if y and y.alive?
end
end
Thread.abort_on_exception = true
Michael W. Ryder wrote:
If I enter something, say 123, then the program displays the 123 as
expected. If I just wait it sits there until I enter something which is
not what I want. I want the input to terminate and display that foo is
‘nil’. For some reason testing the value of status shows that it is the
same as the input, but this may not be relevant to the problem.
That’s a problem with the combination of the msvc-based ruby on windows
and gets and threads (Timeout uses a thread). There was a discussion in
the ruby-talk list with subject “Thread and sleep” a few days ago.
On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
If I enter something, say 123, then the program displays the 123 as
expected. If I just wait it sits there until I enter something which is
not what I want. I want the input to terminate and display that foo is
‘nil’. For some reason testing the value of status shows that it is the
same as the input, but this may not be relevant to the problem.
It works for me (well actually timeout throws an exception when the time
runs out, doesn’t just baort gracefully, but that’s what it’s supposed
to do.)
What platform are you on?
Logan C. wrote:
thread along with the number of seconds, or milliseconds, to sleep. The
second thread would then see if the first thread is still alive when it
wakes up and if so terminate it. Either way the second thread would
exit after the number of seconds given.
Check out Timeout in the standard lib.
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html
Maybe I am missing something here but it doesn’t seem to work for me. I
have the following simple program:
require ‘timeout’
foo = nil
status = Timeout::timeout(5) {
foo = gets()
}
puts (foo)
If I enter something, say 123, then the program displays the 123 as
expected. If I just wait it sits there until I enter something which is
not what I want. I want the input to terminate and display that foo is
‘nil’. For some reason testing the value of status shows that it is the
same as the input, but this may not be relevant to the problem.
Logan C. wrote:
Windows XP Pro, which I guess is part of the problem. The problem I
have with Ruby is that I know it is possible to get this to work in
other languages, BBX (Business Basic) for example. It may be that
because BBX did not use Microsoft compilers, it has been out longer than
Microsoft has existed, that it doesn’t have some limitations built into
the Microsoft compilers. This of course raises the question is there a
free compiler, such as gcc, which could compile Ruby without the thread
lock problem?
Joel VanderWerf wrote:
If I enter something, say 123, then the program displays the 123 as
expected. If I just wait it sits there until I enter something which
is not what I want. I want the input to terminate and display that
foo is ‘nil’. For some reason testing the value of status shows that
it is the same as the input, but this may not be relevant to the problem.That’s a problem with the combination of the msvc-based ruby on windows
and gets and threads (Timeout uses a thread). There was a discussion in
the ruby-talk list with subject “Thread and sleep” a few days ago.
I read that thread which was why I was wondering if one could use two
threads, one for the gets, and one to terminate that thread after a
period of time if the first thread hadn’t already gotten input and
terminated. I know that most non-Microsoft based Operating Systems
don’t have this problem but as Microsoft has the majority of the market
programs have to be able to work on their OS. The language I have been
using for over 25 years works identically on a very large number of
platforms from PCs to mainframes so I would think Ruby would be able to
do the same, if not today then in the near future.
On Mon, Dec 18, 2006 at 12:00:06PM +0900, Michael W. Ryder wrote:
puts (foo)
What platform are you on?Windows XP Pro, which I guess is part of the problem. The problem I
have with Ruby is that I know it is possible to get this to work in
other languages, BBX (Business Basic) for example. It may be that
because BBX did not use Microsoft compilers, it has been out longer than
Microsoft has existed, that it doesn’t have some limitations built into
the Microsoft compilers. This of course raises the question is there a
free compiler, such as gcc, which could compile Ruby without the thread
lock problem?
I believe the other thread established that this kind of code works in
Cygwin and msys built rubies.
Robert K. wrote:
question is there a free compiler, such as gcc, which could compile
$ ruby -v12345
I personally prefer cygwin on Windows boxes anyway because you have a
nice shell, environment etc.Kind regards
robert
I just tried this on Cygwin using Ruby 1.8.4 and still have the same
problem I had with the Windows version. It still waits for I/O and
status is the same as the input. Neither is what I am looking for.
On 18.12.2006 03:59, Michael W. Ryder wrote:
lock problem?
You can use cygwin’s Ruby - this works as expected for me on a Win XP
Home (and I guess also Pro):
Robert@Babelfish2 ~
$ uname -a
CYGWIN_NT-5.1 Babelfish2 1.5.21(0.156/4/2) 2006-07-30 14:21 i686 Cygwin
Robert@Babelfish2 ~
$ ruby -v
ruby 1.8.5 (2006-08-25) [i386-cygwin]
Robert@Babelfish2 ~
$ cat x.rb
require ‘timeout’
foo = nil
status = Timeout::timeout(5) {
foo = gets()
}
puts (foo)
Robert@Babelfish2 ~
$ ruby x.rb
/usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error)
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout’
from x.rb:3
Robert@Babelfish2 ~
$ ruby x.rb
12345
12345
I personally prefer cygwin on Windows boxes anyway because you have a
nice shell, environment etc.
Kind regards
robert
[email protected] wrote:
On Thu, 21 Dec 2006, Michael W. Ryder wrote:
I just tried this on Cygwin using Ruby 1.8.4 and still have the same
problem I had with the Windows version. It still waits for I/O and
status is the same as the input. Neither is what I am looking for.gem install linux ?
-a
Are you saying that I need to run this test under Linux? I thought the
whole point of any language was that it worked the same way on any
supported OS.
On Thu, 21 Dec 2006, Michael W. Ryder wrote:
I just tried this on Cygwin using Ruby 1.8.4 and still have the same problem
I had with the Windows version. It still waits for I/O and status is the
same as the input. Neither is what I am looking for.
gem install linux ?
-a
Michael W. Ryder wrote:
built into the Microsoft compilers. This of course raises the
Robert@Babelfish2 ~
puts (foo)
12345
problem I had with the Windows version. It still waits for I/O and
status is the same as the input. Neither is what I am looking for.
I found out that Cygwin for some reason had not installed Ruby and was
using the Windows version. I reinstalled Ruby and got the same output
as Robert. Now I guess the next thing is to figure out how to catch the
exception and figure out why status seems to have no meaning.