Skip to content

Commit a72385c

Browse files
committed
♲ Move the request processing loop to own method
This helps clarify the abstraction layers, reducing the complexity of individual methods, making it easier to reason about what's going on there.
1 parent e1f37a8 commit a72385c

1 file changed

Lines changed: 41 additions & 27 deletions

File tree

cheroot/workers/threadpool.py

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -99,42 +99,56 @@ def __init__(self, server):
9999
threading.Thread.__init__(self)
100100

101101
def run(self):
102-
"""Process incoming HTTP connections.
102+
"""Set up incoming HTTP connection processing loop.
103103
104-
Retrieves incoming connections from thread pool.
104+
This is the thread's entry-point. It performs lop-layer
105+
exception handling and interrupt processing.
106+
:exc:`KeyboardInterrupt` and :exc:`SystemExit` bubbling up
107+
from the inner-layer code constitute a global server interrupt
108+
request. When they happen, the worker thread exits.
109+
110+
# noqa: DAR401 KeyboardInterrupt SystemExit
105111
"""
106112
self.server.stats['Worker Threads'][self.name] = self.stats
113+
self.ready = True
107114
try:
108-
self.ready = True
109-
while True:
110-
conn = self.server.requests.get()
111-
if conn is _SHUTDOWNREQUEST:
112-
return
113-
114-
self.conn = conn
115-
is_stats_enabled = self.server.stats['Enabled']
116-
if is_stats_enabled:
117-
self.start_time = time.time()
118-
keep_conn_open = False
119-
try:
120-
keep_conn_open = conn.communicate()
121-
finally:
122-
if keep_conn_open:
123-
self.server.put_conn(conn)
124-
else:
125-
conn.close()
126-
if is_stats_enabled:
127-
self.requests_seen += self.conn.requests_seen
128-
self.bytes_read += self.conn.rfile.bytes_read
129-
self.bytes_written += self.conn.wfile.bytes_written
130-
self.work_time += time.time() - self.start_time
131-
self.start_time = None
132-
self.conn = None
115+
self._process_connections_until_interrupted()
133116
except (KeyboardInterrupt, SystemExit) as ex:
134117
self.server.interrupt = ex
135118
finally:
136119
self.ready = False
137120

121+
def _process_connections_until_interrupted(self):
122+
"""Process incoming HTTP connections in an infinite loop.
123+
124+
Retrieves incoming connections from thread pool, processing
125+
them one by one.
126+
"""
127+
while True:
128+
conn = self.server.requests.get()
129+
if conn is _SHUTDOWNREQUEST:
130+
return
131+
132+
self.conn = conn
133+
is_stats_enabled = self.server.stats['Enabled']
134+
if is_stats_enabled:
135+
self.start_time = time.time()
136+
keep_conn_open = False
137+
try:
138+
keep_conn_open = conn.communicate()
139+
finally:
140+
if keep_conn_open:
141+
self.server.put_conn(conn)
142+
else:
143+
conn.close()
144+
if is_stats_enabled:
145+
self.requests_seen += self.conn.requests_seen
146+
self.bytes_read += self.conn.rfile.bytes_read
147+
self.bytes_written += self.conn.wfile.bytes_written
148+
self.work_time += time.time() - self.start_time
149+
self.start_time = None
150+
self.conn = None
151+
138152

139153
class ThreadPool:
140154
"""A Request Queue for an HTTPServer which pools threads.

0 commit comments

Comments
 (0)