Y
Y
Yaroslav2021-08-23 09:19:37
linux
Yaroslav, 2021-08-23 09:19:37

How to make sleep for N seconds or until HTTP request arrives (asynchronous cron with http server)?

There is a certain Python program (client) that periodically does some work (an eternal loop in which it climbs to the server, checks the status and, if necessary, does things, at the end of the iteration - sleep () for 5 minutes, so that the next iteration is most likely there is a new job). Naturally, if new data appears immediately after processing - it will be processed only after 5 minutes - this is not good.

I would like to optimize it a bit. Let the client spin a simple web server in the waiting state, when a new task appears, the server makes an HTTP request to this URL, and the client, having received the request, stops waiting, starts processing, and then comes to this waiting again. Thus, processing will start immediately after the appearance of a new job.

I see two options:
1. Some kind of 'cron with http server' is needed. To tell him - "run the script every 5 minutes, or immediately upon the arrival of an HTTP request."
2. Do it in the program itself. But then instead of sleep () you need to somehow start the web server for 5 minutes. And when a request arrives, kill it ahead of schedule.

Is there any ready-made simple solution for this (the task seems quite typical)? So far, all that comes to mind is the "invention of the bicycle", and in some cunning and complex ways.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
R
Rsa97, 2021-08-23
@Rsa97

If the client is still constantly hanging in memory, then use websockets. Then the server will be able to instantly notify clients about the appearance of a new job.

A
AndromedaStar, 2021-08-23
@AndromedaStar

Long-Polling, if I understand the task correctly, is just a little chaotically described.

W
warus, 2021-08-23
@warus

any signal sent by the kill command stops waiting for sleep
kill -SIGCONT pid_your_process
will wake up and crawl on http for info

Y
Yaroslav, 2021-09-08
@xenon

There was advice to use Firebase Cloud Messaging (FCM), which delivers push notifications to the device. A little strange, but it seems that it is impossible to use it on the desktop as a client (receive messages). There is no code for this in the python library. Even asked a question to a PyFCM developer , his answer is:

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.


Decided for myself :
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

Using the handle_request method instead of serve_forever() allows us to take control each time each request is processed and check if it's time to exit or do something else. And using timeout=1 gives us a return after 1 second even if there were no requests. Eventually

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question