Commit b7f04707 authored by Andrey Veltischev's avatar Andrey Veltischev
Browse files

Gracefully stop loop and shutdown applications

parent 489dbb82
......@@ -4,7 +4,7 @@ from aiohttp import web
import prometheus_client
import logging
LOG = logging.getLogger('mertics')
LOG = logging.getLogger('application_wrapper')
def init_mertics_app():
......@@ -33,26 +33,32 @@ class AioAppWrapper:
self.runner = web.AppRunner(self.app)
self.loop.run_until_complete(self.runner.setup())
site = web.TCPSite(self.runner, '0.0.0.0', self.port)
self.loop.run_until_complete(site.start())
return site.start()
def shutdown(self):
self.loop.run_until_complete(self.runner.shutdown())
self.loop.run_until_complete(self.runner.cleanup())
LOG.info('Shutdown aiohttp app')
self.loop.create_task(self.runner.cleanup())
class CoroutineWrapper:
def __init__(self, _coro, _loop):
def __init__(self, _coro, _loop, _stop_callback):
self.coro = _coro
self.loop = _loop
self.stop_call_back = _stop_callback
self.task = None
def initialize(self):
LOG.info('Initialize coroutine')
self.task = self.loop.create_task(self.coro)
return self.task
def shutdown(self):
self.task.cancel()
LOG.info('Shutting down coroutine')
if self.stop_call_back is not None:
self.stop_call_back()
else:
self.task.cancel()
class ApplicationWrapper:
......@@ -72,22 +78,24 @@ class ApplicationWrapper:
AioAppWrapper(_app, _port, self.loop)
)
def add_coroutine(self, _coro):
def add_coroutine(self, _coro, _stop_callback=None):
self.apps.append(
CoroutineWrapper(_coro, self.loop)
CoroutineWrapper(_coro, self.loop, _stop_callback)
)
def handle_signal(self, _signal_name, callback):
self.loop.add_signal_handler(_signal_name, callback)
def run_all(self):
try:
for app in self.apps:
app.initialize()
try:
LOG.info('Start serving')
self.loop.run_forever()
except KeyboardInterrupt: # pragma: no cover
pass
finally:
for app in self.apps:
app.shutdown()
LOG.info('Start serving')
exceptions = self.loop.run_until_complete(
asyncio.gather(*[app.initialize() for app in self.apps], return_exceptions=True)
)
for exception in filter(lambda ex: isinstance(ex, Exception), exceptions):
LOG.error('Unexpected exception', exc_info=exception)
except KeyboardInterrupt:
pass
finally:
self.loop.close()
for app in self.apps:
app.shutdown()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment