[Python-checkins] python/dist/src/Doc/lib libsocksvr.tex, 1.18, 1.19

montanaro@users.sourceforge.net montanaro at users.sourceforge.net
Thu May 12 15:42:45 CEST 2005

Update of /cvsroot/python/python/dist/src/Doc/lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1244

Modified Files:
libsocksvr.tex
Log Message:
Incorporate a lightly edited version of the SocketServer module's docstring
into the docs and segregate the method descriptions for the various classes
into separate sections.  Base on suggestion by Paul Rubin in c.l.py.

Index: libsocksvr.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocksvr.tex,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- libsocksvr.tex	21 Jul 2004 02:47:10 -0000	1.18
+++ libsocksvr.tex	12 May 2005 13:42:42 -0000	1.19
@@ -52,10 +52,87 @@

\setindexsubitem{(SocketServer protocol)}

+\subsection{Server Creation Notes}
+
+There are five classes in an inheritance diagram, four of which represent
+synchronous servers of four types:
+
+\begin{verbatim}
+        +------------+
+        | BaseServer |
+        +------------+
+              |
+              v
+        +-----------+        +------------------+
+        | TCPServer |------->| UnixStreamServer |
+        +-----------+        +------------------+
+              |
+              v
+        +-----------+        +--------------------+
+        | UDPServer |------->| UnixDatagramServer |
+        +-----------+        +--------------------+
+\end{verbatim}
+
+Note that \class{UnixDatagramServer} derives from \class{UDPServer}, not
+from \class{UnixStreamServer} -- the only difference between an IP and a
+Unix stream server is the address family, which is simply repeated in both
+unix server classes.
+
+Forking and threading versions of each type of server can be created using
+the \class{ForkingMixIn} and \class{ThreadingMixIn} mix-in classes.  For
+instance, a threading UDP server class is created as follows:
+
+\begin{verbatim}
+\end{verbatim}
+
+The mix-in class must come first, since it overrides a method defined in
+\class{UDPServer}.  Setting the various member variables also changes the
+behavior of the underlying server mechanism.
+
+To implement a service, you must derive a class from
+\class{BaseRequestHandler} and redefine its \method{handle()} method.  You
+can then run various versions of the service by combining one of the server
+classes with your request handler class.  The request handler class must be
+different for datagram or stream services.  This can be hidden by using the
+mix-in request handler classes \class{StreamRequestHandler} or
+\class{DatagramRequestHandler}.
+
+Of course, you still have to use your head!  For instance, it makes no sense
+to use a forking server if the service contains state in memory that can be
+modified by different requests, since the modifications in the child process
+would never reach the initial state kept in the parent process and passed to
+each child.  In this case, you can use a threading server, but you will
+probably have to use locks to protect the integrity of the shared data.
+
+On the other hand, if you are building an HTTP server where all data is
+stored externally (for instance, in the file system), a synchronous class
+will essentially render the service "deaf" while one request is being
+handled -- which may be for a very long time if a client is slow to receive
+all the data it has requested.  Here a threading or forking server is
+appropriate.
+
+In some cases, it may be appropriate to process part of a request
+synchronously, but to finish processing in a forked child depending on the
+request data.  This can be implemented by using a synchronous server and
+doing an explicit fork in the request handler class \method{handle()}
+method.
+
+Another approach to handling multiple simultaneous requests in an
+environment that supports neither threads nor \function{fork()} (or where
+these are too expensive or inappropriate for the service) is to maintain an
+explicit table of partially finished requests and to use \function{select()}
+to decide which request to work on next (or whether to handle a new incoming
+request).  This is particularly important for stream services where each
+client can potentially be connected for a long time (if threads or
+subprocesses cannot be used).
+
%XXX should data and methods be intermingled, or separate?
% how should the distinction between class and instance variables be
% drawn?

+\subsection{Server Objects}
+
\begin{funcdesc}{fileno}{}
Return an integer file descriptor for the socket on which the server
is listening.  This function is most commonly passed to
@@ -160,7 +237,8 @@
% instance variables, adding new network families?

\begin{funcdesc}{server_activate}{}
-Called by the server's constructor to activate the server.
+Called by the server's constructor to activate the server.  The default
+behavior just \method{listen}s to the server's socket.
May be overridden.
\end{funcdesc}

@@ -176,6 +254,8 @@
The default implementation always returns \constant{True}.
\end{funcdesc}

+\subsection{RequestHandler Objects}
+
The request handler class must define a new \method{handle()} method,
and can override any of the following methods.  A new instance is
created for each request.
@@ -189,6 +269,7 @@

\begin{funcdesc}{handle}{}
This function must do all the work required to service a request.
+The default implementation does nothing.
Several instance attributes are available to it; the request is
available as \member{self.request}; the client address as
\member{self.client_address}; and the server instance as