Отключение nagle в python: как это сделать правильно?

Мне нужно отключить алгоритм Nagle в Python2.6. Я обнаружил, что исправление HTTPConnection в httplib.py таким образом

    def connect(self):
        """Connect to the host and port specified in __init__."""
        self.sock = socket.create_connection((self.host,self.port),
                                         self.timeout)
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) # added line

делает трюк.

Очевидно, что я хотел бы избежать исправления системной библиотеки, если это возможно. Итак, вопрос в том, как правильно сделать такую ​​вещь? (Я довольно новичок в Python и могу легко пропустить какое-то очевидное решение здесь)

2 ответа

Решение

Невозможно изменить параметры сокета, которые httplib указывает, и невозможно также передать свой собственный объект сокета. По моему мнению, такая нехватка гибкости является самой большой слабостью большинства библиотек Python HTTP. Например, до Python 2.6 было даже невозможно указать тайм-аут для соединения (за исключением глобального использования socket.setdefaulttimeout(), которое было не очень чистым).

Если вы не возражаете против внешних зависимостей, похоже, что httplib2 уже имеет TCP_NODELAY указано.

Вы могли бы обезьяна-патч библиотеки. Поскольку python является динамическим языком и более или менее все выполняется как поиск пространства имен во время выполнения, вы можете просто заменить соответствующий метод в соответствующем классе:

:::python
import httplib

def patch_httplib():
    orig_connect = httplib.HTTPConnection.connect
    def my_connect(self):
        orig_connect(self)
        self.sock.setsockopt(...)

Однако это чрезвычайно подвержено ошибкам, так как это означает, что ваш код становится достаточно специфичным для конкретной версии Python, так как эти библиотечные функции и классы меняются. Например, в 2.7 есть _tunnel() метод, который использует сокет, так что вы хотите подключить в середине connect() метод - обезьяна-исправление делает это чрезвычайно хитрым.

Короче говоря, я не думаю, что есть простой ответ, я боюсь.

Обратите внимание, что если вы используете библиотеку сокетов напрямую, достаточно следующего:

self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)

Я прилагаю эту информацию к принятому ответу, потому что он удовлетворяет потребность в информации, которая привела меня сюда.

Другие вопросы по тегам