From: Skip Montanaro Date: Thu, 12 May 2005 13:43:40 +0000 (+0000) Subject: backport from head X-Git-Tag: v2.4.2c1~224 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c3dd49ce1ad4437b62e0a9107537217b3d1c37a0;p=thirdparty%2FPython%2Fcpython.git backport from head --- diff --git a/Doc/lib/libsocksvr.tex b/Doc/lib/libsocksvr.tex index 1583385b1226..b0cc4164ea62 100644 --- a/Doc/lib/libsocksvr.tex +++ b/Doc/lib/libsocksvr.tex @@ -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