Browse Source

suggested documentation, clarifying the purpose of the mixin class and restrictions. it includes a suggested alternative of the class name.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac352@3324 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 14 years ago
parent
commit
4eefe424dd
1 changed files with 40 additions and 16 deletions
  1. 40 16
      src/lib/python/isc/utils/serve_mixin.py

+ 40 - 16
src/lib/python/isc/utils/serve_mixin.py

@@ -19,27 +19,51 @@ import select
 
 
 SOCK_DATA = b'somedata'
 SOCK_DATA = b'somedata'
 class ServeMixIn:
 class ServeMixIn:
-    '''Mix-In class to override the function serve_forever()
-    and shutdown() in class socketserver::TCPServer.
-      serve_forever() in socketserver.TCPServer use polling
-    for checking request, which reduces the responsiveness to
-    the shutdown request and wastes cpu at all other times.
-      ServeMixIn should be used together with socketserver.TCPServer
-    or some derived classes of it, and ServeMixIn must be the first
-    base class in multiple inheritance, eg. MyClass(ServeMixIn,
-    socketserver.TCPServer). ServeMixIn.__init__() should be called
-    explicitely in derived class.
+    '''This is a mix-in class to override the function serve_forever()
+    and shutdown() in class socketserver.BaseServer.
+
+    As commented in the module source code,  serve_forever() in
+    socketserver.BaseServer uses polling for a shutdown request, which
+    "reduces the responsiveness to a shutdown request and wastes cpu at
+    all other times."
+
+    This class fixes this problem by introducing internal message
+    passing via a separate socket. Note, however, that according to
+    the module documentation serve_forever() and shutdown() are not
+    categorized as functions that can be overridden via mix-ins.  So
+    this mix-in class may not be compatible with future versions of
+    socketserver.  It should be considered a short term workaround
+    until the original implementation is fixed.
+
+    The NoPollMixIn class should be used together with
+    socketserver.BaseServer or some derived classes of it, and it must
+    be placed before the corresponding socketserver class.  In
+    addition, the constructor of this mix-in must be called
+    explicitely in the derived class.  For example, a basic TCP server
+    without the problem of polling is created as follows:
+
+       class MyServer(NoPollMixIn, socketserver.TCPServer):
+           def __init__(...):
+               ...
+               NoPollMixIn.__init__(self)
+               ...
+
+    To shutdown the server correctly, the serve_forever() method must
+    be run in a separate thread, and shutdown() must be called from
+    some other thread.
     '''
     '''
     def __init__(self):
     def __init__(self):
         self.__read_sock, self.__write_sock = socket.socketpair()
         self.__read_sock, self.__write_sock = socket.socketpair()
         self.__is_shut_down = threading.Event()
         self.__is_shut_down = threading.Event()
 
 
     def serve_forever(self, poll_interval=None):
     def serve_forever(self, poll_interval=None):
-        ''' Override the serve_forever([poll_interval]) in class
-        socketserver.TCPServer. use the socketpair to wake up
-        the select when shutdown() is called in anther thread.
-          Note, parameter 'poll_interval' is just used to keep the
-        interface, it's never used in this function.
+        ''' Overrides the serve_forever([poll_interval]) in class
+        socketserver.BaseServer.
+
+        It uses a socketpair to wake up the select when shutdown() is
+        called in anther thread.  Note, parameter 'poll_interval' is
+        just used for interface compatibility; it's never used in this
+        function.
         '''        
         '''        
         while True:
         while True:
             # block until the self.socket or self.__read_sock is readable
             # block until the self.socket or self.__read_sock is readable
@@ -61,9 +85,9 @@ class ServeMixIn:
 
 
     def shutdown(self):
     def shutdown(self):
         '''Stops the serve_forever loop.
         '''Stops the serve_forever loop.
+
         Blocks until the loop has finished, the function should be called
         Blocks until the loop has finished, the function should be called
         in another thread when serve_forever is running, or it will block.
         in another thread when serve_forever is running, or it will block.
         '''
         '''
         self.__write_sock.send(SOCK_DATA) # make self.__read_sock readable.
         self.__write_sock.send(SOCK_DATA) # make self.__read_sock readable.
         self.__is_shut_down.wait()  # wait until the serve thread terminate
         self.__is_shut_down.wait()  # wait until the serve thread terminate
-