codeslinger
2/23/2006 6:08:00 PM
Nevermind about question 2 above. I figured it out. Defining the
lambdas in the previous manner put them in the class scope, not object
instance scope. Here's how to make that work:
puma:~> cat a.rb
require 'socket'
class X
def thread_init
@connection_main = lambda do |sock|
begin
data = sock.gets
handle_sock_data data
rescue => e
puts "#{e.message}:\n\t#{e.backtrace.join("\n\t")}"
raise e
ensure
sock.close rescue nil
end
end
@server_main = lambda do |srv|
begin
while true
s = srv.accept
Thread.start s, &@connection_main
end
rescue => e
puts "#{e.message}:\n\t#{e.backtrace.join("\n\t")}"
ensure
srv.close
end
end
end
def initialize
srv = TCPServer.new nil, 8008
Thread.abort_on_exception = true
thread_init
Thread.start srv, &@server_main
while true
# doing main thread stuff in here
sleep 5
puts Thread.list.join(',')
end
end
def handle_sock_data data
# do something with data here
puts "called handle_sock_data: '#{data.strip}'"
end
end # class X
x = X.new
puma:~>
This outputs:
puma:~> ruby a.rb
called handle_sock_data: 'hello'
#<Thread:0xb7d0fe3c>,#<Thread:0xb7d0fd10>,#<Thread:0xb7d1e748>
called handle_sock_data: 'goodbye'
#<Thread:0xb7d0fe3c>,#<Thread:0xb7d1e748>
#<Thread:0xb7d0fe3c>,#<Thread:0xb7d1e748>
#<Thread:0xb7d0fe3c>,#<Thread:0xb7d1e748>
a.rb:37:in `sleep': Interrupt
from a.rb:37:in `initialize'
from a.rb:49
puma:~>
I Ctrl-C'd it there at the end.
It would seem that I don't need to worry about the Thread
detached/setDaemon functionality, either, since the client
@connection_main threads seem to get cleaned up without having to
explicitly join them. Arigatou gozaimasu, Matsumoto-san :)