Научная статья на тему 'ИССЛЕДОВАНИЕ РАЗРАБОТКИ АСИНХРОННОЙ МОНИТОРИНГОВОЙ СЛУЖБЫ НА БАЗЕ МОДУЛЯ ASYNCIO ЯЗЫКА ПРОГРАММИРОВАНИЯ PYTHON С ПРИМЕНЕНИЕМ ШАБЛОНА ПРОЕКТИРОВАНИЯ ВНЕДРЕНИЯ ЗАВИСИМОСТЕЙ'

ИССЛЕДОВАНИЕ РАЗРАБОТКИ АСИНХРОННОЙ МОНИТОРИНГОВОЙ СЛУЖБЫ НА БАЗЕ МОДУЛЯ ASYNCIO ЯЗЫКА ПРОГРАММИРОВАНИЯ PYTHON С ПРИМЕНЕНИЕМ ШАБЛОНА ПРОЕКТИРОВАНИЯ ВНЕДРЕНИЯ ЗАВИСИМОСТЕЙ Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
26
5
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ВНЕДРЕНИЕ ЗАВИСИМОСТЕЙ / ШАБЛОНЫ ПРОЕКТИРОВАНИЯ / ПРОГРАММИРОВАНИЕ / РАЗРАБОТКА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ / АСИНХРОННОЕ ПРОГРАММИРОВАНИЕ / МОНИТОРИНГ

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Могилатов Р.К.

данная научная работа исследует особенности и результаты применения шаблона проектирования внедрения зависимостей при разработке асинхронных мониторинговых служб на базе модуля asyncio языка программирования Python.

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Могилатов Р.К.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

RESEARCH OF THE DEVELOPMENT OF THE ASYNCHRONOUS MONITORING SERVICE BASED ON THE ASYNCIO MODULE OF THE PYTHON PROGRAMMING LANGUAGE WITH THE APPLICATION OF THE DEPENDENCY INJECTION DESIGN PATTERN

this scientific work examines the features and results of the application of the dependency injection design pattern in the development of asynchronous monitoring services based on the asyncio module of the Python programming language.

Текст научной работы на тему «ИССЛЕДОВАНИЕ РАЗРАБОТКИ АСИНХРОННОЙ МОНИТОРИНГОВОЙ СЛУЖБЫ НА БАЗЕ МОДУЛЯ ASYNCIO ЯЗЫКА ПРОГРАММИРОВАНИЯ PYTHON С ПРИМЕНЕНИЕМ ШАБЛОНА ПРОЕКТИРОВАНИЯ ВНЕДРЕНИЯ ЗАВИСИМОСТЕЙ»

22. Qi X., Silvestrov S., Nazir T. (2017). Data classification with support vector machine and generalized support vector machine. doi: 10.1063/1.4972718.

23. Ren Y., Tang L. (2019). A nonconvex and nonsmooth anisotropic total variation model for image noise and blur removal. Multimedia Tools and Applications, 79 (1-2), 14451473. doi: 10.1007/s11042-019-08179-8.

24. Vincent L. & Heijmans H. (2018). Graph Morphology in Image Analysis. Mathematical Morphology in Image Processing, 170-203. doi:10.1201/9781482277234-6.

25. Roerdink J.B. (2018). Mathematical Morphology with Noncommutative Symmetry Groups. Mathematical Morphology in Image Processing, 205-254. doi:10.1201/9781482277234-7.

26. Liu K., Lu B., Wei Y. (2013). Better image texture recognition based on SVM classification. MIPPR 2013: Pattern Recognition and Computer Vision. doi:10.1117/12.2031539.

27. Budiman A., Fanany M.I. & Basaruddin C. (2014). Stacked Denoising Autoencoder for feature representation learning in pose-based action recognition. 2014 IEEE 3rd Global Conference on Consumer Electronics (GCCE). doi:10.1109/gcce.2014.7031302.

28. Liang J., & Liu R. (2015). Stacked denoising autoencoder and dropout together to prevent overfitting in deep neural network. 2015 8th International Congress on Image and Signal Processing (CISP). doi:10.1109/cisp.2015.7407967.

29. Menezes J., Poojary N. (2019). Hyperspectral image Data Classification with Refined Spectral-Spatial features based on Stacked Autoencoder approach. Recent Patents on Engineering, 13. doi: 10.2174/187221211366619091114 1616.

30. Sercu T. & Goel V. (2016). Advances in Very Deep Convolutional Neural Networks for LVCSR. Interspeech 2016. doi:10.21437/interspeech.2016-1033.

31. Zhang Z., Gong C., Liu R. (2017). Face Detection Based on Method Combined RVM and SVM. Computer Science and Artificial Intelligence. doi: 10.1142/9789813220294_0058.

32. Ganakwar D.G., Kadam V.K. (2019). Face Detection Using Boosted Cascade of Simple Feature. 2019 International Conference on Recent Advances in Energy-efficient Computing and Communication (ICRAECC). doi:10.1109/icraecc43874.2019.8994977.

ИССЛЕДОВАНИЕ РАЗРАБОТКИ АСИНХРОННОЙ МОНИТОРИНГОВОЙ СЛУ БЫ НА БАЗЕ МОДУЛЯ AS N C O ЯЗЫКА ПРОГРАММИРОВАНИЯ P T HON С ПРИМЕНЕНИЕМ ШАБЛОНА ПРОЕКТИРОВАНИЯ ВНЕДРЕНИЯ ЗАВИСИМОСТЕЙ Могилатов Р.К. Email: Mogylatov 17163@scientifictext.ru

Могилатов Роман Константинович - технический руководитель, Python SoftServe Inc., г. Роли, Соединенные Штаты Америки

Аннотация: данная научная работа исследует особенности и результаты применения шаблона проектирования внедрения зависимостей при разработке асинхронных мониторинговых служб на базе модуля asyncio языка программирования Python.

Ключевые слова: внедрение зависимостей, шаблоны проектирования, Python, программирование, разработка программного обеспечения, асинхронное программирование, мониторинг.

RESEARCH OF THE DEVELOPMENT OF THE ASYNCHRONOUS MONITORING SERVICE BASED ON THE ASYNCIO MODULE OF THE PYTHON PROGRAMMING LANGUAGE WITH THE APPLICATION OF THE DEPENDENCY INJECTION DESIGN

PATTERN Mogylatov R.K.

Mogylatov Roman Konstantinovich - Technical Leader, PYTHON SOFTSERVE INC., RALEIGH, UNITED STATES OF AMERICA

Abstract: this scientific work examines the features and results of the application of the dependency injection design pattern in the development of asynchronous monitoring services based on the asyncio module of the Python programming language. Keywords: dependency injection, design patterns, Python, programming, software development, asynchronous programming, monitoring.

УДК 004.053

Цель исследования

Целью данной научной работы является исследование особенностей и результаты применения шаблона проектирования внедрения зависимостей для разработки асинхронных приложений.

Техническое задание

Для проведения исследования применения шаблона проектирования внедрения зависимостей в асинхронных приложениях необходимо использовать прикладную задачу: создать асинхронный мониторинговый сервис на языке программирования Python. Для реализации асинхронной парадигмы необходимо использовать модуль asyncio. Для реализации шаблона внедрения зависимостей необходимо использовать программный комплекс Dependency Injector.

Функциональные требования исследуемого приложения:

• Асинхронная мониторинговая служба должна работать в фоновом режиме

• Асинхронная мониторинговая служба должна выполнять контроль доступности узлов сети интернет example.com и httpbin.org

• Частота дискретизации контроля доступности узлов не должна выходить за пороговое значение 5 секунд.

• При успешном доступе к указанным узлам асинхронная мониторинговая служба должна записать в журнал событий следующую информацию:

o Код HTTP ответа

o Количество байт информации в HTTP ответе

o Время в секундах с точностью до миллисекунд затраченное выполнение запроса

■http-

■every minut

-https-

Рис. 1. Архитектура асинхронного мониторингового сервиса

Подготовка окружения для исследования

Перед началом исследования нам необходимо подготовить окружение. Для исследования мы будем использовать систему виртуализации Docker и программный пакет управления средой виртуализации Docker - утилиту интерфейса командной строки docker-compose.

Перед созданием рабочего окружения выполним проверки версий среды виртуализации Docker и утилиты docker-compose: docker -version docker-compose -version Ожидаемый результат: Docker version 19.03.12, build 48a66213fe docker-compose version 1.26.2, build eefe0d31

В случае если указанные команды выводят ошибку или версии программного обеспечения ниже указанных, необходимо выполнить установку, настройку и обновление программного комплекса Docker [18] и утилиты docker-compose [19]. Проверка и настройка среды виртуализации завершена. Создание структуры исследовательского проекта

Следующим шагом исследования является создание структуры программного проекта.

Выполним создание корневой папки исследовательского проекта: mkdir asyncio-daemon-research cd asyncio-daemon- research

Выполним создание структуры проекта в файловой системе соответственно следующей схеме: ./

|-monitoringdaemon/

|- init .py

|- main .py

| '-containers.py

|-config.yml

|-docker-compose.yml

|-Dockerfile

1-requirements.txt

Далее выполним настройку окружения проекта. Добавим следующие строки в файл requirements.txt: dependency-injector

aiohttp pyyaml pytest

pytest-asyncio pytest-cov

Далее выполним создание базового образа виртуального сервиса мониторинговой службы. Добавим строки в файл Dockerfile: FROM python:3.8-buster

ENV PYTHONUNBUFFERED=1

WORKDIR /code COPY . /code/

RUN apt-get install openssl \ && pip install --upgrade pip \ && pip install -r requirements.txt \ && rm -rf ~/.cache

CMD ["python", "-m", "monitoringdaemon"] Добавим строки в файл docker-compose.yml: version: "3.7" services: monitor: build: ./

image: monitoring-daemon volumes: - "./:/code"

Выполним сборку контейнеров. Выполним в терминале: docker-compose build

Процесс сборки занимает несколько минут. По окончанию сборки увидим в терминале следующие строки (хэш образа может отличаться): Successfully built 5b4ee5e76e35 Successfully tagged monitoring-daemon:latest

После окончания сборки запустим контейнер виртуального окружения: docker-compose up Ожидаемый результат:

Creating network "asyncio-daemon-research default" with the default driver

Creating asyncio-daemon-research monitor 1 ... done

Attaching to asyncio-daemon-research monitor 1

asyncio-daemon-research monitor 1 exited with code 0

Настройка виртуального окружения завершена.

Настройка журнала событий и конфигурирования

Для продолжения исследования нам необходимо настроить логирования в журнал событий и конфигурирование. Для реализации работы журнала событий будем использовать модуль стандартной библиотеки языка программирования Python logging. Для конфигурирования будем использовать компоненты программного пакета Dependency Injector.

Добавим следующие строки в файл containers.py: ......Containers module.......

import logging import sys

from dependency_injector import containers, providers

class Container(containers.DeclarativeContainer): config = providers.Configuration() logging = providers.Resource( logging.basicConfig, stream=sys. stdout, level=config. log. level, format=config.log.format,

)

Конфигурационный файл будет содержать настройки журнала событий.

Отредактируем файл config.yml: log:

level: "INFO"

format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s" Далее создадим основной модуль запуска асинхронной мониторинговой службы.

Отредактируем файл_main_.py:

......Main module.......

from .containers import Container

def main() -> None:

if_name_== '_main_':

container = Container()

container.config.from_yaml('config.yml')

container.init_resources()

main()

Настройка журнала событий и конфигурирования исследуемого приложения завершена.

Добавление диспетчера

Теперь добавим диспетчер контрольных проверок. Диспетчер будет контролировать список задач мониторинга. Он будет выполнять каждую задачу в соответствии с настроенным расписанием. Класс Monitor - это базовый класс для всех мониторов. Вы можете создавать разные мониторы, создавая подклассы и реализуя метод check().

