Tapokpy
@Tapokpy
starting

Как подружить непрерывно выполняющую функцию по мониторингу сети и Телеграм бота на aiogram?

Здравствуйте, добрые люди. Спасите мою голову.
Имеем функцию по мониторингу интернет соединения:
import asyncio
import datetime
import logging
import socket


def send_ping_request(host="google.com", port=443, timeout=3):
    try:
        socket.setdefaulttimeout(timeout)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
    except OSError as error:
        return False
    else:
        s.close()
        return True


def calculate_time(start, stop):
    time_difference = stop - start
    seconds = float(str(time_difference.total_seconds()))
    return str(datetime.timedelta(seconds=seconds)).split(".")[0]


logger = logging.getLogger("Testy")  # Создаем логгер
fileHandler = logging.FileHandler('logs.log')  # создаем хэндлер и формат для записи в файл
# fileFormat = logging.Formatter("[%(asctime)s]  %(message)s")
fileHandler.setLevel(logging.WARNING)  # устанавливаем уровень хэндлера и добавляем к логгеру
# fileHandler.setFormatter(fileFormat)
logger.addHandler(fileHandler)


async def mon_net_connection(ping_freq=2):  # поставить 20>
    await asyncio.sleep(1)
    motd = f"{str(datetime.datetime.now()).split('.')[0]} - Мониторинг сетевого подключения начат. \n" \
           f" Отправка запроса ping каждые {ping_freq} секунды "
    logger.warning(motd)
    print(motd)
    while True:
        if send_ping_request():
            await asyncio.sleep(ping_freq)
        else:
            down_time = datetime.datetime.now()
            fail_msg = f"{str(down_time).split('.')[0]} False - Сетевое соединение недоступно"
            print(fail_msg)
            logger.warning(fail_msg)
            await asyncio.sleep(1)

            while not send_ping_request():
                await asyncio.sleep(1)  # ждать секунду
            up_time = datetime.datetime.now()
            uptime_message = f"{str(up_time).split('.')[0]} - Сетевое подключение восстановлено"
            down_time = calculate_time(down_time, up_time)
            _m = f"Были вне сети: {down_time} "
            print(uptime_message)
            print(_m)
            logger.warning(uptime_message)
            logger.warning(_m)
            await asyncio.sleep(1)

asyncio.run(mon_net_connection())

И стандартный телеграм-бот на aiogram:
from aiogram import executor
from loader import dp

from utils.notify_admins import on_startup_notify
from utils.set_bot_commands import set_default_commands
import handlers


async def on_startup(dispatcher):
    await set_default_commands(dispatcher)  # Устанавливаем дефолтные команды
    await on_startup_notify(dispatcher)  # Уведомляет админов про запуск

if __name__ == '__main__':
    executor.start_polling(dp, on_startup=on_startup)


Как их запустить, что бы и мониторинг и бот с его хендлерами и т.д. заработали дружно и весело?
  • Вопрос задан
  • 871 просмотр
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
Во-первых, asyncio - это выполнение сопрограмм в бесконечном цикле событий. Если в одной из сопрограмм запустить другой бесконечный цикл, он её заблокирует и сломает асинхронность. Поэтому while True нужно убрать и проверки раз в секунду поручать циклу событий. Во-вторых, в асинхронной программе надо максимально избегать блокировок, поэтому блокирующийся send_ping_request надо переписать на асинхронных средствах работы с сокетами, предоставляемых asyncio.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы