xenon
@xenon
Too drunk to fsck

Как сделать sleep на N секунд либо до прихода HTTP запроса (асинхронный cron с http сервером)?

Есть некая питоновская программа (клиент), которая периодические делает некоторую работу (вечный цикл, в котором она лезет на сервер, проверяет состояние и если надо - делает дела, в конце итерации - sleep() на 5 минут, чтобы к следующей итерации скорее всего появилась новая работа). Естественно, если новые данные появляются сразу после обработки - они будут обработаны только через 5 минут - это нехорошо.

Хочется оптимизировать ее немного. Пусть клиент в состоянии ожидания крутит простой веб-сервер, при появлении новой задачи сервер делает HTTP запрос на этот URL, и клиент, получив запрос прекращает ожидание, начинает обработку и затем снова приходит к этому ожиданию. Таким образом обработка будет запускаться сразу же после появления новой работы.

Вижу два варианта:
1. Нужен какой-то 'cron с http сервером'. Чтоб ему сказать - "запускай скрипт каждые 5 минут, либо сразу по приходу HTTP запроса".
2. Сделать это в самой программе. Но тогда нужно вместо sleep() как-то запустить веб-сервер на 5 минут. А при приходе запроса - досрочно его прибить.

Есть какой-то готовый простой вариант решения для этого (задача кажется достаточно типовой)? Пока что все, что приходит на ум - это "изобретение велосипеда", причем какими-то хитрыми и сложными способами.
  • Вопрос задан
  • 247 просмотров
Пригласить эксперта
Ответы на вопрос 4
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если уж клиент всё равно постоянно висит в памяти, то используйте вебсокеты. Тогда сервер сможет моментально извещать клиентов о появлении нового задания.
Ответ написан
@AndromedaStar
.Net - monkey
Long-Polling, если я правильно понял задачу, просто немного сумбурно описано.
Ответ написан
Комментировать
@warus
любой сигнал посланный командой kill прекращает ожидание по sleep
kill -SIGCONT pid_вашего_процесса
заставит проснутся и ползти по http за инфой
Ответ написан
xenon
@xenon Автор вопроса
Too drunk to fsck
Был совет использовать Firebase Cloud Messaging (FCM), которым доставляются push уведомления на устройство. Немного странно, но похоже, его невозможно использовать на десктопе в качестве клиента (принимать сообщения). В python библиотеке нет кода для этого. Даже задал вопрос разработчику PyFCM, его ответ:

You can only receive messages via an Android, iOS or web client https://firebase.google.com/docs/cloud-messaging#h...

An iOS, Android, or web (JavaScript) client app that receives messages via the corresponding platform-specific transport service.



Для себя решил так:

from http.server import BaseHTTPRequestHandler, HTTPServer
class RequestHandler(BaseHTTPRequestHandler):
        # implementation

httpd = HTTPServer((self.address, self.port), RequestHandler)
httpd.timeout = 1
        
while True:
    httpd.handle_request()
    # check if quit


Использование метода handle_request вместо serve_forever() позволяет нам получать управление каждый раз по обработке каждого запроса и проверять, не пора ли выйти или исполнить другие действия. А использование timeout=1 дает нам возврат через 1 секунду даже если запросов не было. В итоге
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы