Permalink
Browse files

add a listener using the socket module.

While uv watchers are evry fast it may be interresting to use the socket
module as well so we can easily wrap later connections to handle SSL and
also reuse shared TCP sockets on unix. (so we can eventually use this
listener in gunicorn as well.
  • Loading branch information...
1 parent e866026 commit abeed04a625aa9ea5ad336ffe94515c4b83e1636 @benoitc committed Sep 11, 2012
Showing with 471 additions and 6 deletions.
  1. +35 −0 examples/echo_sockserver.py
  2. +27 −3 flower/io.py
  3. +4 −1 flower/net/__init__.py
  4. +387 −0 flower/net/sock.py
  5. +3 −0 flower/net/tcp.py
  6. +14 −1 flower/net/udp.py
  7. +1 −1 setup.py
@@ -0,0 +1,35 @@
+# Echo server program
+from flower import tasklet, run
+from flower.net import Listen
+
+
+# handle the connection. It return data to the sender.
+def handle_connection(conn):
+ while True:
+ data = conn.read()
+ if not data:
+ break
+
+ conn.write(data)
+
+
+# Listen on tcp port 8000 on localhost using the python socket module.
+l = Listen(('127.0.0.1', 8000), "socktcp")
+try:
+ while True:
+ try:
+
+ # wait for new connections (it doesn't block other tasks)
+ conn, err = l.accept()
+
+ # Handle the connection in a new task.
+ # The loop then returns to accepting, so that
+ # multiple connections may be served concurrently.
+
+ t = tasklet(handle_connection)(conn)
+ except KeyboardInterrupt:
+ break
+finally:
+ l.close()
+
+run()
View
@@ -6,6 +6,7 @@
from flower.core import channel
from flower.core.uv import get_fd, uv_mode, uv_server
+from pyuv import errno
class IOChannel(channel):
""" channel to wait on IO events for a specific fd. It now use the UV server
@@ -25,12 +26,35 @@ def __init__(self, io, mode=0, label=''):
self._poller = pyuv.Poll(uv.loop, fno)
self._poller.start(uv_mode(mode), self._tick)
- def _tick(self, handle, events, errno):
- if errno:
- self.send_exception(IOError, errno)
+ def _tick(self, handle, events, error):
+ print("error")
+ if error:
+ if error == errno.EBADF:
@saghul
saghul Sep 11, 2012

pyuv errnos have UV_ prefix, that would be UV_EBADF

+ self.handle.close()
+ self.send(None)
+ else:
+ self.send_exception(IOError, "uv error: %s" % errno)
else:
self.send(events)
def stop(self):
self._poller.stop()
self.close()
+
+def wait_read(io):
+ """ wrapper around IOChannel to only wait when a device become
+ readable """
+ c = IOChannel(io)
+ try:
+ return c.receive()
+ finally:
+ c.close()
+
+def wait_write(io):
+ """ wrapper around IOChannel to only wait when a device become
+ writanle """
+ c = IOChannel(io, 1)
+ try:
+ return c.receive()
+ finally:
+ c.close()
@@ -6,11 +6,14 @@
from flower.net.tcp import TCPListen, dial_tcp
from flower.net.udp import UDPListen, dial_udp
from flower.net.pipe import PipeListen, dial_pipe
+from flower.net.sock import TCPSockListen, PipeSockListen
LISTEN_HANDLERS = dict(
tcp = TCPListen,
udp = UDPListen,
- pipe = PipeListen)
+ pipe = PipeListen,
+ socktcp = TCPSockListen,
+ sockpipe = PipeSockListen)
DIAL_HANDLERS = dict(
tcp = dial_tcp,
Oops, something went wrong. Retry.

0 comments on commit abeed04

Please sign in to comment.