Rev 6185: Implement basic testing that the smart server tracks client connections, in http://bazaar.launchpad.net/~jameinel/bzr/2.5-soft-hangup-795025

John Arbash Meinel john at arbash-meinel.com
Fri Sep 23 14:27:58 UTC 2011


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

------------------------------------------------------------
revno: 6185
revision-id: john at arbash-meinel.com-20110923142749-jd2ketuz1u4vihfx
parent: john at arbash-meinel.com-20110923130112-do88k6x35e2vtj2t
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.5-soft-hangup-795025
timestamp: Fri 2011-09-23 16:27:49 +0200
message:
  Implement basic testing that the smart server tracks client connections,
  and cleans out the queue on shutdown.
  Now we need a test that it prunes out inactive connections at runtime, so that
  the list of active connections doesn't grow without bound.
  Then we need to figure out how graceful shutdown should work, specifically,
  how long do we wait for client threads to timeout.
  My initial thought is that if this is a graceful shutdown, we should probably
  wait forever, and people who want something faster can give a stronger signal
  than SIGHUP.
-------------- next part --------------
=== modified file 'bzrlib/smart/server.py'
--- a/bzrlib/smart/server.py	2011-09-23 12:57:40 +0000
+++ b/bzrlib/smart/server.py	2011-09-23 14:27:49 +0000
@@ -191,6 +191,8 @@
                         if self._should_terminate:
                             break
                         self.serve_conn(conn, thread_name_suffix)
+                    # Cleanout any threads that have finished processing.
+                    # self._poll_active_connections()
             except KeyboardInterrupt:
                 # dont log when CTRL-C'd.
                 raise
@@ -206,6 +208,7 @@
             except self._socket_error:
                 # ignore errors on close
                 pass
+            self._poll_active_connections()
             self.run_server_stopped_hooks()
 
     def get_url(self):

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2011-09-23 13:01:12 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2011-09-23 14:27:49 +0000
@@ -1119,6 +1119,47 @@
         server._poll_active_connections(0.1)
         self.assertEqual(0, len(server._active_connections))
 
+    def test_serve_closes_out_finished_connections(self):
+        t = _mod_transport.get_transport_from_url('memory:///')
+        server = _mod_server.SmartTCPServer(t, client_timeout=1.0)
+        server._ACCEPT_TIMEOUT = 0.1
+        # We don't use 'localhost' because that might be an IPv6 address.
+        server.start_server('127.0.0.1', 0)
+        server_thread = threading.Thread(target=server.serve,
+                                         args=(self.id(),))
+        server_thread.start()
+        client_sock = None
+        try:
+            # Wait for the server to start. Then connect to the port
+            client_sock = socket.socket()
+            server._started.wait()
+            client_sock.connect(('127.0.0.1', server.port))
+            # We send and receive on the connection, so that we know the
+            # server-side has seen the connect, and started handling the
+            # results.
+            client_sock.send('hello\n')
+            self.assertEqual('ok\x012\n', client_sock.recv(5))
+            self.assertEqual(1, len(server._active_connections))
+            # Grab a handle to the thread that is processing our request
+            server_side_thread = server._active_connections[0][2]
+        finally:
+            # Close the connection, ask the server to stop, and wait for the
+            # server to stop, as well as the thread that was servicing the
+            # client request.
+            if client_sock is not None:
+                client_sock.close()
+            # Wait for the server-side request thread to notice we are closed.
+            server_side_thread.join()
+            # Stop the server, it should notice the connection has finished.
+            server._stop_gracefully()
+            # Do a throw-away connection so that the server stops immediately
+            s = socket.socket()
+            s.connect(('127.0.0.1', server.port))
+            s.close()
+            server._stopped.wait()
+            server_thread.join()
+        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