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.
Check out Timeout in the standard lib.
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html
···
On Mon, Dec 18, 2006 at 08:55:10AM +0900, Michael W. Ryder wrote:
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.
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
Logan Capaldo wrote:
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.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.
···
On Mon, Dec 18, 2006 at 08:55:10AM +0900, Michael W. Ryder wrote:
Michael W. Ryder wrote:
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.
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.
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
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?
···
On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
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 Capaldo wrote:
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.
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?
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?
···
On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
Joel VanderWerf wrote:
Michael W. Ryder wrote:
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.
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.
I believe the other thread established that this kind of code works in
Cygwin and msys built rubies.
···
On Mon, Dec 18, 2006 at 12:00:06PM +0900, Michael W. Ryder wrote:
Logan Capaldo wrote:
>On Mon, Dec 18, 2006 at 10:40:05AM +0900, Michael W. Ryder wrote:
>>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.
>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?
>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?
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
I personally prefer cygwin on Windows boxes anyway because you have a nice shell, environment etc.
Kind regards
robert
···
On 18.12.2006 03:59, Michael W. Ryder wrote:
Logan Capaldo wrote:
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?
Robert Klemme wrote:
···
On 18.12.2006 03:59, Michael W. Ryder wrote:
Logan Capaldo wrote:
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?
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 CygwinRobert@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:3Robert@Babelfish2 ~
$ ruby x.rb
12345I 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.
gem install linux ?
-a
···
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.
--
if you find yourself slandering anybody, first imagine that your mouth is
filled with excrement. it will break you of the habit quickly enough. - the
dalai lama
Michael W. Ryder wrote:
Robert Klemme wrote:
Logan Capaldo wrote:
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?
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 CygwinRobert@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:3Robert@Babelfish2 ~
$ ruby x.rb
12345I 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.
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.
···
On 18.12.2006 03:59, Michael W. Ryder wrote:
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.
···
ara.t.howard@noaa.gov 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