Search code examples
pythonwindowssubprocessrestart

subprocess can't successfully restart the targeted python file


I write a program my_test.py to get data from web and store to mysql. But the program my_test.py collapses a lot (my bad programming skill...) and I try to monitor its status and restart it when it collapses. I use subprocess modular with the following codes.

import subprocess
import time
p = subprocess.Popen(['python.exe', r'D:\my_test.py'], shell=True)
while True:
    try:
        stopped = p.poll()
    except:
        stopped = True
    if stopped:
        p = subprocess.Popen(['python.exe', r'D:\my_test.py'], shell=True)
    time.sleep(60)

But when my_test.py collapses, a windows warning window jumps out to alert me that my_test.py is down and which action I will choose: stop, debug ... Something like that. And my_test.py seems frozen by the alert windows and the codes above can't restart it successfully. Only when I manually close the window by choose 'close', it will restart again.

It there any solution to this problem such that my codes can successfully restart my_test.py when it breaks down?

Sorry for the inconvinience brought by my poor English and thank in advance for your kind advices.


Solution

  • There are two parts in your question:

    How to restart

    The priority order:

    1. fix my_test.py, to avoid crashing due to known issues
    2. use a supervisor program to run your script such as upstart or supervisord -- they can restart it automatically if it crashes
    3. write your own supervisor program with its own bugs that you have to maintain

    It is best to limit yourself to options 1 and/or 2 if you can find an already-written supervisor program that works on Windows (upstart and supervisord do not work on Windows).

    Your current supervisor script could be improved to avoid waiting a minute before restarting the program after it crashes if it has been running more than a minute already:

    #!/usr/bin/env python3
    import sys
    import subprocess
    import time
    try:
        from time import monotonic as timer
    except ImportError:
        from time import time as timer # time() can be set back
    
    while True:
        earliest_next_start = timer() + 60
        subprocess.call([sys.executable, r'D:\my_test.py'])
        while timer() < earliest_next_start:
            time.sleep(max(0, earliest_next_start - timer()))