Почему asyncio.StreamWriter.drain должен вызываться явно?Python

Программы на Python
Ответить
Anonymous
 Почему asyncio.StreamWriter.drain должен вызываться явно?

Сообщение Anonymous »

Из документа:

write(data)

Код: Выделить всё

Write data to the stream.

This method is not subject to flow control. Calls to write() should be followed by drain().
сопрограмма дренаж()

Код: Выделить всё

Wait until it is appropriate to resume writing to the stream. Example:

writer.write(data)
await writer.drain()
Насколько я понимаю,
  • Вам нужно вызвать дренаж каждый раз, когда вызывается write.
  • Если нет, то write заблокирует поток цикла
Тогда почему write не является сопрограммой, которая вызывает ее автоматически? Зачем одному вызову писать без необходимости слива? Я могу вспомнить два случая.
  • Вы хотите написать и закрыть немедленно
  • Вам необходимо буферизовать некоторые данные до того, как сообщение будет завершено.
Первый случай — особый случай, я думаю, у нас может быть другой API. Буферизация должна обрабатываться внутри функции записи, и приложению это не важно.

Позвольте мне поставить вопрос по-другому. В чем недостаток этого действия? Эффективно ли это делает версия python3.8?

Код: Выделить всё

async def awrite(writer, data):
writer.write(data)
await writer.drain()
Примечание: в документе дренажа прямо указано следующее:

Когда ждать нечего, дренаж() возвращается немедленно.


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

Код: Выделить всё

def write(data):
remaining = socket.try_write(data)
if remaining:
_pendingbuffer.append(remaining) # Buffer will keep growing if other side is slow and we have a lot of data

async def drain():
if len(_pendingbuffer) < BUF_LIMIT:
return
await wait_until_other_side_is_up_to_speed()
assert len(_pendingbuffer) < BUF_LIMIT

async def awrite(writer, data):
writer.write(data)
await writer.drain()
Итак, когда что использовать:
  • Когда данные не являются непрерывными, например, в ответ на HTTP-запрос. Нам просто нужно отправить некоторые данные, и нас не волнует, когда они будут достигнуты, а память не имеет значения. Просто используйте write
  • То же, что и выше, но память вызывает беспокойство. , используйте awrite
  • При потоковой передаче данных большому количеству клиентов (например, прямой эфир или огромный файл). Если данные дублируются в каждом из буферов соединения, это обязательно приведет к переполнению оперативной памяти. В этом случае напишите цикл, который принимает фрагмент данных на каждой итерации, и вызовите awrite. В случае огромного файла лучше использовать циклический файл loop.sendfile, если он доступен.


Подробнее здесь: https://stackoverflow.com/questions/537 ... tly-called
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»