Information
- Rating
- Does not participate
- Location
- Москва, Москва и Московская обл., Россия
- Registered
- Activity
Specialization
Бэкенд разработчик, Веб-разработчик
Младший
From 150,000 ₽
Git
Docker
Linux
Python
Английский язык
ООП
Базы данных
Nginx
Высоконагруженные системы
REST
Мощный ресёрч, особенно про
canaryи две копииstdв одном процессе.Есть небольшое уточнение по поводу FFI и
extern "C". Вы пишете, что в 1.81 границу закрыли окончательно и теперь это принудительный abort. Но разве это спасает от ситуации, когда Сишный код, вызванный из Rust, сам бросаетlongjmp(или плюсовый код кидает эксепшен черезextern "C"обратно в раст)? Насколько я помню, Itanium ABI в таких случаях все равно может сломать стек, если на пути окажутся фреймы раст без правильного landing pad. То естьC-unwindобязателен не только для проброса паники наружу, но и для безопасного пролета чужого unwind внутрь раст кода?Идея с self-service отличная, но есть пара инфраструктурных нюансов по реализации:
Под каким пользователем запущен сам фласк? Если сервис работает от
root, чтобы иметь права наos.kill— это очень опасный паттерн для веб-приложения. Гораздо безопаснее запускать сам Flask (через systemd/gunicorn) строго под юзеромhcl. Тогда проверкаif owner != PROCESS_OWNERстановится просто страховкой от ошибок логики — ядро ОС на уровне прав само не даст фласку убить чужие процессы, даже если кто-то подделает запрос.Вы пишете, что выбрали SIGTERM как "менее жесткий вариант". Но если флоучарт реально намертво «завис» (например, случился дедлок или процесс повис на I/O-операциях), он с большой вероятностью просто проигнорирует мягкий SIGTERM, и процесс останется висеть. В таких хелперах обычно реализуют паттерн graceful shutdown: отправляют SIGTERM (у
psutilдля этого есть удобный методproc.terminate()), ждут пару секунд черезproc.wait(timeout=3), и если процесс всё ещё жив — добивают уже жесткимproc.kill(). Иначе вашим инженерам всё равно придется периодически заходить и делатьkill -9руками.Свой gRPC-wire вместо стандартного стека — это круто, но есть один архитектурный нюанс по безопасности.
В секции про Tsak вы пишете: «берётся самый правый хоп X-Forwarded-For, тот, который дописал доверенный прокси и который клиент подделать не может».
Если перед вашим приложением стоит цепочка балансировщиков (например, внешний Anti-DDoS -> ваш краевой Nginx), то самым правым хопом в заголовке окажется IP-адрес внешнего шлюза, а не реального атакующего. Выдав бан по этому IP при переборе, вы положите доступ вообще всем легитимным пользователям, идущим через этот узел.
Безопаснее парсить заголовок X-Forwarded-For справа налево, последовательно отбрасывая статические IP-адреса ваших собственных доверенных прокси. Первый же неизвестный адрес в цепочке с конца — это и есть настоящий IP клиента.
Травма от джанговских строк очень понятна)
Но фишка современных DI на питоне (той же Dishka) как раз в том, что там под капотом нет никакой строковой магии. Всё резолвится исключительно по type hints.
Вы просто указываете в init юзкейса зависимость вида repo: UserRepository. В итоге IDE, mypy и автокомплит работают идеально, потому что типы прописаны явно и строго. Так что компромиссов с типизацией тут не будет, реально советую потыкать.
Запихивать репозитории в TransactionManager через @property — это прямой путь к god-object. При росте приложения этот класс раздует, и его придется модифицировать при добавлении каждой новой таблички (явное нарушение OCP). Гораздо изящнее разруливать это через нормальный DI-контейнер (ту же Dishka). Провайдишь сессию куда надо, а управление транзакцией вешаешь декоратором прямо на юзкейс. И базовый класс чистый, и бойлерплейта меньше.