Restart a python function in a script after n minutes

Viewed 137

I have a script that uses a server-sent event library to connect with a server that pushes events to me regularly. The issue is that the stream will freeze after a long time and I will have to restart the script manually and this is not maintainable. The structure of the current code looks like this

def listen(self):
        print("listening to events .....")
        try:
            url = settings.EVENT_URL + "/v1/events"
            auth_key = settings.KEY

            headers = {
                "Authorization": "Basic " + auth_key,
                "Accept": "text/event-stream",
            }

            response = self.with_urllib3(url, headers)
            client = sseclient.SSEClient(response)

            for event in client.events():
                # the script freezes here.
                logger.info(event.data)

                process(event.data)

I have tried doing something like

def start(self):
    def wait():
        time.sleep(10 * 60)

    background = threading.Thread(name = 'background', target = self.listen)
    background.daemon = True
    background.start()
    wait()

try:
    self.start()
except:
    self.start()
finally:
    self.start()

But I don't know if this will work mainly because a daemon thread will keep running in the background which means I will have copies of the task running after a while.

What I need is a better way to call a function and after some elapsed time return from the function and recall it again immediately. Thanks for any help.

1 Answers

You could consider a construction using the signal module like shown below. As a note though, the SIGALRM signal is not compatible with Windows.

import signal


TIMEOUT = 5


def _handle_alarm(_, __):
    raise TimeoutError("Some useful message")


def listen():
    print("Starting to listen...")
    import time
    time.sleep(10)


while True:
    try:
        timer = signal.signal(signal.SIGALRM, _handle_alarm)
        timer.alarm(TIMEOUT)
        listen()
    except TimeoutError:
        pass
Related