Архитектура

«Доступна новая версия сайта»: как вкладка узнаёт о выкладке и почему не перезагружается сама

«Доступна новая версия сайта»: как вкладка узнаёт о выкладке и почему не перезагружается сама

Сайт VOG перестал перезагружать страницу при переходах, и вкладка стала жить часами на коде, загруженном до выкладки. Как вкладка узнаёт о новой сборке почти без лишней нагрузки на сервер — из заголовков обычных ответов и редкого опроса, — почему обновление предлагается кнопкой, а не делается само, и как одна строка ?v= дала на странице две копии React

Мигратор схемы: на чём он стоит и что ломается вне ванильного PostgreSQL

Мигратор схемы: на чём он стоит и что ломается вне ванильного PostgreSQL

Мигратор — не «скрипты по порядку», а программа со своими требованиями к СУБД: журнал версий, транзакционный DDL, интроспекция каталогов. Живая матрица пяти инструментов (goose, Flyway, Liquibase, Atlas, Alembic) против PostgreSQL, CockroachDB и Picodata: на Picodata ни один не дошёл до первой миграции, на CockroachDB два споткнулись о собственную служебную часть. Плюс декларативный против императивного, привязка к формату и что на самом деле стоит денег в бесплатных редакциях

Порядок вывода легаси: почему VOG переносит игры по одной

Порядок вывода легаси: почему VOG переносит игры по одной

Почему перезапуск VOG не стал «переписать всё с нуля»: откуда в проекте привычка к осторожности, что пришлось сделать в 2021 году, чтобы старый C++-сервер вообще можно было собрать и запустить, и как в 2026-м выбрали порядок — сначала общее хранилище для всех игр, потом по одной игре, на каждом шаге меняется что-то одно

Как писать тестируемый код

Как писать тестируемый код

Тестопригодность — свойство дизайна, а не тестов: если тяжело написать тест, проблема в коде. Швы и инъекция зависимостей, инъекция недетерминизма (часы, случайность, ID), functional core / imperative shell, зависимость от абстракций на границах и заход в легаси через characterization-тесты — на живом Go-стенде

Инциденты и постмортемы: как надёжность делают процессом

Инциденты и постмортемы: как надёжность делают процессом

Технические паттерны устойчивости не работают без процесса вокруг них: как устроен инцидент-менеджмент (роли, severity, коммуникация), почему постмортемы должны быть блеймлесс (иначе люди прячут причины), как из инцидента рождаются action items и runbooks, и как политика error budget превращает надёжность из лозунга в решения о релизах. SRE-сторона отказоустойчивости

Планировщики: семантика расписаний в кластере

Планировщики: семантика расписаний в кластере

«Раз в час» перестаёт быть понятным требованием, как только реплик становится больше одной, а планировщик успевает поспать: что означает пропущенный запуск, догоняет ли расписание пропущенное (одно или всё), что делать с перекрытием и почему полночь — худшее время для задачи. Поведение снято прогонами на живом кластере, а не пересказано по документации

Disaster Recovery: RTO/RPO, стратегия бэкапов и restore-тесты

Disaster Recovery: RTO/RPO, стратегия бэкапов и restore-тесты

Отказоустойчивость — это не только про «не упасть», но и про «восстановиться». RTO и RPO как язык договорённостей о потерях, стратегия бэкапов (3-2-1, полные/инкрементальные, PITR), почему бэкап без regular restore-теста — это не бэкап, мульти-регион failover (active-passive vs active-active), DR-runbook и учения. Дисциплина, которая проверяется только реальным восстановлением

Горутины, корутины, потоки: модели конкурентности в разных языках

Горутины, корутины, потоки: модели конкурентности в разных языках

Как C++, Go, Rust, Java, Python и Node решают один вопрос — как исполнять независимую работу параллельно с чужими стеками и планировщиками: потоки ОС, green/virtual threads, stackless-корутины и event loop. Вытеснение против кооперации, stackful против stackless, 1:1 против M:N — и чем каждая модель платит

Очереди задач: аренда и жизненный цикл джобы

Очереди задач: аренда и жизненный цикл джобы

Джоба — не сообщение: у неё есть владелец и срок владения. Как устроен цикл claim → lease → heartbeat → complete, что на самом деле удерживает джобу за воркером (не аренда), что происходит при смерти воркера и почему штатный SIGTERM при деплое способен выполнить работу дважды

Backpressure и load shedding: как система защищает себя

Backpressure и load shedding: как система защищает себя

Rate limiting ограничивает клиента, но что делать, когда система сама не тянет? Backpressure (распространить «притормози» вверх по цепочке через bounded queues) и load shedding (сознательно отбросить часть нагрузки, чтобы не упасть целиком) — механика самозащиты: почему неограниченные очереди убивают, adaptive concurrency, приоритезация и деградация, и чем это отличается от rate limiting и circuit breaker