2016-02-26 60 views
1

我想替換Cron作業來「保持」我的程序,因爲它會調用每隔XX個時間間隔是否已經調用腳本,從而創建重複條目。無限運行服務器端python腳本?

我調查了這個問題,並有幾種方法。一個是修改我的程序,以便檢查它是否已被調用並自行關閉。我就一前一後是完全的cronjob由自稱一遍又一遍地用execfile其取下它的工作原理正是我想除了以下問題: RuntimeError: maximum recursion depth exceeded

有沒有辦法讓程序在「無限循環「沒有得到堆棧溢出?

這是我的代碼,它是一個檢查郵件的程序,並將它們轉換成MySQL數據庫條目。

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

我不明白你爲什麼如果沒有郵件發出異常,然後重新啓動腳本。你爲什麼不檢查新的電子郵件,然後只處理郵件,如果「結果」和「數據」不爲空?如果你想永遠運行,一個簡單的'while True'檢查可能的數據結果就足夠了。如果你想要某種腳本管理,你可以使用supervisord來確保你的腳本正在運行,並且如果它碰巧碰到了一個無法預料的錯誤,就會重新啓動。 – antikantian

+0

由於人們正在使用該收件箱,因此無法檢查新郵件,我每天收到超過20種不同類型的郵件進入該收件箱+/- 2000,並且必須檢查每個單一郵件,如果這是我必須處理的事情。上面的腳本只是一小部分,腳本是如何開始的,應該在腳本完成後結束。基本上有很多東西我必須檢查低谷,然後將條目寫入MySQLdb。我知道我的做法很勉強,但我必須從某個地方開始。 –

回答

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 python converter.py運行控制器,則會爲您提供一個nohup.out文件,您可以在其中看到有關錯誤處理的任何問題。

我希望我能幫助任何人遇到同樣的問題。

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。