2015-04-20 29 views
7

我有一個在Apache HTTPD後面運行的Flask應用程序。 Apache被配置爲擁有多個子進程。如何在Apache終止Flask進程時調用函數?

燒瓶應用程序創建了文件的名稱等於其進程ID在服務器上的文件。 代碼看起來是這樣的:

import os 

@app.before_first_request 
def before_first_request(): 
    filename = os.getpid() 
    with open(filename, 'w') as file: 
     file.write('Hello') 

當子進程被終止/結束/終止我想瓶應用刪除此文件。

這是不是非常重要的是移除文件的情況發生,因爲這些文件不會佔用太多的空間,因此,如果出現離奇失誤,我不需要處理它們。但是對於正常的工作流程,我希望在Apache關閉Flask進程時進行一些清理。

上做到這一點的最好方法你知道嗎?

回答

6

正常結束服務器控制的Python進程(例如在Apache WSGI上下文中運行的Flask應用程序,甚至更好,在Apache後面的Gunicorn)之前添加清理功能的最佳方法是使用atexit退出處理程序。

在闡述你的原來的例子,這裏的另外的退出處理做.pid文件的清理:

import atexit 
import os 

filename = '{}.pid'.format(os.getpid()) 

@app.before_first_request 
def before_first_request(): 
    with open(filename, 'w') as file: 
     file.write('Hello') 

def cleanup(): 
    try: 
     os.remove(filename) 
    except Exception: 
     pass 

atexit.register(cleanup) 
+1

阿帕奇/ mod_wsgi的肯定總是試圖確保的atexit回調調用,即使在情況下,過程由於諸如請求超時等條件而不得不關閉。在gunicorn中沒有這麼好的保證,你必須更加小心地使用gunicorn下的atexit作爲它不會被調用的各種情況。在任何情況下,您都不應該依賴它,並且應用程序應該對後續運行中存在的文件具有彈性(如果它不應存在)。一個單獨的任務來刪除可能需要的其他答案描述。 –

+0

對於其他WSGI服務器,atexit回調甚至可能根本不會被調用。我相信uWSGI的情況仍然如此,除非你強迫它使用單個解釋器,因爲它沒有采取措施確保在子解釋器中調用回調函數。由於Python不會在子解釋器中調用atexit回調函數,並且Apache/mod_wsgi正在使用特殊技巧來確保它們是必需的,所以必須採取特殊步驟。 –

+0

更多信息@GrahamDumpleton!感謝你,以及os.remove'調用的異常警衛。 –

2

最簡單的方法是處理此Apache進程之外。有沒有保證的方式,該進程將永遠刪除文件(例如,如果你重新啓動Apache中間請求)。

我已經採取了在過去的方法是使用cron。在你的倉庫的某個地方寫一個小腳本,並按計劃執行(通常每天都有效)。該腳本可以清除24小時以內的所有文件,因此您始終可以獲得1天價值的文件滾動窗口。

這有兩個好處:

  1. 你在腳本的總量控制,並可以使用任何你想要的語言。
  2. 你可以做花哨的東西用這些文件。您可以壓縮它們並將它們存儲在別處,刪除它們或對它們執行分析。完全取決於你!

大多數腳本語言有一個小包裝類,可用於使cron更友好。紅寶石的流行之一是whenever

相關問題