微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – gevent和posgres:异步连接失败

我正在使用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-safe?还有什么我想念的吗?

解决方法:

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

All the connections are stored in 07001, which is
the instance of 07002. Every time ORM
is about to issue a query, it requests a DB connection by calling
connections[‘default’]. In turn, ConnectionHandler.__getattr__ checks if there is a connection in
07003, and creates a new one if it is
empty.

All opened connections should be closed after use. There is a signal
07004, which is run by
07005. Django closes DB connections
at the very last moment, when nobody Could use it anymore – and it
seems reasonable.

Yet there is tricky part about how ConnectionHandler stores DB
connections. It uses 07006, which becomes
07007 after monkeypatching. Declared once, this
structure works just as it was unique at every greenlet. Controller
*some_view* started its work in one greenlet, and Now we’ve got a connection in *ConnectionHandler._connections*. Then we create few
more greenlets and which get an empty
*ConnectionHandlers._connections*, and they’ve got connectinos from pool. After new greenlets done, the content of their local() is gone,
and DB connections gone withe them without being returned to pool. At
some moment, pool becomes empty

Developing Django+gevent you should always keep that in mind and close
the DB connection by calling 07008. It
should be called at exception as well, you can use a decorator for
that, something like:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