Recycling gunicorn worker (#800)

* add recycling feature to gunicorn worker

* add unit tests

* add more unit tests, and remove redundant trigger_events call

* fixed up unit tests

* make flake8 happy

* address feedbacks

* make flake8 happy

* add doc
This commit is contained in:
7
2017-06-22 13:26:50 -07:00
committed by Eli Uriegas
parent b5369e611c
commit f049a4ca67
4 changed files with 118 additions and 10 deletions

View File

@@ -75,7 +75,7 @@ class HttpProtocol(asyncio.Protocol):
signal=Signal(), connections=set(), request_timeout=60,
request_max_size=None, request_class=None, has_log=True,
keep_alive=True, is_request_stream=False, router=None,
**kwargs):
state=None, **kwargs):
self.loop = loop
self.transport = None
self.request = None
@@ -99,6 +99,9 @@ class HttpProtocol(asyncio.Protocol):
self._request_handler_task = None
self._request_stream_task = None
self._keep_alive = keep_alive
self.state = state if state else {}
if 'requests_count' not in self.state:
self.state['requests_count'] = 0
@property
def keep_alive(self):
@@ -154,6 +157,9 @@ class HttpProtocol(asyncio.Protocol):
self.headers = []
self.parser = HttpRequestParser(self)
# requests count
self.state['requests_count'] = self.state['requests_count'] + 1
# Parse request chunk or close connection
try:
self.parser.feed_data(data)
@@ -389,7 +395,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
register_sys_signals=True, run_async=False, connections=None,
signal=Signal(), request_class=None, has_log=True, keep_alive=True,
is_request_stream=False, router=None, websocket_max_size=None,
websocket_max_queue=None):
websocket_max_queue=None, state=None):
"""Start asynchronous HTTP Server on an individual process.
:param host: Address to host on
@@ -427,8 +433,6 @@ def serve(host, port, request_handler, error_handler, before_start=None,
if debug:
loop.set_debug(debug)
trigger_events(before_start, loop)
connections = connections if connections is not None else set()
server = partial(
protocol,
@@ -445,7 +449,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
is_request_stream=is_request_stream,
router=router,
websocket_max_size=websocket_max_size,
websocket_max_queue=websocket_max_queue
websocket_max_queue=websocket_max_queue,
state=state
)
server_coroutine = loop.create_server(
@@ -457,6 +462,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
sock=sock,
backlog=backlog
)
# Instead of pulling time at the end of every request,
# pull it once per minute
loop.call_soon(partial(update_current_time, loop))
@@ -464,6 +470,8 @@ def serve(host, port, request_handler, error_handler, before_start=None,
if run_async:
return server_coroutine
trigger_events(before_start, loop)
try:
http_server = loop.run_until_complete(server_coroutine)
except: