[Python-checkins] python/dist/src/Doc/lib libsocksvr.tex, 1.18, 1.18.4.1
montanaro@users.sourceforge.net
montanaro at users.sourceforge.net
Thu May 12 15:43:42 CEST 2005
Update of /cvsroot/python/python/dist/src/Doc/lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1594
Modified Files:
Tag: release24-maint
libsocksvr.tex
Log Message:
backport from head
Index: libsocksvr.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocksvr.tex,v
retrieving revision 1.18
retrieving revision 1.18.4.1
diff -u -d -r1.18 -r1.18.4.1
--- libsocksvr.tex 21 Jul 2004 02:47:10 -0000 1.18
+++ libsocksvr.tex 12 May 2005 13:43:40 -0000 1.18.4.1
@@ -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}
+ class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
+\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
More information about the Python-checkins
mailing list