Модель конкурентности и жизненный цикл горутин
Обработка десятков высокобитрейтных потоков RTSP, одновременных зрителей WebRTC и непрерывной дисковой записи требует строгой, защищённой от утечек архитектуры конкурентности.
1. Иерархия горутин и распространение контекста (context.Context)
Каждая фоновая горутина в RUSEON Core привязана к дереву контекстов context.Context:
- Корневой контекст (Root Context): Формируется на основе сигналов операционной системы (
SIGINT,SIGTERM). - Контекст камеры (Camera Context): Привязан к жизненному циклу конкретной камеры. Отключение камеры автоматически отменяет её воркер приёма, цикл демуксинга и каналы записи.
- Контекст клиентской сессии: Ограничен сессией WebRTC или скачиванием чанка HLS.
2. Правила владения каналами и неблокирующие шаблоны
Для предотвращения взаимных блокировок (дедлоков) и утечек ресурсов:
- Явное владение: Горутина-отправитель всегда создаёт и закрывает канал. Получатели никогда не закрывают каналы.
- Неблокирующая отправка (
select ... default): Раздача кадров подписчикам всегда выполняется через неблокирующийselect. Зависший клиент не может остановить поток камеры. - Ограниченные буферы: Все каналы имеют фиксированную ёмкость (например, каналы подписчиков RingBuffer имеют ёмкость 50–100 кадров).
3. Стратификация блокировок (Защита от дедлоков)
Для гарантии того, что конкурентные захваты блокировок не создадут циклических зависимостей:
$$\text{Уровень 1: Мьютекс хранилища Ring Buffer} \longrightarrow \text{Уровень 2: Мьютекс реестра подписчиков}$$
- Правило: Горутине, удерживающей мьютекс подписчиков, строго запрещено запрашивать мьютекс хранилища Ring Buffer.
- Чтение параметров кодека полностью исключает блокировки за счёт
atomic.Pointer[CodecParams].
4. Корректное завершение работы (Graceful Shutdown)
При получении сигнала завершения (SIGTERM):
- Прекращается приём новых HTTP/WHEP соединений.
- Отменяется корневой контекст, останавливая циклы приёма RTSP.
- Дозаписываются все оставшиеся в памяти кадры архива fMP4.
- Выполняется системный сброс скользящих окон 2MB на диск через
unix.SyncFileRange. - Корректно закрывается база данных BadgerDB v4 с фиксацией журнала WAL.