Возможное решение: http://groups.google.com/group/django-users/browse_thread/thread/2c7421cdb9b99e48
До недавнего времени мне было любопытно проверить
это на Джанго 1.1.1. Будет ли это
исключение быть брошенным снова ... сюрприз,
там это было снова. Это заняло у меня немного
время отладки, полезный совет был
что он показывает только когда (предварительно) разветвление.
Так что для тех, кто получает случайно
эти исключения, я могу сказать ... исправить
твой код :) окей .. серьезно, там
всегда есть несколько способов сделать это, так
позвольте мне объяснить, где находится
проблема первая. Если вы получаете доступ к базе данных
когда любой из ваших модулей будет импортировать
как, например, чтение конфигурации из
базы данных, то вы получите эту ошибку.
Когда ваше приложение fastcgi-prefork
запускается, сначала он импортирует все модули,
и только после этого раздваивает детей.
Если вы установили соединение БД
во время импорта все дочерние процессы
будет иметь точную копию этого
объект. Эта связь в настоящее время
закрыто в конце фазы запроса
(сигнал запроса завершен). Итак, сначала
ребенок, который будет призван к процессу
ваш запрос, закроет это
подключение. Но что будет с
остальные дочерние процессы? Oни
будет верить, что у них есть открытый и
предположительно рабочая связь с
дБ, поэтому любая операция дБ вызовет
исключение. Почему это не отображается в
модель исполнения с резьбой? Я полагаю
потому что потоки используют один и тот же объект
и знать, когда любой другой поток
закрытие соединения. Как это исправить?
Лучший способ исправить ваш код ... но
это может быть сложно иногда.
Другой вариант, на мой взгляд довольно
чистый, это написать где-то в вашем
небольшой кусочек кода приложения:
from django.db import connection
from django.core import signals
def close_connection(**kwargs):
connection.close()
signals.request_started.connect(close_connection)
Не идеальная мысль, в лучшем случае обход дважды - это обходной путь.
Возможное решение: использование пула соединений (pgpool, pgbouncer), чтобы у вас были соединения и стабильность соединений с БД, и они быстро передавались вашим демонам FCGI.
Проблема в том, что это вызывает другую ошибку, psycopg2 вызывает InterfaceError , потому что он пытается отключиться дважды (pgbouncer уже обработал это).
Теперь виновником является сигнал Django request_finished , запускающий connection.close () и вызывающий сбои, даже если он уже был отключен. Я не думаю, что такое поведение желательно, так как если запрос уже завершен, нас больше не заботит соединение с БД. Патч для исправления этого должен быть простым.
Соответствующая трассировка:
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/core/handlers/wsgi.py in __call__(self=<django.core.handlers.wsgi.WSGIHandler object at 0x24fb210>, environ={'AUTH_TYPE': 'Basic', 'DOCUMENT_ROOT': '/storage/test', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTPS': 'off', 'HTTP_ACCEPT': 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_AUTHORIZATION': 'Basic dGVzdGU6c3VjZXNzbw==', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': '__utma=175602209.1371964931.1269354495.126938948...none); sessionid=a1990f0d8d32c78a285489586c510e8c', 'HTTP_HOST': 'www.rede-colibri.com', ...}, start_response=<function start_response at 0x24f87d0>)
246 response = self.apply_response_fixes(request, response)
247 finally:
248 signals.request_finished.send(sender=self.__class__)
249
250 try:
global signals = <module 'django.core.signals' from '/usr/local/l.../Django-1.1.1-py2.6.egg/django/core/signals.pyc'>, signals.request_finished = <django.dispatch.dispatcher.Signal object at 0x1975710>, signals.request_finished.send = <bound method Signal.send of <django.dispatch.dispatcher.Signal object at 0x1975710>>, sender undefined, self = <django.core.handlers.wsgi.WSGIHandler object at 0x24fb210>, self.__class__ = <class 'django.core.handlers.wsgi.WSGIHandler'>
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/dispatch/dispatcher.py in send(self=<django.dispatch.dispatcher.Signal object at 0x1975710>, sender=<class 'django.core.handlers.wsgi.WSGIHandler'>, **named={})
164
165 for receiver in self._live_receivers(_make_id(sender)):
166 response = receiver(signal=self, sender=sender, **named)
167 responses.append((receiver, response))
168 return responses
response undefined, receiver = <function close_connection at 0x197b050>, signal undefined, self = <django.dispatch.dispatcher.Signal object at 0x1975710>, sender = <class 'django.core.handlers.wsgi.WSGIHandler'>, named = {}
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/__init__.py in close_connection(**kwargs={'sender': <class 'django.core.handlers.wsgi.WSGIHandler'>, 'signal': <django.dispatch.dispatcher.Signal object at 0x1975710>})
63 # when a Django request is finished.
64 def close_connection(**kwargs):
65 connection.close()
66 signals.request_finished.connect(close_connection)
67
global connection = <django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>, connection.close = <bound method DatabaseWrapper.close of <django.d...ycopg2.base.DatabaseWrapper object at 0x17b14c8>>
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/backends/__init__.py in close(self=<django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>)
74 def close(self):
75 if self.connection is not None:
76 self.connection.close()
77 self.connection = None
78
self = <django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>, self.connection = <connection object at 0x1f80870; dsn: 'dbname=co...st=127.0.0.1 port=6432 user=postgres', closed: 2>, self.connection.close = <built-in method close of psycopg2._psycopg.connection object at 0x1f80870>
Обработка исключений здесь может добавить больше снисхождения:
/ USR / местные / Библиотека / python2.6 / Расс-пакеты / Django-1.1.1-py2.6.egg / Джанго / дб / __ __ INIT. Ру
63 # when a Django request is finished.
64 def close_connection(**kwargs):
65 connection.close()
66 signals.request_finished.connect(close_connection)
Или это может быть лучше обработано на psycopg2, чтобы не выдавать фатальные ошибки, если все, что мы пытаемся сделать, это отключиться, и это уже так:
/ USR / местные / Библиотека / python2.6 / Расс-пакеты / Django-1.1.1-py2.6.egg / Джанго / дб / бэкэнды / __ __ INIT. Ру
74 def close(self):
75 if self.connection is not None:
76 self.connection.close()
77 self.connection = None
Кроме этого, у меня мало идей.