簡體   English   中英

gevent和posgres:異步連接失敗

[英]gevent and posgres: Asynchronous connection failed

我正在使用gevent在基於Django的Web系統上處理API I / O。

我用以下方法修補了猴子:

import gevent.monkey; gevent.monkey.patch_socket()

我使用以下方法修補了psychopg:

import psycogreen; psycogreen.gevent.patch_psycopg()

但是,某些Django調用使Model.save()失敗並顯示以下錯誤:“異步連接失敗”。 在Django環境中,我還需要做些其他的事情來使postgres綠色安全嗎? 還有其他我想念的東西嗎?

一篇關於這個問題的文章 ,不幸的是它是俄語的。 讓我引用最后一部分:

所有連接都存儲在django.db.utils.ConnectionHandler的實例django.db.connections中 每次ORM即將發出查詢時,它都會通過調用connections ['default']來請求數據庫連接。 反過來, ConnectionHandler .__ getattr__檢查ConnectionHandler._connections中是否存在連接 ,如果連接為空,則創建一個新連接

使用后應關閉所有打開的連接。 有一個信號request_finished ,它由django.http.HttpResponseBase.close運行。 Django在沒有人可以使用的最后時刻關閉數據庫連接-這似乎是合理的。

但是,關於ConnectionHandler如何存儲數據庫連接還有一些棘手的部分。 它使用threading.local ,在monkeypatching之后變為gevent.local.local。 曾經聲明過,這種結構的工作原理就像每個綠色小部件都是唯一的一樣。 控制器* some_view *在一個greenlet中開始工作,現在我們在* ConnectionHandler._connections *中有了一個連接。 然后我們再創建幾個greenlet,它們會得到一個空的* ConnectionHandlers._connections *,並且它們已經從池中獲得了connectinos。 完成新的Greenlet之后,其local()的內容將消失,並且數據庫連接也將隨之消失,而不會返回到池中。 在某一時刻,池變空

開發Django + gevent時,應始終牢記這一點,並通過調用django.db.close_connection關閉數據庫連接。 也應該在異常處調用它,您可以為此使用裝飾器,例如:

class autoclose(object):
    def __init__(self, f=None):
        self.f = f

    def __call__(self, *args, **kwargs):
        with self:
            return self.f(*args, **kwargs)

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_info, tb):
        from django.db import close_connection
        close_connection()
        return exc_type is None

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM