Реализация длительных асинхронных операций синхронным способом

#python #asynchronous

#python #асинхронный

Вопрос:

Мне нужно реализовать функцию, которая включает в себя длительную асинхронную операцию (отправлять запрос на внешний сервер и периодически проверять, выполнено ли это), которая должна вести себя как синхронная операция. Я делаю это следующим образом:

 start_long_operation()
while True:
  if operation_finished():
    return
  sleep()  
  

Интересно, приемлемо ли это и есть ли лучшее решение?

Комментарии:

1. На самом деле не понимаю, почему вы используете while True: with a separate if вместо того, чтобы просто помещать условие в while цикл, но в остальном все выглядит нормально.

Ответ №1:

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

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

Ответ №2:

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

Затем вы можете сделать так, чтобы операции синхронизации отображались асинхронно в вашем локальном цикле событий, используя несколько потоков управления (потоки, процессы, FSM на основе выбора, что угодно). Если у вас нет контроля над внешним протоколом, и он действительно асинхронный, тогда у вас нет выбора, кроме как опрашивать. В зависимости от того, каким, по вашему мнению, будет распределение времени отклика, я бы использовал какое-то экспоненциальное отклонение с ограничением на период опроса. Для большинства программ у меня было бы это внешнее по отношению к моему основному циклу событий, и оно сообщало бы об этом через какой-либо механизм событий моему циклу событий.