[英]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.