tokio::select! сожрал нам данные в проде — cancellation safety это мина

Теги: #Rust
Рейтинг: 45.7% · 101 голосов
Python, Rust, Go, C++, C#, Java, Kotlin: синтаксис, паттерны проектирования, производительность, многопоточность и сравнение языков.
Аватара пользователя
jsrust8863
Сообщения: 2
Зарегистрирован: Ср май 20, 2026 6:03 pm

tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение jsrust8863 »

Поймали жёсткий баг: select! отменил ветку с buf.read() на середине, часть байт уже была вычитана из сокета и просто потерялась. Сообщения бились раз в пару часов под нагрузкой. Rust safe, ага, память не текла — данные текли.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
arseny9906
Сообщения: 20
Зарегистрирован: Пн май 11, 2026 11:59 am

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение arseny9906 »

Классика. read() в tokio cancellation-safe, а вот read_exact и многие комбинаторы — нет. Если фьюча отменяется между await-точками, всё что она держала в стеке (промежуточный буфер) уходит в небытие. В доке tokio про это есть, но кто её читает.
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
pynode5808
Сообщения: 31
Зарегистрирован: Пн май 11, 2026 4:55 pm

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение pynode5808 »

alex_dev в том и дело что read() сам по себе safe, а у нас был кастомный декодер поверх, который копил в свой буфер и await-ил внутри. Вот он и не safe оказался.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
nastya6941
Сообщения: 2
Зарегистрирован: Чт май 14, 2026 2:42 am

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение nastya6941 »

Вот за это я и недолюбливаю async Rust. "Безопасность" компилятора заканчивается ровно там где начинается логика отмены, и тут ты сам по себе как в C. Никакой borrow checker тебе тут не друг.
👍1 ❤️1 🔥 😄1 🤔
Аватара пользователя
sasha_py52
Сообщения: 10
Зарегистрирован: Пн май 11, 2026 6:50 pm

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение sasha_py52 »

Решение — не держать состояние в локалках фьючи которая может быть отменена. Всё что должно пережить отмену выносишь наружу select!, либо используешь tokio_util::codec::Framed который cancellation-safe by design. Мы так и сделали, баг ушёл.
👍 ❤️ 🔥1 😄 🤔
Аватара пользователя
roman_js5
Сообщения: 26
Зарегистрирован: Пн май 11, 2026 12:17 am

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение roman_js5 »

Дмитрий_К да, в итоге переехали на Framed + LinesCodec и забыли как страшный сон. Но осадочек что наступил на это в проде, а не в тестах, остался.
👍1 ❤️ 🔥 😄 🤔2
Аватара пользователя
liza_go
Сообщения: 11
Зарегистрирован: Чт май 14, 2026 10:05 pm

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение liza_go »

А воспроизвести в тестах такое почти нереально, это же гонка по таймингу отмены. Нужен loom или ручной детерминированный планировщик. Кто-нибудь реально тестит cancellation safety автоматически?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
oleg_linux
Сообщения: 9
Зарегистрирован: Вт май 12, 2026 12:32 am

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение oleg_linux »

perf_freak loom для этого и есть, но он про потоки/atomics, а не про async cancellation напрямую. Для отмены народ пишет руками тесты с tokio::time + abort в конкретный момент. Боль.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
kolya_flux
Сообщения: 11
Зарегистрирован: Вт май 12, 2026 2:59 am

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение kolya_flux »

Кстати это ещё и вектор атаки в некоторых протоколах — если злоумышленник может спровоцировать таймаут-отмену в нужный момент, рассинхрон стрима бывает эксплуатируемым. Видел CVE по похожему паттерну.
👍1 ❤️ 🔥2 😄 🤔
Аватара пользователя
codelinux601
Сообщения: 33
Зарегистрирован: Вс май 10, 2026 11:57 pm

Re: tokio::select! сожрал нам данные в проде — cancellation safety это мина

Сообщение codelinux601 »

А в Go контекст отменяется, горутина видит ctx.Done() и сама решает докатать чтение или нет. Никто за тебя стек не дропает. Иногда явность это и есть безопасность.
👍1 ❤️ 🔥 😄 🤔
Ответить
Поделиться темой: ✈ Telegram VK
Похожие запросы: как работает borrow checker в rust

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость