我正在使用 gevent 处理基于 Django 的 Web 系统上的 API I/O。
我已经使用以下方法进行了猴子补丁:
import gevent.monkey; gevent.monkey.patch_socket()
我已经使用以下方法修补了psychopg:
import psycogreen; psycogreen.gevent.patch_psycopg()
尽管如此,某些 Django 调用 Model.save() 失败并出现错误:“异步连接失败”。我需要做其他事情才能使 postgres greenlet 在 Django 环境中安全吗?我还缺少其他东西吗?
有一个article http://habrahabr.ru/post/174717/关于这个问题,不幸的是它是俄语的。让我引用最后一部分:
所有连接都存储在django.db.connections https://github.com/django/django/blob/1.5c2/django/db/__init__.py#L14,即
的实例django.db.utils.ConnectionHandler https://github.com/django/django/blob/1.5c2/django/db/utils.py#L55。每次ORM
即将发出查询,它通过调用请求数据库连接连接['默认']。反过来,ConnectionHandler.__getattr__检查是否有连接ConnectionHandler._connections https://github.com/django/django/blob/1.5c2/django/db/utils.py#L65,如果是则创建一个新的
空的。
使用后应关闭所有打开的连接。有信号请求完成 https://github.com/django/django/blob/1.5c2/django/db/__init__.py#L53,其运行者为django.http.HttpResponseBase.close https://github.com/django/django/blob/1.5c2/django/http/response.py#L230。 Django 关闭数据库连接
在最后一刻,当没有人可以再使用它时 - 而它
看起来很合理。
然而,ConnectionHandler 如何存储数据库有一个棘手的部分
连接。它用线程.local http://docs.python.org/2/library/threading.html#threading.local,这变成gevent.local.local http://gevent.org/gevent.local.html猴子补丁后。声明一次,这
结构的运作就像每个小绿地都是独一无二的一样。控制器
*some_view* 在一个 greenlet 中开始工作,现在我们在 *ConnectionHandler._connections* 中有一个连接。然后我们创建几个
更多的小绿地,其中空了
*ConnectionHandlers._connections*,并且他们从池中获得了连接。新的 greenlet 完成后,其 local() 的内容就消失了,
数据库连接也随之消失,没有返回到池中。在
某个时刻,池子变空了
开发 Django+gevent 你应该时刻牢记这一点并关闭
通过调用数据库连接django.db.close_connection https://github.com/django/django/blob/1.5c2/django/db/__init__.py#L44。它
也应该在异常时调用,您可以使用装饰器
那个,比如:
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)