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
上一篇:python 基础(五)协程 —— 微线程 greenlet gevent


下一篇:python之路---协程