twisted: бесполезная ошибка "AlreadyCalled" - PullRequest
5 голосов
/ 28 сентября 2010

Моя искаженная программа на Python постоянно выдает это сообщение:

Unhandled error in Deferred:

Traceback (most recent call last):
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 757, in gotResult
    _inlineCallbacks(r, g, deferred)
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 747, in _inlineCallbacks
    deferred.errback()
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 269, in errback
    self._startRunCallbacks(fail)
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 312, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 328, in _runCallbacks
    self.result = callback(self.result, *args, **kw)
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 243, in callback
    self._startRunCallbacks(result)
  File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 298, in _startRunCallbacks
    raise AlreadyCalledError
twisted.internet.defer.AlreadyCalledError:

Это не слишком полезно, поскольку не имеет ссылки на мой исходный код ... Я также использую defer.inlineCallbacks,Есть идеи, что могло пойти не так?

Ответы [ 2 ]

7 голосов
/ 28 сентября 2010

Если у вас нет других подсказок о том, что идет не так (например, ваши юнит-тесты указывают на конкретные случаи, которые вызывают это, или если ответ pyfunc не дает понять, почему это происходит), тогда включите отложенную отладкучтобы получить информацию о том, где указывается первый (и только разрешенный) результат Отложенного:

from twisted.internet import defer
defer.setDebugging(True)

Или

twistd --debug [...]

Или

trial --debug [...]

ВыВы получите дополнительные трассировки стека с отчетами об ошибках, подобных тому, с которым вы столкнулись.Дополнительные трассировки стека сообщат вам, где был создан рассматриваемый Отложенный и где он был впервые вызван (если к нему были вызваны .callback () или .errback ()).

Поскольку вы используете inlineCallbacksвы не получите хорошую трассировку стека о том, где происходит настоящая ошибка, но информация о том, где Отложенный запускается впервые, может дать вам подсказку о том, откуда может последовать активация.

К сожалению,Добавленная неизвестность - это просто стоимость использования inlineCallbacks на данный момент.Это, вероятно, преодолимо, но кто-то должен взять на себя эту задачу.

2 голосов
/ 28 сентября 2010

Я предполагаю, что где-то в вашем коде вы явно вызываете функцию обратного вызова deferred.Это также происходит несколько раз.Отложенный обратный вызов может быть запущен только один раз, что указывает на завершение долгожданной задачи, приводящей к ошибке или положительному результату.В Twisted есть механизм для выдачи вышеуказанного исключения, если вы пытались запустить отложенное несколько раз.

Рассмотрите следующий код:

from twisted.internet.defer import Deferred
def func(x): print x
d = Deferred()
d.addCallbacks(func, func)
d.callback('First fire')
d.callback('Second fire')

Это приведет к следующей ошибке:

    raise AlreadyCalledError
twisted.internet.defer.AlreadyCalledError

Проверьте в своем коде возможность такого многократного запуска.Это может быть проблемой.

...