DRb & thread blocking

Greetings,

I added a post earlier today in hopes someone might know right off hand why
the Ruby progam I’ve written was not functioning as expected. I didn’t have
a lot to go on, nor to share so someone could advise me. So, I spent some
time stripping my problem child down to its bare minimum and the problem is
persisting. Can anyone explain to my why this little program seems to block
DRb from responding to calls when a thread in the same app has called
gets()? Here’s the code & instructions. Thanks in advance for any insight
you can provide. I hope to return the favor in the future.

···

app.rb

Instructions: run this program (app.rb) in one shell THEN run

myclnt.rb in a separate shell. If the call to “gets” at line

43 (below) is active, calls to MyServer::service from myclnt.rb

seem to be blocked. Pressing [enter] (w/a short sleep provided

to better illustrate the problem), allows the DRb calls from

myclnt.rb to be processed, that is right up until the next call

to gets. Commenting out the call to gets, re-running app.rb,

and then re-running myclnt.rb shows the problem has “gone away.”

require 'thread’
require ‘drb’

MyServer handles calls from myclnt.rb - just returns an I’m alive message.

class MyServer
def service
"MyServer is alive!!!"
end
end

class App

def initialize()

array of threads, 1 for DRb and 1 for my command loop,

@services = []
end

def run()

Start MyServer service and store thread.

