Twisted иногда выбрасывает (казалось бы, не полностью) «максимальная глубина рекурсии превышена» RuntimeError - PullRequest
2 голосов
/ 09 июля 2009

Поскольку функция Twisted getPage не дает мне доступа к заголовкам, мне пришлось написать собственную функцию getPageWithHeaders.

def getPageWithHeaders(contextFactory=None, *args, **kwargs):
    try:
        return _makeGetterFactory(url, HTTPClientFactory,
                                  contextFactory=contextFactory,
                                  *args, **kwargs)
    except:
        traceback.print_exc()

Это в точности то же самое, что и обычная функция getPage, за исключением того, что я добавил блок try / Кроме того, чтобы вернуть фабричный объект, а не фабричный.

По какой-то причине я иногда получаю ошибку превышения максимальной глубины рекурсии здесь. Это происходит последовательно несколько раз из 700, обычно на разных сайтах каждый раз. Кто-нибудь может пролить свет на это? Мне непонятно, почему или как это могло произойти, а база кода Twisted достаточно велика, чтобы я даже не знал, где искать.

РЕДАКТИРОВАТЬ: Вот трассировку, которую я получаю, которая кажется странно неполной:

Traceback (most recent call last):
  File "C:\keep-alive\utility\background.py", line 70, in getPageWithHeaders
    factory = _makeGetterFactory(url, HTTPClientFactory, timeout=60 , contextFactory=context, *args, **kwargs)
  File "c:\Python26\lib\site-packages\twisted\web\client.py", line 449, in _makeGetterFactory
    factory = factoryFactory(url, *args, **kwargs)
  File "c:\Python26\lib\site-packages\twisted\web\client.py", line 248, in __init__
    self.headers = InsensitiveDict(headers)
RuntimeError: maximum recursion depth exceeded

Это полная трассировка, которая явно недостаточно длинна, чтобы превысить нашу максимальную глубину рекурсии. Есть ли что-то еще, что мне нужно сделать, чтобы получить полный стек? У меня никогда не было этой проблемы раньше; как правило, когда я делаю что-то вроде

def f(): return f()
try: f()
except: traceback.print_exc()

тогда я получаю вид "максимальная глубина рекурсии превышена", который вы ожидаете, с кучей ссылок на f()

Ответы [ 3 ]

2 голосов
/ 10 июля 2009

Конкретная обратная связь, на которую вы смотрите, немного загадочна. Вы можете попробовать traceback.print_stack вместо traceback.print_exc, чтобы взглянуть на весь стек над проблемным кодом, а не просто на стек, возвращающийся туда, где перехватывается исключение.

Не видя больше вашей трассировки, я не могу быть уверен, но вы можете столкнуться с проблемой, когда Deferreds вызовет исключение предела рекурсии, если вы объедините слишком много их вместе .

Если вы включите отложенную отладку (from twisted.internet.defer import setDebugging; setDebugging(True)), в некоторых случаях вы можете получить более полезные трассировки, но имейте в виду, что это может также немного замедлить работу вашего сервера.

1 голос
/ 09 июля 2009

Вам следует взглянуть на отслеживаемую трассировку, которую вы получаете, за исключением исключения, которое скажет вам, какие функции (функции) возвращаются слишком глубоко, «ниже» _makeGetterFactory. Скорее всего, вы обнаружите, что ваш собственный getPageWithHeaders участвует в рекурсии именно потому, что вместо правильного возврата отложенного элемента он пытается вернуть фабрику, которая еще не готова. Что произойдет, если вы действительно вернетесь к возврату отложенного?

0 голосов
/ 09 июля 2009

Средство открытия URL, вероятно, следует за бесконечной серией переадресаций 301 или 302.

...