【问题标题】:gevent and posgres: Asynchronous connection failedgevent 和 posgres:异步连接失败
【发布时间】:2013-07-07 17:48:52
【问题描述】:

我正在使用 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 greenlet 安全?我还缺少什么吗?

【问题讨论】:

    标签: python django postgresql gevent


    【解决方案1】:

    在这个问题上有一个article,不幸的是它是俄语的。让我引用最后一部分:

    所有连接都存储在django.db.connections,即 django.db.utils.ConnectionHandler 的实例。每次ORM 即将发出查询,它通过调用请求数据库连接 连接['default']。反过来,ConnectionHandler.__getattr__ 检查是否存在连接 ConnectionHandler._connections,如果是则创建一个新的 空。

    所有打开的连接都应该在使用后关闭。有信号 request_finished,由 django.http.HttpResponseBase.close。 Django 关闭数据库连接 在最后一刻,没有人可以再使用它了——而且它 看起来很合理。

    然而,关于 ConnectionHandler 如何存储数据库有一个棘手的部分 连接。它使用threading.local,变成 gevent.local.local 猴子补丁后。声明过一次,这 结构的工作原理就像它在每个绿地都是独一无二的。控制器 *some_view* 在一个 greenlet 中开始工作,现在我们在 *ConnectionHandler._connections* 中建立了一个连接。然后我们创建几个 更多的绿色植物,其中空无一物 *ConnectionHandlers._connections*,他们从池中获得了连接。在新的greenlets完成后,他们的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
    

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多