Refactor asyncio monitoring daemon example application

This commit is contained in:
Roman Mogylatov 2020-10-08 15:43:53 -04:00
parent 71eab0b756
commit 7ec2afe17f
6 changed files with 27 additions and 25 deletions

View File

@ -1,8 +1,10 @@
Asyncio Daemon Dependency Injection Example Asyncio Daemon + Dependency Injector Example
=========================================== ============================================
Application ``monitoringdaemon`` is an `asyncio <https://docs.python.org/3/library/asyncio.html>`_ This is an `asyncio <https://docs.python.org/3/library/asyncio.html>`_ +
+ `Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ application. `Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
The example application is a daemon that monitors availability of web services.
Run Run
--- ---
@ -31,19 +33,16 @@ The output should be something like:
monitor_1 | response code: 200 monitor_1 | response code: 200
monitor_1 | content length: 648 monitor_1 | content length: 648
monitor_1 | request took: 0.074 seconds monitor_1 | request took: 0.074 seconds
monitor_1 |
monitor_1 | [2020-08-08 17:04:36,811] [INFO] [HttpMonitor]: Check monitor_1 | [2020-08-08 17:04:36,811] [INFO] [HttpMonitor]: Check
monitor_1 | GET https://httpbin.org/get monitor_1 | GET https://httpbin.org/get
monitor_1 | response code: 200 monitor_1 | response code: 200
monitor_1 | content length: 310 monitor_1 | content length: 310
monitor_1 | request took: 0.153 seconds monitor_1 | request took: 0.153 seconds
monitor_1 |
monitor_1 | [2020-08-08 17:04:41,731] [INFO] [HttpMonitor]: Check monitor_1 | [2020-08-08 17:04:41,731] [INFO] [HttpMonitor]: Check
monitor_1 | GET http://example.com monitor_1 | GET http://example.com
monitor_1 | response code: 200 monitor_1 | response code: 200
monitor_1 | content length: 648 monitor_1 | content length: 648
monitor_1 | request took: 0.067 seconds monitor_1 | request took: 0.067 seconds
monitor_1 |
monitor_1 | [2020-08-08 17:04:41,787] [INFO] [HttpMonitor]: Check monitor_1 | [2020-08-08 17:04:41,787] [INFO] [HttpMonitor]: Check
monitor_1 | GET https://httpbin.org/get monitor_1 | GET https://httpbin.org/get
monitor_1 | response code: 200 monitor_1 | response code: 200
@ -77,11 +76,11 @@ The output should be something like:
Name Stmts Miss Cover Name Stmts Miss Cover
---------------------------------------------------- ----------------------------------------------------
monitoringdaemon/__init__.py 0 0 100% monitoringdaemon/__init__.py 0 0 100%
monitoringdaemon/__main__.py 9 9 0% monitoringdaemon/__main__.py 12 12 0%
monitoringdaemon/containers.py 11 0 100% monitoringdaemon/containers.py 11 0 100%
monitoringdaemon/dispatcher.py 43 5 88% monitoringdaemon/dispatcher.py 44 5 89%
monitoringdaemon/http.py 6 3 50% monitoringdaemon/http.py 6 3 50%
monitoringdaemon/monitors.py 23 1 96% monitoringdaemon/monitors.py 23 1 96%
monitoringdaemon/tests.py 37 0 100% monitoringdaemon/tests.py 37 0 100%
---------------------------------------------------- ----------------------------------------------------
TOTAL 129 18 86% TOTAL 133 21 84%

View File

@ -1,18 +1,21 @@
"""Main module.""" """Main module."""
from .containers import ApplicationContainer import sys
from dependency_injector.wiring import Provide
from .dispatcher import Dispatcher
from .containers import Container
def main() -> None: def main(dispatcher: Dispatcher = Provide[Container.dispatcher]) -> None:
"""Run the application."""
container = ApplicationContainer()
container.config.from_yaml('config.yml')
container.configure_logging()
dispatcher = container.dispatcher()
dispatcher.run() dispatcher.run()
if __name__ == '__main__': if __name__ == '__main__':
container = Container()
container.config.from_yaml('config.yml')
container.configure_logging()
container.wire(modules=[sys.modules[__name__]])
main() main()

View File

@ -1,4 +1,4 @@
"""Application containers module.""" """Containers module."""
import logging import logging
import sys import sys
@ -8,8 +8,7 @@ from dependency_injector import containers, providers
from . import http, monitors, dispatcher from . import http, monitors, dispatcher
class ApplicationContainer(containers.DeclarativeContainer): class Container(containers.DeclarativeContainer):
"""Application container."""
config = providers.Configuration() config = providers.Configuration()

View File

@ -44,6 +44,7 @@ class Dispatcher:
self._logger.info('Shutting down') self._logger.info('Shutting down')
for task, monitor in zip(self._monitor_tasks, self._monitors): for task, monitor in zip(self._monitor_tasks, self._monitors):
task.cancel() task.cancel()
self._monitor_tasks.clear()
self._logger.info('Shutdown finished successfully') self._logger.info('Shutdown finished successfully')
@staticmethod @staticmethod

View File

@ -47,7 +47,7 @@ class HttpMonitor(Monitor):
' %s %s\n' ' %s %s\n'
' response code: %s\n' ' response code: %s\n'
' content length: %s\n' ' content length: %s\n'
' request took: %s seconds\n', ' request took: %s seconds',
self._method, self._method,
self._url, self._url,
response.status, response.status,

View File

@ -6,7 +6,7 @@ from unittest import mock
import pytest import pytest
from .containers import ApplicationContainer from .containers import Container
@dataclasses.dataclass @dataclasses.dataclass
@ -17,7 +17,7 @@ class RequestStub:
@pytest.fixture @pytest.fixture
def container(): def container():
container = ApplicationContainer() container = Container()
container.config.from_dict({ container.config.from_dict({
'log': { 'log': {
'level': 'INFO', 'level': 'INFO',