Created
February 18, 2010 20:42
-
-
Save temoto/308038 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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