⏰ Хватит дергать: Waker и паттерн пейджера
Окей, Future вернула управление (сказала Poll::Pending). Но как рантайм узнает, что данные по сети пришли и пора снова вызвать poll()? Если он будет постоянно опрашивать все Future в цикле (while loop), ваш CPU улетит в космос на 100% загрузке.
Здесь на сцену выходят Executor, Reactor и Waker.
• Executor - это менеджер задач. Он берет Future и вызывает у нее poll().
• Reactor - это слушатель ОС (обертка над epoll в Linux, kqueue в macOS или IOCP в Windows). Он ждет событий от сетевой карты или диска.
• Waker - это тот самый пейджер, который выдают в бургерной.
Как это работает:
1. Future делает сетевой запрос и понимает, что данных еще нет.
2. Она регистрирует этот запрос в Reactor и отдает ему свой Waker (колбэк, в котором зашит ID этой Future).
3. Future возвращает Pending. Executor забывает про неё и идет выполнять другие задачи.
4. ...проходит время... Сетевая карта получает пакеты. ОС дергает epoll.
5. Reactor видит: "Ага, пришли данные для сокета X". Он берет Waker, привязанный к этому сокету, и вызывает waker.wake().
6. Waker сигнализирует Executor'у: "Задача #42 готова, помести её обратно в очередь на выполнение".
7. Executor снова вызывает poll(), и стейт-машина делает следующий шаг.
Никакого холостого хода CPU. Только чистая событийная архитектура.
#rust #async #waker #tokio #epoll
👉 Мы в MAX max.ru/channel_rust_lib
👉 Мы в Telegram t.me/rust_lib
👉 Мы в VK vk.com/rust_lib