Skip to content

Instantly share code, notes, and snippets.

@temoto
Created February 18, 2010 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save temoto/308038 to your computer and use it in GitHub Desktop.
Save temoto/308038 to your computer and use it in GitHub Desktop.
def connect(addr, family=socket.AF_INET, bind=None):
"""Convenience function for opening client sockets.
:param addr: Address of the server to connect to. For TCP sockets,
this is a (host, port) tuple.
:param family: Socket family, optional. See :mod:`socket`
documentation for available families.
:param bind: Local address to bind to, optional.
"""
sock = green_socket.socket(family)
if bind is not None:
sock.bind(bind)
sock.connect(addr)
return sock
def listen(addr, family=socket.AF_INET, backlog=50):
"""Convenience function for opening server sockets.
Sets SO_REUSEADDR on the socket.
:param addr: Address to listen on. For TCP sockets, this is a
(host, port) tuple.
:param family: Socket family, optional. See :mod:`socket`
documentation for available families.
:param backlog: The maximum number of queued connections. Should be
at least 1; the maximum value is system-dependent.
"""
sock = green_socket.socket(family)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(backlog)
return sock
class StopServer(Exception): pass
def serve(sock, handle, concurrency=1000):
"""Runs a server listening on a socket. Calls the function
*handle* in a separate greenthread for every incoming request.
This function is blocking; it won't return until the server is
finished serving.
The *handle* function must raise an EndServerException to
gracefully terminate the server -- that's the only way to get the
server() function to return. Any other uncaught exceptions raised
in *handle* are raised as exceptions from :func:`serve`, so be
sure to do a good job catching exceptions that your application
raises. The return value of *handle* is ignored.
The value in *concurrency* controls the maximum number of
greenthreads that will be open at any time handling requests. When
the server hits the concurrency limit, it stops accepting new
connections until the existing ones complete.
"""
pool = greenpool.GreenPool(concurrency)
server_thread = greenthread.getcurrent()
def stop_checker(t):
try:
t.wait()
except StopServer:
server_thread.throw(StopServer)
while True:
try:
conn, addr = sock.accept()
pool.spawn(handle, conn, addr).link(stop_checker)
except StopServer:
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment