Skip to content

Instantly share code, notes, and snippets.

@reprah
Created October 5, 2013 17:36
Show Gist options
  • Save reprah/6843916 to your computer and use it in GitHub Desktop.
Save reprah/6843916 to your computer and use it in GitHub Desktop.
Ruby methods in io/nonblock
#
# Documenting io/nonblock and how the methods (nonblock?, nonblock=, nonblock{}) there behave
#
# server.rb
require 'socket'
TCPServer.open('localhost', 3030) do |server|
while client = server.accept
sleep()
end
end
# Connect to server in IRB
~$ irb
:001 > require 'socket'
=> true
:002 > require 'io/nonblock'
=> true
:003 > s = TCPSocket.new('localhost', 3030)
=> #<TCPSocket:fd 5>
:004 > s.nonblock?
=> false
:005 > s.nonblock = 0 # put it into nonblocking mode
=> 0
:006 > s.nonblock?
=> true
:007 > s.recv(1)
# This is blocking, so I expected it to raise an exception, but it waits for data instead
:011 > s.nonblock { |s| s.recv(1) }
# This hangs too
#
# This is how a similar method works in Python, and it's the behavior I was expecting
# from putting a socket into blocking/nonblocking mode
#
# server.py
import SocketServer
import time
class TCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
time.sleep(5000)
if __name__ == "__main__":
server = SocketServer.TCPServer(('localhost', 3030), TCPHandler)
server.serve_forever()
# Connect to server in python REPL
~$ python
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.connect(('localhost', 3030))
>>> s.setblocking(0) # set nonblocking mode on the socket
>>> s.recv(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 11] Resource temporarily unavailable
# So we get an exception like I expected, because there's no immediately available data
>>> s.setblocking(1) # put it back into blocking mode
>>> s.recv(1)
# hangs and waits for data instead of raising exception, like I expected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment