Rev 6183: Track the active connections, add a polling function to notice when they are stopped. in http://bazaar.launchpad.net/~jameinel/bzr/2.5-soft-hangup-795025

John Arbash Meinel john at arbash-meinel.com
Fri Sep 23 12:57:49 UTC 2011


At http://bazaar.launchpad.net/~jameinel/bzr/2.5-soft-hangup-795025

------------------------------------------------------------
revno: 6183
revision-id: john at arbash-meinel.com-20110923125740-bistyq17nlwp53gw
parent: john at arbash-meinel.com-20110923124214-8mwfb09hs208qrr4
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.5-soft-hangup-795025
timestamp: Fri 2011-09-23 14:57:40 +0200
message:
  Track the active connections, add a polling function to notice when they are stopped.
-------------- next part --------------
=== modified file 'bzrlib/smart/server.py'
--- a/bzrlib/smart/server.py	2011-09-22 15:18:52 +0000
+++ b/bzrlib/smart/server.py	2011-09-23 12:57:40 +0000
@@ -75,6 +75,7 @@
         self.backing_transport = backing_transport
         self.root_client_path = root_client_path
         self._client_timeout = client_timeout
+        self._active_connections = []
 
     def start_server(self, host, port):
         """Create the server listening socket.
@@ -216,6 +217,23 @@
             conn, self.backing_transport, self.root_client_path,
             timeout=self._client_timeout)
 
+    def _poll_active_connections(self, timeout=0.0):
+        """Check to see if any active connections have finished.
+
+        This will iterate through self._active_connections, and update any
+        connections that are finished.
+
+        :param timeout: The timeout to pass to thread.join(). By default, we
+            set it to 0, so that we don't hang if threads are not done yet.
+        :return: None
+        """
+        still_active = []
+        for conn, handler, thread in self._active_connections:
+            thread.join(timeout)
+            if thread.isAlive():
+                still_active.append((conn, handler, thread))
+        self._active_connections = still_active
+
     def serve_conn(self, conn, thread_name_suffix):
         # For WIN32, where the timeout value from the listening socket
         # propagates to the newly accepted socket.
@@ -230,6 +248,7 @@
         # rid of them -- vila 20100531
         connection_thread.setDaemon(True)
         connection_thread.start()
+        self._active_connections.append((conn, handler, connection_thread))
         return connection_thread
 
     def start_background_thread(self, thread_name_suffix=''):

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2011-09-23 12:42:14 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2011-09-23 12:57:40 +0000
@@ -1104,6 +1104,21 @@
         handler = server._make_handler(server_socket)
         self.assertEqual(1.23, handler._client_timeout)
 
+    def test_serve_conn_tracks_connections(self):
+        server = _mod_server.SmartTCPServer(None, client_timeout=4.0)
+        server_sock, client_sock = portable_socket_pair()
+        server.serve_conn(server_sock, '-%s' % (self.id(),))
+        self.assertEqual(1, len(server._active_connections))
+        # We still want to talk on the connection. Polling should indicate it
+        # is still active.
+        server._poll_active_connections()
+        self.assertEqual(1, len(server._active_connections))
+        # Closing the socket will end the active thread, and polling will
+        # notice and remove it from the active set.
+        client_sock.close()
+        server._poll_active_connections(0.1)
+        self.assertEqual(0, len(server._active_connections))
+
 
 class SmartTCPTests(tests.TestCase):
     """Tests for connection/end to end behaviour using the TCP server.



More information about the bazaar-commits mailing list