views:

48

answers:

1

I'm trying to write a server connection in Ruby that will spawn a thread to handle incoming connections. This thread will then interpret the incoming data, then place some instructions in a queue to be processed by the main program loop at its convenience. However, I seem to have some issues with the queue processing, as the program seems to either block somewhere, or the main loop just stops working unexpectedly. It's somewhat hard to explain so, here is the listen method for my server socket:

def listen
  @socket = TCPServer.open(@ip, @port)

  while @looping do
    puts "Waiting for socket accept"
    server = @socket.accept
    puts "Socket accepted"
    serverloop = Thread.new do
      puts "Waiting for response"
      response = server.read
      puts "Command received: #{response}"
      parse_command(response)
      puts "Response complete"
    end 
    processloop = Thread.new do
      while @looping do  
        process_command_queue
        process_response_queue
      end 
    end 
    if interrupted
      exit
    end 
  end 
end

def process_command_queue
  puts "In the command queue"
  if @command_queue.length > 0 
    @command = @queue.pop
    @command.process
  end 
end

When a connection is made, here is the output:

magicked$ ./server.rb 
Waiting for socket accept
Socket accepted
Waiting for response
In the command queue
In the command queue ... (repeats)
Waiting for socket accept
In the command queue
In the command queue ... (repeats a lot)
Command received: EXEC 1 1 thisisacommand
Command initialized: EXEC 1 1 thisisacommand
Response complete

After this, it pauses again and waits for another connection/command. What I expected to see was the "In the command queue" continuing to repeat.

I probably haven't entirely wrapped my head around the way ruby threads work yet. I know the instance of the ruby interpreter has limitations when doing multiple threads. So is the loop reaching the @socket.accept again and it's blocking other instructions while waiting for another connection? Is my first thread completing and joining back up with the main thread, causing the second thread to do the same? Do I need to fork another ruby interpreter to handle one of these?

Finally, does anyone recommend a good resource that will help explain more advanced ruby threading? I've found plenty of simple instances, but obviously I still have a lot of confusion remaining.

Thanks for the help!

+1  A: 

You should use eventmachine.

Marc-André Lafortune
`evenmachine` -> `eventmachine`?
Adrian
@Adrian: yes, thanks, and thanks to theIV for the edit.
Marc-André Lafortune