我想替换Cron Jobs以“保持”我的程序活着,因为无论是否已经调用了脚本,它都会调用每个XX间隔,从而创建重复的条目。
我调查了这个问题,并采取了一些方法。一个是修改我的程序,以便检查它是否已被调用并自行关闭。我追求的是通过execfile
一遍又一遍地调用它来完全脱离Cronjob,除了以下问题之外,它正是我想要的。
RuntimeError: maximum recursion depth exceeded
有没有办法让程序保持“无限循环”而不会出现堆栈溢出?
这是我的代码,它是一个检查Mails的程序,并将它们转换为MySQL DB条目。
imap = imaplib.IMAP4(hst)
try:
imap.login(usr, pwd)
except Exception as e:
errormsg = e
time.sleep(30)
print "IMAP error: " + str(errormsg)
execfile('/var/www/html/olotool/converter.py')
raise IOError(e)
# Authentification & Fetch Step
while True:
time.sleep(5)
'''
The script will always result in an error if there
are no mails left to check in the inbox. It then
goes into sleep mode and relaunches itself to check
if new mails have arrived.
'''
try:
imap.select("Inbox") # Tell Imap where to go
result, data = imap.uid('search', None, "ALL")
latest = data[0].split()[-1]
result, data = imap.uid('fetch', latest, '(RFC822)')
raw = data[0][1] # This contains the Mail Data
msg = email.message_from_string(raw)
except Exception as e:
disconnect(imap)
time.sleep(60)
execfile('/var/www/html/olotool/converter.py')
raise IOError(e)
答案 0 :(得分:0)
我自己解决了这个问题的唯一方法就是我现在可以看到它。 首先,我在上面的代码中更改了我的异常:
except Exception as e:
disconnect(imap)
print "Converter: No messages left"
raise os._exit(0)
# This is a special case since this Exception is
# no error thus os._exit(0) gives no false-positives
如您所见,我现在不使用execfile
。相反,我写了一个控制器脚本来检查我的converter.py的状态,如果它还没有运行则启动它:
while True:
presL = os.popen('pgrep -lf python').read()
print "________________________________________"
print "Starting PIDcheck"
print "Current Processes: "
print presL # Check Processes
presRconverter = find('\d{7} python converter.py', presL)
if presRconverter:
# Store the PID
convPID = find('\d{7}', presRconverter)
print "Converter is running at PID: " + convPID
else:
print "PID Controller: Converter not running"
try:
print "PID Controller: Calling converter"
subprocess.check_call('python converter.py', shell=True)
except subprocess.CalledProcessError as e:
errormsg = e
print "Couldn't call Converter Module"
sendMail(esender,ereceiver,esubject,etext,server)
print "Error notification send"
raise IOError(e)
# If we got until here without ERROR, the call was Successfull
print "PID Controller: Call successful"
print "________________________________________"
time.sleep(60)
此方法不会引发:RuntimeError: maximum recursion depth exceeded
。此外,如果您使用命令nohup.out
运行控制器,则会为您提供nohup python converter.py
文件,您可以在其中查看错误处理的任何问题。
我希望我可以帮助任何遇到同样问题的人。
答案 1 :(得分:0)
除此之外,还可以使用子进程检查等等:
def check_mail_loop():
imap = imaplib.IMAP4(hst)
# Build some function to login, and, in the event of an error, sleep for n seconds and call login function again.
imap.login(usr, pwd)
while True:
try:
imap.select("Inbox")
result, data = imap.uid('search', None, "ALL")
if result and data:
latest = data[0].split()[-1]
result, data = imap.uid('fetch', latest, '(RFC822)')
raw = data[0][1] # This contains the Mail Data
msg = email.message_from_string(raw)
time.sleep(5)
except SomeRelevantException as e:
logging.log(e)
time.sleep(60)
pass
如果您没有预见到某些随机错误,请使用过程控制管理器,例如supervisord或monit。