Рис. 2. Диаграмма классов диспетчера мониторингового сервиса Создадим файлы dispatcher.py и monitors.py в пакете monitoringdaemon:

-monitoringdaemon/

--init_.py

--main_.py

-containers.py

-dispatcher.py

-monitors.py

-config.yml

-docker-compose.yml

-Dockerfile

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

-requirements.txt

Затем поместим следующие строки в monitors.py: ......Monitors module.......

import logging

class Monitor:

def_init_(self, check_every: int) -> None:

self.check_every = check_every

self.logger = logging.getLogger(self._class_._name_)

async def check(self) -> None: raise NotImplementedError() И затем поместим следующие строки в dispatcher.py: ......Dispatcher module.......

import asyncio import logging import signal

import time

from typing import List

from .monitors import Monitor

class Dispatcher:

def_init_(self, monitors: List[Monitor]) -> None:

self._monitors = monitors self._monitor_tasks: List[asyncio.Task] = []

self._logger = logging.getLogger(self._class_._name_)

self._stopping = False def run(self) -> None:

asyncio.run(self.start()) async def start(self) -> None: self._logger.info('Starting up') for monitor in self._monitors: self._monitor_tasks.append( asyncio.create_task(self._run_monitor(monitor)),

)

asyncio.get_event_loop(). add_signal_handler(signal. SIGTERM, self. stop) asyncio.get_event_loop(). add_signal_handler(signal. SIGINT, self. stop) await asyncio.gather(*self._monitor_tasks, return_exceptions=True) self.stop() def stop(self) -> None: if self._stopping:

return self._stopping = True self._logger.info('Shutting down')

for task, monitor in zip(self._monitor_tasks, self._monitors):

task.cancel() self._monitor_tasks.clear() self._logger.info('Shutdown finished successfully') @staticmethod

async def _run_monitor(monitor: Monitor) -> None: def _until_next(last: float) -> float: time_took = time.time() - last return monitor.check_every - time_took while True: time_start = time.time() try:

await monitor.check() except asyncio.CancelledError:

break except Exception:

monitor.logger.exception('Error executing monitor check') await asyncio.sleep(_until_next(last=time_start)) Далее подключим диспетчер в контейнер зависимостей. Отредактируем файл containers.py:

......Containers module.......

import logging import sys

from dependency_injector import containers, providers

from . import dispatcher

class Container(containers.DeclarativeContainer): config = providers.Configuration() logging = providers.Resource( logging.basicConfig, stream=sys. stdout, level=config. log. level, format=config.log.format,

)

dispatcher = providers.Factory( dispatcher.Dispatcher, monitors=providers.List( # TODO: add monitors

),

)

Воспользуемся шаблоном проектирования внедрения зависимостей для того чтобы связать основную функцию приложения с диспетчером и вызвать его метод run().

Отредактируем файл_main_.py:

......Main module.......

import sys

from dependency_injector.wiring import inject, Provide from .dispatcher import Dispatcher from .containers import Container

@inject

def main(dispatcher: Dispatcher = Provide[Container.dispatcher]) -> None: dispatcher.run()

if_name_== '_main_':

container = Container()

container.config.from_yaml('config.yml')

container.init_resources()

container.wire(modules=[sys.modules[_name_]])

main()

Для проверки работоспособности интеграции выполним запуск виртуальной службы. Выполним в терминале: docker-compose up Ожидаемый результат:

Starting asyncio-daemon-research_monitor_1 ... done Attaching to asyncio-daemon-research_monitor_1 monitor_1 | [2020-08-08 16:12:35,772] [INFO] [Dispatcher]: Starting up monitor_1 | [2020-08-08 16:12:35,774] [iNFo] [Dispatcher]: Shutting down monitor_1 | [2020-08-08 16:12:35,774] [INFO] [Dispatcher]: Shutdown finished successfully

asyncio-daemon-research_monitor_1 exited with code 0 Подключение диспетчера завершено. Асинхронный монитор для example.com

Добавим задачу мониторинга, которая будет проверять доступность http://example.com. Начнем с расширения нашей модели класса новым типом проверки мониторинга HttpMonitor.

