0

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 :/

8
  • Your code as posted here just defines a main function and never calls it. Is that true for your real code as well? Commented Jul 13, 2018 at 17:40
  • Put the declaration of the variable flag and the definition of timeout outside the main. Commented Jul 13, 2018 at 17:40
  • Anyway, if you fix that (by adding a dedented main() at the end of your script), you'll have a whole new problem: you're creating and calling a new timeout function over and over as fast as possible. Each one creates a Timer, which creates a new thread. So you're very quickly going to create more threads than your OS can handle. If you're lucky, you'll get an error. If you're not lucky, your system will slow to a crawl, and take minutes to recover even after you manage to kill the script. Commented Jul 13, 2018 at 17:42
  • @AfloroaieRobert While those are both reasonable things to do, how is either one going to fix any problem with the code? There's a tiny cost to constructing a new function object every 10 seconds, but who cares? The flag in main will be hidden by the flag in timeout, but the same would be true for a global flag. Commented Jul 13, 2018 at 17:50
  • @abarnert, I wasn't trying to solve the problem, I was trying to suggest some improvements to the code hence the comment and not an answer. Commented Jul 13, 2018 at 17:51

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

hi, thank you first for the accurate answer :) One Question for a newbie, how i do that for the timer, i rly dont understand that timer well in python and the docu dont help me out. In this case i will pass the flag in my main like that ? main(flag)
@Kai A Timer takes a timeout, a function, and any number of args and kwargs. So, for example, Timer(20, timeout, flag) will call timeout(flag) adter 20 seconds, and Timer(20, print, 20, 30, sep=',') will call print(20, 30, sep=',') after 20 seconds.
so, can i call instead of main the timer function with the parameter ?
@Kai Yes, if you want to use the Timer, you don't really need main, you can just call timeout directly. If you're passing the flag as an argument, your top-level code would call timeout(0) to pass in the initial value for flag, and then at the end of timeout it would do a Timer(10, timeout, flag) to pass the new value on to the next call.
i have edit the code and the timer function dont call itself after 10 seconds :/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.