Таймер (Python)
Хай,
В python программе необходима функция, при запуске которой проверяется условие 'z' (например, подключение к серверу) в начале цикла, спустя 10, 20, 30 минут.
Если подключение появилось, функция останавливает свою работу, если по истечению 30 минут подключения также нет, функция оправляет на email сообщение о неисправности.
Реализовать эту функцию нужно без использования sleep(), т.к. при этом остальная программа засыпает, что неприемлемо.
Обычный цикл постоянной проверки сильно нагружает машинку, он тоже отпадает, вот такой я изначально написал:
def check_connection():
import time
if path.exists(decode(filename)):
files_to_send.append(filename)
# connection exist, save log, don't send anything
else:
point1 = time.time() # remember connection lost moment
while path.exists(decode(filename)) != True:
delta = time.time() - point1 # delta
if delta > 600.0:
# no connection for 10 minutes, do nothing
if delta > 1200.0:
# no connection for 20 minutes, do nothing
if delta > 1800.0:
# no connection for 30 minutes, sending email massage
message_text += "\nОШИБКА: присоединенный к e-mail файл
'%s' не найден" % filename
send_mail_from_account("000000", ["[email protected]"], "alert",
message_text, files_to_send)
break # exit cycle
Где path.exists(decode(filename)) - проверка подключения
По сему было принято решение как-то реализовать функцию в отдельном py-файле, с использованием sleep(), где в период ожидания программа спит, просыпаясь только на проверку условия, пока первая продолжает работать. После и результат выполнения возвращается в первую программу или не возвращается и выполняется либо выход из цикла и закрытие 2й программы (если подключение появилось) или 2ая программа сама выполнит отправку отчета на email.
В силу своей малограмотности не пойму, как увязать 2 программы между собой, как передавать результат между ними. Помогите реализовать цикл, или подскажите более оптимальное решение.
Спасибо.
Ответы (1 шт):
Основная работа программы происходит в функции main(), в отдельном multiprocessing-процессе. В главном процессе, в функции check_connection(), происходит проверка наличия подключения, отправка сообщения на email, и выход из программы. Процессы работают паралельно и связаны между собой _connection-эвентом, указывающим на признак наличия "подключения к серверу", и exit_status-эвентом, указывающим на необходимость завершения работы функции main().
Если происходит потеря "подключения к серверу", необходимо установить _connection-эвент, а функция check_connection() периодически проверяет этот эвент, и при необходимости замеряет время, прошедшее с момента последней такой проверки. При превышении таймаута connection_timeout, устанавливается признак exit_status, сигнализирующий функции main() о необходимости завершения её работы на следующей итерации цикла; или т.к. у функции main() для процесса установлен признак daemon=True, то выход может произойти принудительно, не дожидаясь следующей итерации цикла для проверки exit_status-эвента, сразу после завершения функции check_connection() в главном процессе.
import random, multiprocessing, time
_connection = multiprocessing.Event() # условие подключения
connection_lost = lambda con: con.set() # эмуляция потери подключения
is_connect = lambda con: not con.is_set() # проверка наличия подключения
exit_status = multiprocessing.Event() # условие выхода из программы
def check_connection(connection_timeout=5, condition_timeout=1):
"""проверяется условие подключения"""
t1 = time.monotonic()
while True:
if is_connect(_connection):
t1 = time.monotonic() # при появлении подключения - сбросить таймаут проверки подключения
else:
t2 = time.monotonic() - t1 # таймаут с момента последней проверки подключения
print('Подключения нет уже {:.1f} сек'.format(t2))
if t2 >= connection_timeout:
break # превышен таймаут при отсутствии подключения
exit_status.wait(condition_timeout) # частота проверки подключения
exit_status.set() # признак выхода main-работы программы
print('Отправка сообщения о неисправности на [email protected]')
def main(_connection, exit_status):
"""работа программы"""
while not exit_status.is_set():
print('идет какая-то работа программы...')
exit_status.wait(2) # 'эмуляция работы
if is_connect(_connection) and random.randint(1, 3) == 3:
print('\nПотеря подключения !!!\n')
connection_lost(_connection)
if __name__ == '__main__':
multiprocessing.Process(target=main, args=(_connection, exit_status), daemon=True).start()
check_connection(connection_timeout=5, condition_timeout=1)
print('выход')
out:
идет какая-то работа программы...
идет какая-то работа программы...
Потеря подключения !!!
идет какая-то работа программы...
Подключения нет уже 1.0 сек
Подключения нет уже 2.0 сек
идет какая-то работа программы...
Подключения нет уже 3.0 сек
Подключения нет уже 4.0 сек
идет какая-то работа программы...
Подключения нет уже 5.0 сек
Отправка сообщения о неисправности на [email protected]
выход