Это ошибка httplib2

моя программа python использует httplib2.Http, чтобы сделать запрос http. Как только мне нужно сгенерировать запрос, я создаю httplib2.Http-объект, так что моя программа будет часто создавать / уничтожать httplib2.Объекты Http.

я обнаружил, что моя программа легко сбой из-за достижения максимального количества открытых файлов. Проверка /proc / / fd, было слишком много открытых сокетов fds. Проблема заставила меня копаться в исходном коде httplib2.

затем я нашел это в httplib2.Http._conn_request метод, был такой код:

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
        break

это показывает, что сокет закрывается только тогда, когда http-метод HEAD. Возможно, httplib2 хотел как-то повторно использовать сокет. Но класс Http не имеет метода close (). Это означает, что когда я делаю Http-запрос, сокет не закроется, пока мой процесс не завершится.

затем я изменил код:

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
                conn.close() # I ADD THIS CLOSE
        break

после этого, моя программа работала хорошо.

но мне все еще интересно, действительно ли это ошибка httplib2, учитывая, что httplib2-очень старый и распространенный lib.

1 ответов


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

путь , Он ждет, пока сервер закроет соединение или для него тайм-аут, он не закрывает их активно (execept on errors). Если соединение было закрыто, httplib2 просто попытается восстановить его при следующем использовании.

закрытие соединения (как и ваш патч к источнику) сделает это невозможно, каждый запрос должен использовать свое собственное соединение.

уничтожение httplib2.Http объект должен автоматически закрывать открытые соединения, поскольку на них ссылаются только в нем connections словарь, так что если вы не держите никаких ссылок на Http объекты, которые вы создали, должны работать. Вы уверены, что у вас нет никаких рекомендаций?

в качестве альтернативы вы можете пройти Connnection: close заголовок к вашему запросу:

http.request("http://example.org", headers={'Connection': 'close'})

это должно вызвать сервер закрыть соединение после каждого запроса. Или вы можете попытаться вручную закрыть все соединения в объекте connections дикт.