До вмісту
fr0staman
Усі статті

Переписати пет-проєкт на Rust: два роки потому

2 хв читання

У вересні 2021 року я почав телеграм-бота на Python з aiogram — без кращої причини, ніж те, що це здавалося смішним. У серпні 2023-го я переписав його на Rust. Він досі працює, виріс приблизно до 20 000 активних користувачів на добу, а процес тримається біля 1% CPU.

«Ми переписали це на Rust» уже майже окремий жанр, тож скажу конкретно, що саме сталося — включно з тим, що радше свідчить проти такого рішення.

Проблема була не в Python

Спокусливо виправдовувати переписування мовою, з якої ти пішов. Тут це було б нечесно. Бот на Python працював. Він витримував своє навантаження. Більшість того, що приписують зміні мови, насправді пояснюється тим, що ти пишеш ту саму систему вдруге — коли нарешті розумієш вимоги. Це покращило б і Python-версію.

Правдою було вужче твердження: бот обріс поведінкою, яку я вже не наважувався змінювати. Інлайн-запити, гра з окремим станом на кожен чат, дуелі, де стан двох користувачів змінюється одночасно. Нічого екзотичного, але достатньо рухомих частин, щоб необережна правка зіпсувала комусь прогрес, — і жодної системи типів, яка сказала б, що я забув випадок.

Що Rust справді дав

Насамперед — вичерпний перебір варіантів. Компілятор, який відмовляється збирати проєкт, доки не оброблено кожен варіант, виявився функцією, якою я користуюсь найбільше. Додати нову інлайн-дію тепер означає розмову з компілятором про місця, які я проґавив, а не пошук того, що я зламав.

Профіль споживання, про який я перестав думати. Ця частина звучить як реклама Rust, тож наведу чесне число: 20 000 користувачів на добу, близько 1% CPU. Воно виміряне, а не приблизне — бот віддає метрики в Prometheus, і сама ця звичка прийшла з оплачуваної роботи. Практичний ефект не у швидкості, а в тому, що бот ділить сервер з іншими речами й ніколи не стає їхньою проблемою.

Впевненість залишити його в спокої. Справжній ворог пет-проєкту — не продуктивність, а момент, коли ти перестаєш хотіти його відкривати. Те, що код компілюється перед запуском, дозволяє повернутися після трьох місяців перерви й щось змінити, не перечитуючи все спочатку.

Чого це коштувало

Місяці вечорів. І окремий вид рутини: Python-версія колись дійшла до потрібного набору функцій за вихідні, а Rust-версії знадобилося значно більше часу, щоб наздогнати її. Кожну дрібну зручність — надіслати фото, розібрати команду, записати рядок — доводилося шукати заново в менш поблажливій екосистемі.

Для клієнта на таких умовах я б цього не робив. Розрахунок інший, коли витрачаєш власні вечори, а купуєш власну готовність підтримувати це далі.

Що перенеслося

Несподівана віддача виявилася в основній роботі. Rust змінив те, як я читаю код будь-якою іншою мовою, — насамперед те, які стани коду я тепер помічаю як необроблені. Ця звичка повернулася зі мною в TypeScript і, як не дивно, в двадцятирічний Perl, де найцікавіше питання майже завжди звучить так: «а що стається у випадку, який ніхто не описав».

Пет-проєкт виправдовує себе, якщо навчив чогось, що ти забираєш у роботу. За цим критерієм переписування окупилося ще до релізу.

Поділитися