HttpMonitor - это подкласс монитора. Мы реализуем метод check(), который будет отправлять HTTP-запрос на указанный URL. Отправка HTTP-запроса будет делегирована HttpClient.

Dispatcher N Monitor

monitors; [] Monitor + check_every: int

run() start)) stopQ

+ check()

А

HttpMonitor

+■ chect_every: int

о

* HttpClient

+ check_every: int

/

+ check(}

Рис. 3. Диаграмма классов диспетчера мониторингового сервиса с классом HttpMonitor Создадим файл http.py в пакете monitoringdaemon:

-monitoringdaemon/

- init .py

--main_.py

-containers.py

-dispatcher.py

-http.py

1-monitors.py

-config.yml

-docker-compose.yml

-Dockerfile

'-requirements.txt

Добавим в него следующие строки: ......Http client module.......

from aiohttp import ClientSession, ClientTimeout, ClientResponse class HttpClient:

async def request(self, method: str, url: str, timeout: int) -> ClientResponse: async with ClientSession(timeout=ClientTimeout(timeout)) as session: async with session.request(method, url) as response: return response

Далее добавим HttpClient в контейнер. Отредактируем файл containers.py: ......Containers module.......

import logging import sys

from dependency_injector import containers, providers from . import http, dispatcher

class Container(containers.DeclarativeContainer): config = providers.Configuration() logging = providers.Resource( logging.basicConfig, stream=sys. stdout, level=config. log. level, format=config.log.format,

)

http_client = providers.Factory(http.HttpClient) dispatcher = providers.Factory( dispatcher.Dispatcher, monitors=providers.List( # TODO: add monitors

),

)

Далее добавляем класс HttpMonitor. Мы добавим его в модуль мониторов. Отредактируем файл monitors.py: ......Monitors module.......

import logging import time

from typing import Dict, Any from .http import HttpClient

class Monitor:

def_init_(self, check_every: int) -> None:

self.check_every = check_every

self.logger = logging.getLogger(self._class_._name_)

async def check(self) -> None: raise NotImplementedError()

class HttpMonitor(Monitor): def __init__ ( self,

http_client: HttpClient, options: Dict[str, Any], ) -> None: self._client = http_client self._method = options.pop('method') self._url = options.pop('url') self._timeout = options.pop('timeout')

super()._init_(check_every=options.pop('check_every'))

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

async def check(self) -> None: time_start = time.time() response = await self._client.request( method=self._method, url=self._url, timeout=self._timeout,

)

time_end = time.time() time_took = time_end - time_start self.logger.info(

'Check\n'

' %s %s\n'

' response code: %s\n'

' content length: %s\n'

' request took: %s seconds',

self._method,

self._url,

response.status,

response.content_length,

round(time_took, 3)

)

Все готово для добавления мониторинга веб-узла http://example.com. Необходимо внести два изменения в контейнер:

• Добавление поставщика фабрики example_monitor.

• Внедрение example_monitor в диспетчер. Отредактируем файл containers.py:

......Containers module.......

import logging import sys

from dependency_injector import containers, providers from . import http, monitors, dispatcher

class Container(containers.DeclarativeContainer): config = providers.Configuration() logging = providers.Resource( logging.basicConfig, stream=sys. stdout, level=config. log. level, format=config.log.format,

)

http_client = providers.Factory(http.HttpClient) example_monitor = providers.Factory( monitors. HttpMonitor, http_client=http_client, options=config. monitors.example,

)

dispatcher = providers.Factory( dispatcher.Dispatcher, monitors=providers.List( example_monitor,

),

)

Provider example_monitor зависит от параметров конфигурации. Определим эти параметры. Отредактируем файл config.yml: log:

level: "INFO"

format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s" monitors: example: method: "GET" url: "http://example.com" timeout: 5

check_every: 5

Добавление монитора завершено. Запустим асинхронную мониторинговую службу для тестирования работы. Запускаем в терминале: docker-compose up Ожидаемый результат:

Starting asyncio-daemon-research_monitor_1 ... done

Attaching to asyncio-daemon-research_monitor_1

monitor_1 | [2020-08-08 17:06:41,965] [INFO] [Dispatcher]: Starting up

monitor_1 | [2020-08-08 17:06:42,033] [INFO] [HttpMonitor]: Check

monitor_1 | GET http://example.com

monitor_1 | response code: 200

monitor_1 | content length: 648

monitor_1 | request took: 0.067 seconds

monitor_1 | [2020-08-08 17:06:47,040] [INFO] [HttpMonitor]: Check

monitor_1 | GET http://example.com

monitor_1 | response code: 200

monitor_1 | content length: 648

monitor_1 | request took: 0.073 seconds

Разрабатываемая асинхронная мониторинговая служба отслеживает доступность веб-узла http://example.com.

Асинхронный монитор для httpbin.org

Далее нам необходимо добавить монитор для веб-узла httpbin.org. Это будет требовать меньшего количества изменений, потому что все необходимые для этого компоненты уже разработаны. Таким образом нет необходимости добавлять дополнительный программный код, добавление монитора сводится к изменению контейнера зависимостей и конфигурационного файла. Этого преимущества возможно добиться благодаря применению шаблона проектирования внедрения зависимостей и использованию программного комплекса Dependency Injector. Создадим новый провайдер в контейнере зависимостей и обновим конфигурацию. Отредактируем файл containers.py: ......Containers module.......

import logging import sys

from dependency_injector import containers, providers from . import http, monitors, dispatcher

class Container(containers.DeclarativeContainer): config = providers.Configuration() logging = providers.Resource( logging.basicConfig, stream=sys. stdout, level=config. log. level, format=config.log.format,

)

http_client = providers.Factory(http.HttpClient) example_monitor = providers.Factory( monitors. HttpMonitor, http_client=http_client, options=config. monitors.example,

)

httpbin_monitor = providers.Factory( monitors.HttpMonitor,

http_client=http_client, options=config.monitors.httpbin,

)

dispatcher = providers.Factory( dispatcher.Dispatcher, monitors=providers.List( example_monitor, httpbin_monitor,

),

)

Отредактируем файл config.yml: log:

level: "INFO"

format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s" monitors: example: method: "GET" url: "http://example.com" timeout: 5 check_every: 5 httpbin: method: "GET" url: "https://httpbin.org/get" timeout: 5 check_every: 5

Запустим асинхронную мониторинговую службу и проверим журнал событий. Выполним в терминале: docker-compose up Ожидаемый результат:

Starting asyncio-daemon-tutorial_monitor_1 ... done Attaching to asyncio-daemon-tutorial_monitor_1

[2020-08-08 18:09:08,540] [INFO] [Dispatcher]: Starting up [2020-08-08 18:09:08,618] [INFO] [HttpMonitor]: Check GET http://example.com response code: 200 content length: 648 request took: 0.077 seconds [2020-08-08 18:09:08,722] [INFO] [HttpMonitor]: Check GET https://httpbin.org/get response code: 200 content length: 310 request took: 0.18 seconds [2020-08-08 18:09:13,619] [INFO] [HttpMonitor]: Check GET http://example.com response code: 200 content length: 648 request took: 0.066 seconds [2020-08-08 18:09:13,681] [INFO] [HttpMonitor]: Check GET https://httpbin.org/get response code: 200 content length: 310 request took: 0.126 seconds

Автоматическое модульное тестирование

Исследуем добавление автоматического модульного тестирования в асинхронную мониторинговую службу на базе модуля asyncio стандартной библиотеки языка программирования Python разработанную по принципу шаблона проектирования внедрения зависимостей с применением программного комплекса Dependency Injector.

Будем использовать программные пакеты pytest и coverage для запуска процесса автоматизированного тестирования и измерения процента покрытия. Создаем файл tests.py в пакете monitoringdaemon: ./

-monitoringdaemon/

--init_.py

--main_.py

-containers.py

-dispatcher.py

-http.py

-monitors.py

-tests.py

-config.yml

-docker-compose.yml

-Dockerfile

-requirements.txt

И добавляем в него следующие строки: ......Tests module.......

import asyncio import dataclasses from unittest import mock import pytest

from .containers import Container

@dataclasses.dataclass class RequestStub: status: int content_length: int

@pytest.fixture def container():

container = Container() container.config.from_dict({ 'log': { 'level': 'INFO',

'formant': '[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s',

},

'monitors': { 'example': { 'method': 'GET', 'url': 'http://fake-example.com', 'timeout': 1, 'check_every': 1,

},

'httpbin': {

'method': 'GET',

'url' : 'https://fake-httpbin. org/get', 'timeout': 1, 'check_every': 1,

},

},

})

return container @pytest. mark. asyncio

async def test_example_monitor(container, caplog): caplog. set_level('INFO') http_client_mock = mock.AsyncMock() http_client_mock.request.return_value = RequestStub( status=200, content_length=635,

)

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

with container.http_client.override(http_client_mock): example_monitor = container.example_monitor() await example_monitor.check() assert 'http://fake-example.com' in caplog.text assert 'response code: 200' in caplog.text assert 'content length: 635' in caplog.text

@pytest. mark. asyncio

async def test_dispatcher(container, caplog, event_loop): caplog. set_level('INFO') example_monitor_mock = mock.AsyncMock() httpbin_monitor_mock = mock.AsyncMock()

with container.example_monitor.override(example_monitor_mock),

container.httpbin_monitor.override(httpbin_monitor_mock): dispatcher = container.dispatcher() event_loop.create_task(dispatcher.start()) await asyncio.sleep(0.1) dispatcher.stop() assert example_monitor_mock. check. called assert httpbin_monitor_mock. check. called Для запуска автоматического тестирования выполняем команду в терминале: docker-compose run --rm monitor py.test monitoringdaemon/tests.py --cov=monitoringdaemon Ожидаемый результат:

platform linux -- Python 3.8.3, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 rootdir: /code

plugins: asyncio-0.14.0, cov-2.10.0 collected 2 items

monitoringdaemon/tests.py .. [100%]

-----------coverage: platform linux, python 3.8.3-final-0-----------

Name Stmts Miss Cover

monitoringdaemon/_init_.py 0 0 100%

monitoringdaemon/_main_.py 13 13 0%

monitoringdaemon/containers.py 11 0 100%

monitoringdaemon/dispatcher.py 44 5 89%

monitoringdaemon/http.py 6 3 50%

monitoringdaemon/monitors.py 23 1 96%

monitoringdaemon/tests.py 37 0 100%

TOTAL 134 22 84%

Рассмотрим результаты тестирования. Все основные модули покрыты автоматическими тестами. Общий процент покрытия составляет 84%. Это является высоким значением так как диапазон нормальных по индустрии на 2021 год является 40-60% покрытия. Вывод

Мы исследовали особенности и результаты применения шаблона применения внедрения зависимостей для разработки асинхронных мониторинговых систем на базе модуля asyncio стандартной библиотеки языка программирования Python применяя программный комплекс Dependency Injector.

Результатом исследования является полнофункциональное асинхронное мониторинговое приложение, которое удовлетворяет всем функциональным требованиям поставленной исследовательской задачи и обладает высоким процентом покрытия кода автоматическими модульными тестами превышающим по качеству диапазон стандартных значений по индустрии.

На базе проведенного исследования можно сделать вывод, что шаблон проектирования внедрения зависимостей выполняет свои функции при разработке асинхронных мониторинговых систем. Так же применений программного комплекса Dependency Injector для реализации шаблона проектирования внедрения зависимостей не ведет к деградации функциональной или нефункциональной частей асинхронного приложения.

Применение шаблона проектирования внедрения зависимостей и программного комплекса Dependency Injector позволяет добиваться снижения связности и увеличения сцепления в программных компонентах приложений на базе модуля asyncio стандартной библиотеки языка программирования Python.

Список литературы /References

1. Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts, Erich Gamma (Foreword) // Addison-Wesley Professional; 1st edition (June 28, 1999).

