From c94eaabb400f885a93aa9bf79a7153a6d8581d41 Mon Sep 17 00:00:00 2001 From: Liam Staskawicz Date: Tue, 18 Aug 2020 09:40:27 -0700 Subject: [PATCH] server: make connections 'private' --- cheroot/connections.py | 4 ++-- cheroot/server.py | 27 +++++++++++++++++++-------- cheroot/workers/threadpool.py | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/cheroot/connections.py b/cheroot/connections.py index 359cba1850..b230307cb2 100644 --- a/cheroot/connections.py +++ b/cheroot/connections.py @@ -276,8 +276,8 @@ def close(self): self._selector.close() @property - def _num_connections(self): # noqa: D401 - """The current number of connections. + def _num_connections(self): + """Return the current number of connections. Includes any in the readable list or registered with the selector, minus one for the server socket, which is always registered diff --git a/cheroot/server.py b/cheroot/server.py index 42decc2a7c..5405b2c746 100644 --- a/cheroot/server.py +++ b/cheroot/server.py @@ -1162,10 +1162,7 @@ def send_headers(self): # noqa: C901 # FIXME # Override the decision to not close the connection if the connection # manager doesn't have space for it. if not self.close_connection: - can_keep = ( - self.server.ready - and self.server.connections.can_add_keepalive_connection - ) + can_keep = self.server.can_add_keepalive_connection self.close_connection = not can_keep if b'connection' not in hkeys: @@ -1784,7 +1781,8 @@ def prepare(self): # noqa: C901 # FIXME self.socket.settimeout(1) self.socket.listen(self.request_queue_size) - self.connections = connections.ConnectionManager(self) + # must not be accessed once stop() has been called + self._connections = connections.ConnectionManager(self) # Create worker threads self.requests.start() @@ -1832,6 +1830,19 @@ def _run_in_thread(self): finally: self.stop() + @property + def can_add_keepalive_connection(self): + """Flag whether it is allowed to add a new keep-alive connection.""" + return self.ready and self._connections.can_add_keepalive_connection + + def put_conn(self, conn): + """Put an idle connection back into the ConnectionManager.""" + if self.ready: + self._connections.put(conn) + else: + # server is shutting down, just close it + conn.close() + def error_log(self, msg='', level=20, traceback=False): """Write error message to log. @@ -2024,7 +2035,7 @@ def resolve_real_bind_addr(socket_): def tick(self): """Accept a new connection and put it on the Queue.""" - conn = self.connections.get_conn() + conn = self._connections.get_conn() if conn: try: self.requests.put(conn) @@ -2032,7 +2043,7 @@ def tick(self): # Just drop the conn. TODO: write 503 back? conn.close() - self.connections.expire() + self._connections.expire() @property def interrupt(self): @@ -2100,7 +2111,7 @@ def stop(self): # noqa: C901 # FIXME sock.close() self.socket = None - self.connections.close() + self._connections.close() self.requests.stop(self.shutdown_timeout) diff --git a/cheroot/workers/threadpool.py b/cheroot/workers/threadpool.py index b9987d9de3..6e6c721d90 100644 --- a/cheroot/workers/threadpool.py +++ b/cheroot/workers/threadpool.py @@ -120,7 +120,7 @@ def run(self): keep_conn_open = conn.communicate() finally: if keep_conn_open: - self.server.connections.put(conn) + self.server.put_conn(conn) else: conn.close() if is_stats_enabled: