Pull to refresh

Comments 6

Супер интересно. Спасибо!

Насколько я помню, в корутинах (а точнее, их реализации через генераторы) идёт возвращение значения из цикла. В псевдокоде это что-то типа:

res = task.send(None)

while not finished:
  res = tasl.send(res)

return res

В step я такого не увидел. Я так понимаю, там всегда создаётся новая таска и она либо выполняется, либо нет.

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

Спасибо за комментарий!

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

По поводу send(res). Тут есть тонкость. В asyncio Task.__step всегда вызывает coro.send(None), а не coro.send(result) (соответствующий фрагмент кода есть в статье). Когда таска останавливается на await future, она подписывает свой метод __wakeup на завершение этого фьючера через add_done_callback() и засыпает. Дальше инициатива переходит к фьючеру: когда он завершается, он сам обходит свои коллбэки и через call_soon() закидывает вызов __wakeup тасок, которые подписались на этот фьючер, в очередь цикла событий. Цикл вызывает __wakeup таски, тот вызывает __step и таска продолжает выполнение с того места, где остановилась, вызывая у корутины все тот же coro.send(None). Результат завершившегося фьючера корутина получает не через аргумент send(), а через return self.result() внутри Future.__await__ при возобновлении. Поэтому новая таска при каждом шаге не создается, одна и та же таска просто двигает выполнение корутины от одного авайта фьючера к другому авайту.

Отличные статьи. Продолжайте пожалуйста. Очень бы хотелось почитать статью про взаимодействие сервер + фреймворк (про реализацию ASGI)

Статья супер, спасибо!

Sign up to leave a comment.

Articles