Switch to threading model of socketserver

In an attempt to maybe get more information as to why the finger
daemon seems to be disappearing on us, try using threads instead
of forks. Alas, there is no spoon.

Change-Id: I473d874037fb81b940bfe71e5d6d1a17b131635f
diff --git a/tests/base.py b/tests/base.py
index 4de9134..176c535 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -2390,6 +2390,7 @@
                      'pydevd.CommandThread',
                      'pydevd.Reader',
                      'pydevd.Writer',
+                     'FingerStreamer',
                      ]
         threads = [t for t in threading.enumerate()
                    if t.name not in whitelist]
diff --git a/zuul/lib/log_streamer.py b/zuul/lib/log_streamer.py
index ce8537f..1906be7 100644
--- a/zuul/lib/log_streamer.py
+++ b/zuul/lib/log_streamer.py
@@ -182,7 +182,7 @@
                     return False
 
 
-class CustomForkingTCPServer(socketserver.ForkingTCPServer):
+class CustomThreadingTCPServer(socketserver.ThreadingTCPServer):
     '''
     Custom version that allows us to drop privileges after port binding.
     '''
@@ -193,7 +193,7 @@
         self.jobdir_root = kwargs.pop('jobdir_root')
         # For some reason, setting custom attributes does not work if we
         # call the base class __init__ first. Wha??
-        socketserver.ForkingTCPServer.__init__(self, *args, **kwargs)
+        socketserver.ThreadingTCPServer.__init__(self, *args, **kwargs)
 
     def change_privs(self):
         '''
@@ -209,7 +209,7 @@
 
     def server_bind(self):
         self.allow_reuse_address = True
-        socketserver.ForkingTCPServer.server_bind(self)
+        socketserver.ThreadingTCPServer.server_bind(self)
         if self.user:
             self.change_privs()
 
@@ -226,6 +226,16 @@
                 return
             raise
 
+    def process_request(self, request, client_address):
+        '''
+        Overridden from the base class to name the thread.
+        '''
+        t = threading.Thread(target=self.process_request_thread,
+                             name='FingerStreamer',
+                             args=(request, client_address))
+        t.daemon = self.daemon_threads
+        t.start()
+
 
 class LogStreamer(object):
     '''
@@ -235,10 +245,10 @@
     def __init__(self, user, host, port, jobdir_root):
         self.log = logging.getLogger('zuul.lib.LogStreamer')
         self.log.debug("LogStreamer starting on port %s", port)
-        self.server = CustomForkingTCPServer((host, port),
-                                             RequestHandler,
-                                             user=user,
-                                             jobdir_root=jobdir_root)
+        self.server = CustomThreadingTCPServer((host, port),
+                                               RequestHandler,
+                                               user=user,
+                                               jobdir_root=jobdir_root)
 
         # We start the actual serving within a thread so we can return to
         # the owner.