2. Patterns of Enterprise Application Architecture by Martin Fowler. Implementation Patterns by Kent Beck // Addison-Wesley Professional; 1st edition (October 23, 2007).

3. The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt, David Thomas // Addison-Wesley Professional; 1st edition (October 1, 1999).

4. Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin // Pearson; 1st edition (August 1, 2008).

5. Building Microservices: Designing Fine-Grained Systems by Sam Newman // O'Reilly Media; 1st edition (February 2, 2015).

6. Design Patterns: Elements of Reusable Object-Oriented Software by GoF - Gang of Four - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides // Addison-Wesley Professional; 1st edition (November 10, 1994).

7. Refactoring: Improving the Design of Existing Code (2nd Edition) by Martin Fowler // Addison-Wesley Professional; 2nd edition (November 30, 2018).

8. Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans // Addison-Wesley Professional; 1st edition (August 20, 2003).

9. The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition) by Brooks Jr., Frederick P. // Addison-Wesley Professional; Anniversary edition (August 2, 1995).

10. The Innovation Algorithm: TRIZ, systematic innovation and technical creativity (1st Edition) by Genrich Altshuller. // Technical Innovation Ctr; 1st edition (March 1, 1999).

11. Software Estimation: Demystifying the Black Art by Steve McConnell. // Microsoft Press; 1st edition (March 1, 2006).

12. Inversion of Control Containers and the Dependency Injection pattern. [Электронный ресурс]. Режим доступа: https://martinfowler.com/articles/injection.html/ (дата обращения: 15.06.2021).

13. Dependency Injector (Documentation). [Электронный ресурс]. Режим доступа: https://python-dependency-injector.ets-labs.org/ (дата обращения: 15.06.2021).

14. Dependency Injector (GitHub). [Электронный ресурс]. Режим доступа:https://github.com/ets-labs/python-dependency-injector/ (дата обращения: 15.06.2021).

15. Dependency Injector (Python Package Index). [Электронный ресурс]. Режим доступа:https://pypi.org/project/dependency-injector/ (дата обращения: 15.06.2021).

16. Dependency injection and inversion of control in Python. [Электронный ресурс]. Режим доступа:https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html/ (дата обращения: 15.06.2021).

17. Dependency injection. [Электронный ресурс]. Режим доступа:https://en.wikipedia.org/wiki/Dependency_injection/ (дата обращения: 15.06.2021).

18. Docker installation guide. [Электронный ресурс]. Режим доступа:https://docs.docker.com/engine/install/ (дата обращения: 15.06.2021).

19. Docker-compose installation guide. [Электронный ресурс]. Режим доступа:https://docs.docker.com/compose/install/ (дата обращения: 15.06.2021).

20. Python asyncio module documentation. [Электронный ресурс]. Режим доступа:https://docs.python.org/3/library/asyncio.html/ (дата обращения: 15.06.2021).

ПРОГНОЗИРОВАНИЕ СТАТИСТИЧЕСКИХ ДАННЫХ АВТОМОБИЛЬНЫХ ДОРО НО-ТРАНСПОРТНЫХ ПРОИСШЕСТВИЙ Ларионов К.О.

Email: Larionov 17163@scientifictext.ru

Ларионов Константин Олегович - аспирант, кафедра вычислительной техники и защиты информации, Оренбургский государственный университет, г. Оренбург

Аннотация: в статье анализируется статистика автомобильных дорожно-транспортных происшествий. Актуальность разработки и внедрения метода прогнозирования статистики автомобильных дорожно-транспортных происшествий обуславливается тем, что применяемый метод прогнозирования позволяет достаточно точно определить прогнозное значение с максимальной погрешностью меньше 15%. Автоматизированные методы прогнозирования на сегодняшний день помогают быстрому принятию решений в конкретной предметной области за счет быстрой обработки большого количества статистических данных. Ключевые слова: защита, система, информация, программное обеспечение, дорожно-транспортные происшествия, прогноз, статистика, автомобиль.

i Надоели баннеры? Вы всегда можете отключить рекламу.