svr = MyServer.new();
DRb.start_service(‘druby://localhost:9000’, svr);
@services << DRb.thread;

Start command loop. *** When “gets” is called DRb appears to block:.

calls to it from myclnt.rb stall until enter is pressed, thereby

giving enough cycles to DRb.thread to respond to the request?!?!?

@services << Thread.new {
while true
print "Prompt> "
# comment out the next line and then rerun app.rb and myclnt.rb
#exit if gets.chomp() == “exit”;
sleep(1)
end
}

@services.each {|svc| svc.join()}
end

end

App.new().run();


myclnt.rb

require ‘drb’

puts "Running my client…"
DRb.start_service(nil,nil)

while true
svr = DRbObject.new(nil, ‘druby://localhost:9000’)
puts "Calling server…"
puts "Server returned: " + svr.service;
end

ken-

so far, this seems to work fine on my box? what’s you platform/arch/ruby
version, etc?

-a

···

On Wed, 28 Apr 2004, Ken Hilton wrote:

Greetings,

I added a post earlier today in hopes someone might know right off hand why
the Ruby progam I’ve written was not functioning as expected. I didn’t have
a lot to go on, nor to share so someone could advise me. So, I spent some
time stripping my problem child down to its bare minimum and the problem is
persisting. Can anyone explain to my why this little program seems to block
DRb from responding to calls when a thread in the same app has called
gets()? Here’s the code & instructions. Thanks in advance for any insight
you can provide. I hope to return the favor in the future.


app.rb

Instructions: run this program (app.rb) in one shell THEN run

myclnt.rb in a separate shell. If the call to “gets” at line

43 (below) is active, calls to MyServer::service from myclnt.rb

seem to be blocked. Pressing [enter] (w/a short sleep provided

to better illustrate the problem), allows the DRb calls from

myclnt.rb to be processed, that is right up until the next call

to gets. Commenting out the call to gets, re-running app.rb,

and then re-running myclnt.rb shows the problem has “gone away.”

require ‘thread’
require ‘drb’

MyServer handles calls from myclnt.rb - just returns an I’m alive message.

class MyServer
def service
“MyServer is alive!!!”
end
end

class App

def initialize()

array of threads, 1 for DRb and 1 for my command loop,

@services =
end

def run()

Start MyServer service and store thread.

svr = MyServer.new();
DRb.start_service(‘druby://localhost:9000’, svr);
@services << DRb.thread;

Start command loop. *** When “gets” is called DRb appears to block:.

calls to it from myclnt.rb stall until enter is pressed, thereby

giving enough cycles to DRb.thread to respond to the request?!?!?

@services << Thread.new {
while true
print "Prompt> "
# comment out the next line and then rerun app.rb and myclnt.rb
#exit if gets.chomp() == “exit”;
sleep(1)
end
}

@services.each {|svc| svc.join()}
end

end

App.new().run();


myclnt.rb

require ‘drb’

puts “Running my client…”
DRb.start_service(nil,nil)

while true
svr = DRbObject.new(nil, ‘druby://localhost:9000’)
puts “Calling server…”
puts "Server returned: " + svr.service;
end

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================

Ruby 1.8.1 from Pragmatic Programmers installable, w/problem duplicated in
Win2000 and WinXP - I’m stumped.

Ken.

PS. Thanks Ara.

“Ara.T.Howard” ahoward@fattire.ngdc.noaa.gov wrote in message
news:Pine.LNX.4.44.0404272224390.10053-100000@fattire.ngdc.noaa.gov

ken-

so far, this seems to work fine on my box? what’s you platform/arch/ruby
version, etc?

-a

Greetings,

I added a post earlier today in hopes someone might know right off hand
why
the Ruby progam I’ve written was not functioning as expected. I didn’t
have
a lot to go on, nor to share so someone could advise me. So, I spent
some
time stripping my problem child down to its bare minimum and the problem
is
persisting. Can anyone explain to my why this little program seems to
block
DRb from responding to calls when a thread in the same app has called
gets()? Here’s the code & instructions. Thanks in advance for any
insight
you can provide. I hope to return the favor in the future.


app.rb

Instructions: run this program (app.rb) in one shell THEN run

myclnt.rb in a separate shell. If the call to “gets” at line

43 (below) is active, calls to MyServer::service from myclnt.rb

seem to be blocked. Pressing [enter] (w/a short sleep provided

to better illustrate the problem), allows the DRb calls from

myclnt.rb to be processed, that is right up until the next call

to gets. Commenting out the call to gets, re-running app.rb,

and then re-running myclnt.rb shows the problem has “gone away.”

require ‘thread’
require ‘drb’

MyServer handles calls from myclnt.rb - just returns an I’m alive

message.

···

On Wed, 28 Apr 2004, Ken Hilton wrote:

class MyServer
def service
“MyServer is alive!!!”
end
end

class App

def initialize()

array of threads, 1 for DRb and 1 for my command loop,

@services =
end

def run()

Start MyServer service and store thread.

svr = MyServer.new();
DRb.start_service(‘druby://localhost:9000’, svr);
@services << DRb.thread;

Start command loop. *** When “gets” is called DRb appears to block:.

calls to it from myclnt.rb stall until enter is pressed, thereby

giving enough cycles to DRb.thread to respond to the request?!?!?

@services << Thread.new {
while true
print "Prompt> "
# comment out the next line and then rerun app.rb and myclnt.rb
#exit if gets.chomp() == “exit”;
sleep(1)
end
}

@services.each {|svc| svc.join()}
end

end

App.new().run();


myclnt.rb

require ‘drb’

puts “Running my client…”
DRb.start_service(nil,nil)

while true
svr = DRbObject.new(nil, ‘druby://localhost:9000’)
puts “Calling server…”
puts "Server returned: " + svr.service;
end

============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done

============================================================================

Ara.T.Howard wrote:

ken-

so far, this seems to work fine on my box? what’s you platform/arch/ruby
version, etc?

-a

Posting with OE6, I guess the answer’s going to be Windows.

So gets() blocks everything.

If anyone knows the work-around to this, please add.

daz

Ruby 1.8.1 from Pragmatic Programmers installable, w/problem
duplicated in Win2000 and WinXP - I’m stumped.

Yep, #gets always blocks win32.

This was a problem with the DRb examples, and most of them have been
changed to use DRb.thread.join rather than #gets.

Unfortunately, this is rather useless if you want to use #gets for
actual input.

My untested attempt at a solution is “try non-blocking IO”. (I don’t
have a windows box to play with at the moment, and it is my bedtime.)

···

Ken Hilton (kenosis@comcast.net) wrote:

On Wed, 28 Apr 2004, Ken Hilton wrote:

Greetings,

I added a post earlier today in hopes someone might know right off
hand why the Ruby progam I’ve written was not functioning as
expected. I didn’t have a lot to go on, nor to share so someone
could advise me. So, I spent some time stripping my problem child
down to its bare minimum and the problem is persisting. Can
anyone explain to my why this little program seems to block DRb
from responding to calls when a thread in the same app has called
gets()? Here’s the code & instructions. Thanks in advance for
any insight you can provide. I hope to return the favor in the
future.


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

in linux this should work, but doesn’t (threads)

require ‘io/nonblock’
buf = io.nonblock{io.read}

this is lame, but might work (i don’t know if io/wait is in windows inst)

buf = ‘’
buf << io.getc while io.ready?

don’t know much about the windows ruby…

-a

···

On Wed, 28 Apr 2004, daz wrote:

Ara.T.Howard wrote:

ken-

so far, this seems to work fine on my box? what’s you platform/arch/ruby
version, etc?

-a

Posting with OE6, I guess the answer’s going to be Windows.

So gets() blocks everything.

If anyone knows the work-around to this, please add.

daz

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================

I’d suggest using the cygwin Ruby. I’ve used it as a workaround for similar
threading problems on Windows.

···

At 12:09 AM 4/28/2004, daz wrote:

Posting with OE6, I guess the answer’s going to be Windows.

So gets() blocks everything.

If anyone knows the work-around to this, please add.


Bret Pettichord, Software Tester
Consultant - www.pettichord.com
Author - www.testinglessons.com
Blogger - www.io.com/~wazmo/blog

Homebrew Automation Seminar
Scripting for Testers Tutorial
Portland, Seattle, Orlando, Austin
www.pettichord.com/training.html

If anyone knows the work-around to this, please add.

Hope this is of general use for STDIN#gets in a thread.
It checks for input in the keyboard buffer and if there
is any, does a normal (blocking) STDIN#gets.

STDIN#wt_gets for Windows

Doesn’t block threads until there’s input.

Won’t run from GUIs (e.g. RDE, SciTE …)

(see kbhit API docs.)

require ‘Win32API’
W_kbhit = Win32API.new(‘msvcrt’, ‘_kbhit’, ‘’, ‘I’)

def STDIN.key_wait
while W_kbhit.call == 0; sleep 0.1; end
end

def STDIN.wt_gets
key_wait
gets
end

#----- Usage …

STDOUT.sync = true

Thread.new do
loop do
puts Time.now
sleep 1
end
end

Thread.new do
loop do
inp = STDIN.wt_gets.chomp!
inp.upcase == ‘EXIT’ and Thread.exit
puts inp
end
end.join

puts “\n\nPress a key to really exit …\n\n”
STDIN.key_wait # defined above

···

#----------

I tried a VRuby GUI solution but it became a bit too
feature-packed. Couldn’t hold myself back :slight_smile:

daz

Hi,

At Wed, 28 Apr 2004 22:04:08 +0900,
Ara.T.Howard wrote in [ruby-talk:98643]:

in linux this should work, but doesn’t (threads)

require ‘io/nonblock’
buf = io.nonblock{io.read}

this is lame, but might work (i don’t know if io/wait is in windows inst)

buf = ‘’
buf << io.getc while io.ready?

don’t know much about the windows ruby…

Both don’t work on Windows at all.

···


Nobu Nakada

Thanks much. I’ll give it a try. Something I also noticed was the
following: select([$stdin],nil,nil) always returns true when called
immediately before calling gets() on Windows. Hmmm…

Kind Regards,

Ken.

“daz” dooby@d10.karoo.co.uk wrote in message
news:pbCdnQhPWaQC2g3dSa8jmA@karoo.co.uk

···

If anyone knows the work-around to this, please add.

Hope this is of general use for STDIN#gets in a thread.
It checks for input in the keyboard buffer and if there
is any, does a normal (blocking) STDIN#gets.

STDIN#wt_gets for Windows

Doesn’t block threads until there’s input.

Won’t run from GUIs (e.g. RDE, SciTE …)

(see kbhit API docs.)

require ‘Win32API’
W_kbhit = Win32API.new(‘msvcrt’, ‘_kbhit’, ‘’, ‘I’)

def STDIN.key_wait
while W_kbhit.call == 0; sleep 0.1; end
end

def STDIN.wt_gets
key_wait
gets
end

#----- Usage …

STDOUT.sync = true

Thread.new do
loop do
puts Time.now
sleep 1
end
end

Thread.new do
loop do
inp = STDIN.wt_gets.chomp!
inp.upcase == ‘EXIT’ and Thread.exit
puts inp
end
end.join

puts “\n\nPress a key to really exit …\n\n”
STDIN.key_wait # defined above

#----------

I tried a VRuby GUI solution but it became a bit too
feature-packed. Couldn’t hold myself back :slight_smile:

daz