2014-01-23 98 views
2

我正在做一些基本的東西WSGI:WSGI - 處理客戶端超時

def application(environ, start_response): 
    start_response("200", []) 
    result = some_long_func() 
    return [result] 

它時有發生的時間之前完成some_long_func,我看到我的日誌下面的客戶端斷開連接:

SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected)... 

有沒有辦法在應用程序級別處理斷開的客戶端,即在application()返回之前?

我的服務器是uwsgi(獨立的)。沒有框架,只是純粹的Python。

+0

沒有線索。但我很想知道。 –

+0

你應該澄清你的意思是「處理」一個斷開連接的客戶端。如果你想忽略它,你可以用uWSGI選項來實現,如果你想要確保在請求結束時執行代碼,只需使用WSGI close()方法。 – roberto

+0

@roberto:我想在斷開連接時採取一些特定於應用程序的操作,例如將錯誤記錄到數據庫中,發送郵件等。 – georg

回答

1

如果應用程序返回的迭代有一個close()方法,服務器或網關必須在當前請求完成後調用該方法,無論是請求正常完成,或者由於錯誤提前終止。

因此,如果在輸出迭代器完成之前調用close(),則知道客戶端已斷開連接。

+0

謝謝!這看起來像一個可行的解決方案。 – georg

1

不。在WSGI規範的範圍內,沒有辦法處理這個。在mod_wsgi郵件列表上進行搜索討論。一個這樣的討論:

+0

我很困惑。在那裏引用你自己的回覆:「......當檢測到連接關閉時,應用程序將看到一個Python異常,並且該如何處理它取決於它」 - 這正是我所需要的。 – georg

+0

隨着代碼寫入的方式,您不會看到它並能夠處理它,因爲您沒有使用write()可調用(您不應該這樣做),而是以可迭代的字符串形式返回。因此,它只會成爲WSGI服務器,它會看到斷開連接的異常,並因此通常只記錄一些內容。考慮到使用write()回調是不好的做法,唯一一次在代碼中會看到異常的情況是,如果在發生斷開連接時從wsgi.input中讀取數據塊時發生阻塞。 –

+0

我明白了。我認爲在返回ping客戶端之前,嘗試寫入(「」),除了...之外,如果中斷,記錄異常並返回任何內容,否則返回通常的迭代。這是一個愚蠢的想法? – georg