]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
backport from head
authorSkip Montanaro <skip@pobox.com>
Thu, 12 May 2005 13:43:40 +0000 (13:43 +0000)
committerSkip Montanaro <skip@pobox.com>
Thu, 12 May 2005 13:43:40 +0000 (13:43 +0000)
Doc/lib/libsocksvr.tex

index 1583385b1226303a81fa5eb3f72dc86fe17e72d0..b0cc4164ea62dc31408a6213b6933e4c494294c2 100644 (file)
@@ -52,10 +52,87 @@ matter what network protocol they use:
 
 \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 @@ and \class{ThreadingMixIn} classes do this.
 % 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 @@ This function can be overridden to implement access controls for a server.
 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 @@ function will not be called.
 
 \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