Kai
Kai

Reputation: 81

Python Execute a Function after timeout

i want to start a function after a timeout in a While true loop, but the code dont execute anything and jumps out the loop and i dont know why :/

Here is my Code

import requests
from threading import Timer

def timeout(flag):
            print("New Request")
            statuscode = requests.get("http://adslkfhdsjf.de").status_code
            if statuscode == 200 and flag == 0:
                print("Service available")
            #Testzwecke
            print("Flag: ", flag)
            flag = 0
            #Poste result to Backend
        elif statuscode == 200 and flag == 1: 
            print("Service is available now")
            print("Flag: ", flag)
            flag = 0
            #Email an User
            #Post Request
        elif statuscode != 200 and flag == 0:
            print("Service is not available")
            #Testzwecke
            print("Flag: ", flag)
            flag = 1
            #Email to User
            #Post Request
        else: 
            print("Service is not available")
            #Testzwecke
            print("Flag: ", flag)
            #Post Request
        Timer(10, timeout, flag)

timeout(0)

I want that timeout is executed for example every 10 seconds. So every 10 second one condition from the function timeout() will be executed.

But its not working so far, the console output is nothing :/

Upvotes: 0

Views: 799

Answers (1)

abarnert
abarnert

Reputation: 366133

Your first problem is just that you're not calling main(). And normally, I'd just add a comment to tell you that and close the question as a typo, but you don't want to fix that until you first fix your bigger problem.

Your code tries to create and call a new timeout function over and over, as fast as possible. And the first thing that timeout function does is to create a new Timer object. Which is a new thread.

So you're spawning new threads as fast as Python will let you, which means in a very short time you're going to have more threads than your OS can handle. If you're lucky, that will mean you get an exception and your program quits. If you're unlucky, that will mean your system slows to a crawl as the kernel starts swapping thread stacks out to disk, and, even after you manage to kill the program, it may still take minutes to recover.

And really, there's no reason for the while loop here. Each Timer schedules the next Timer, so it will keep running forever. And there's only ever 2 threads alive at a time that way.

But there's not even a reason for a Timer in the first place. You don't want to do anything while waiting 10 seconds between requests, so why not just sleep?

import time
import requests

def main():
    flag = 0
    while True:
        print("New Request")
        statuscode = requests.get("http://google.de").status_code
        if statuscode == 200 and flag == 0:
            print("Service available")
            # etc.
        time.sleep(10)

main()

Your code had another problem: you're defining a local variable named flag in timeout, but then you're trying to use it, in that flag == 0 check, before you ever assign to it. That would raise an UnboundLocalError. The fact that you happen to also have a local variable named flag in main doesn't make a difference. To fix this, you'd have to do one of these:

  • Pass flag in as an argument for Timer to pass to each timeout call as a parameter. (Probably best.)
  • Add a nonlocal flag declaration to timeout, so it becomes a closure cell shared by all of the timeout functions you define. (Not bad, but not the most idiomatic solution.)
  • Add a global flag declaration to both functions, so it becomes a global variable shared by everyone in the universe. (Probably fine a program this simple, but at the very least not a good habit to get into.)

But, once we've gotten rid of the thread, we've also gotten rid of the function, so there's just the one local flag, so the problem doesn't come up in the first place.

Upvotes: 2

Related Questions