diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 6e1ae9f..0b8fa34 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -59,10 +59,31 @@ The Mix-in class must come first, since it overrides a method defined in 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 -BaseRequestHandler and redefine its handle() method. You can then run -various versions of the service by combining one of the server classes -with your request handler class. +To implement a service, you must create a function that instantiates +and starts a new request handler. The BaseRequestHandler class is +offered as the simplest option: you must derive a class from it and +redefine its handle() method. Then, you must assign this function or +class to the RequestHandlerClass parameter of the server constructor. +This function or the class constructor must accept three arguments: +request, client_address and server. You can then run various versions +of the service by combining one of the server classes with your +factory function or handler class. + +The parameter name 'RequestHandlerClass' in the server constructor is +an historical misnomer. The factory function does not have to be a class. + +Your request handler might need extra arguments, say a database +connection, in addition to the arguments that are accepted by the +factory function. One way to address this issue is to create +another factory function with the extra parameters and create a +closure over it as follows: + + def doclosure(fct, dbconn): + def closure(request, client_address, server): + return fct(request, client_address, server, dbconn) + return closure + + factoryfunction = doclosure(yourfactoryfunction, dbconn) The request handler class must be different for datagram or stream services. This can be hidden by using the request handler @@ -193,7 +214,7 @@ class BaseServer: Instance variables: - - RequestHandlerClass + - RequestHandlerClass # historical misnomer; you can assign a factory function. - socket """ @@ -267,8 +288,8 @@ class BaseServer: # - get_request() is different for stream or datagram sockets # - process_request() is the place that may fork a new process or create a # new thread to finish the request - # - finish_request() instantiates the request handler class; this - # constructor will handle the request all by itself + # - finish_request() calls the factory function, which instantiates and + # starts the handler; this handler will handle the request all by itself. def handle_request(self): """Handle one request, possibly blocking. @@ -672,7 +693,8 @@ class BaseRequestHandler: """Base class for request handler classes. - This class is instantiated for each request to be handled. The + If assigned to the RequestHandlerClass parameter of the server, + this class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which