🔄 Синхронизация — Справка и администрирование

Этот раздел содержит практические инструкции и операционные заметки по развертыванию, мониторингу и поддержке сервиса бэкфилла dicechess-sync на Raspberry Pi (192.168.10.9).

Если вам нужно детальное описание теории графа игроков и логических машин состояний, обратитесь к разделу архитектуры: 03 Синхронизация — обзор и архитектура.


1. Схема инфраструктуры и портов

Все процессы развернуты в домашней лаборатории на Raspberry Pi. Контейнеры делят одну директорию для хранения базы данных SQLite, что позволяет безопасно читать состояние краулинга параллельно с активным скрейпингом.

flowchart TD
    subgraph RPi["Raspberry Pi (192.168.10.9)"]
        subgraph HostDir["/home/jegors/dicechess-sync/"]
            ENV[".env"]
            DCY["docker-compose.yaml"]
        end

        subgraph HostData["/home/jegors/dicechess-sync-data/"]
            DB[("sync.db <br/> (SQLite WAL)")]
        end

        SH["sync-status.sh"] -.->|запросы к БД| DB

        subgraph DockerCompose["Docker Compose Stack"]
            SYNC["sync container<br/>(crawl-service.ts :8085)"]
            ADMIN["admin container<br/>(sqlite-web :8082)"]
        end

        BACKFILL["dc-sync-backfill container<br/>(sync-player.ts, ручной)"]

        SYNC <-->|чтение и запись| DB
        ADMIN -->|только чтение| DB
        BACKFILL <-->|чтение и запись| DB

        ENV -->|переменные среды| SYNC
        ENV -->|переменные среды| BACKFILL
    end

    subgraph Central["Центральные серверы"]
        ANALYTICS[("Analytics API (aurora :8020)<br/>GOLD Layer (PostgreSQL)")]
        ARCHIVE[("Raw Archive (dexus :5433)<br/>BRONZE Layer (PostgreSQL)")]
    end

    SYNC -->|"API-запросы"| DC_API["🌐 dicechess.com API"]
    BACKFILL -->|"API-запросы"| DC_API

    SYNC -->|"normalize & POST /api/games"| ANALYTICS
    BACKFILL -->|"normalize & POST /api/games"| ANALYTICS

    SYNC -->|"зеркалирование JSON"| ARCHIVE
    BACKFILL -->|"зеркалирование JSON"| ARCHIVE

2. Где что хранится

Службы используют общие хранилища и хост-пути на Raspberry Pi:

  • Конфигурация проекта: /home/jegors/dicechess-sync/
    • Содержит docker-compose.yaml и файл секретов/параметров .env.
  • База данных SQLite (sync.db): /home/jegors/dicechess-sync-data/sync.db
    • Файл бэкапа и логов. Вся очередь обхода игроков и кэш сырых партий хранятся локально в этой SQLite БД.
    • Благодаря режиму WAL (PRAGMA journal_mode = WAL), база поддерживает параллельное бесконфликтное чтение во время записи.
  • Зеркало сырья (Bronze Layer): dexus (192.168.10.4:5433)
    • Сюда демон зеркалирует сырые JSON-файлы с историей ходов, чтобы их можно было пересобрать в Gold-аналитику без повторного парсинга сайтов.
  • Итоговая аналитика (Gold Layer): aurora (192.168.10.3:8020)
    • Готовые нормализованные и проверенные движком партии.

3. Фазы обработки данных (Как это работает)

Каждый проход демона (crawl-service.ts) разделен на 4 четкие фазы:

[Обнаружение (Enumerate)] ➔ [Скачивание (Fetch)] ➔ [Нормализация и отправка (Post)] ➔ [Архивация (Archive)]
  1. Обнаружение (Enumerate):
    • Из таблицы players берется игрок со статусом pending с наивысшим приоритетом (рейтингом).
    • Выполняется постраничный запрос к API сайта (POST /api/player/history).
    • Найденные игры заносятся в таблицу games со статусом discovered, а оппоненты — обратно во фронтир players со статусом pending. Это запускает автоматический лавинообразный поиск по всему графу игроков.
  2. Скачивание сырья (Fetch):
    • Для новых игр из каталога последовательно запрашивается полная история ходов (GET /api/game-move-history).
    • Запросы идут через рейт-лимитер с паузами для обхода блокировок Cloudflare.
    • Скачанные сырые JSON сохраняются в таблицу raw_game_data, а статус игры в каталоге переходит в fetched.
  3. Нормализация и отправка (Post):
    • Сырая история ходов из SQLite нормализуется в структуру ходов и событий Dice Chess и валидируется локально.
    • Готовая партия отсылается в Analytics API (POST /api/games). В случае успеха статус игры в каталоге становится posted, при логических ошибках движка — rejected (422), при сетевых проблемах — временно паркуется в error для повтора.
  4. Архивация (Archive):
    • Скачанные сырые JSON из локальной таблицы raw_game_data асинхронно отправляются в центральный bronze-архив на dexus.
    • После этого колонка archived_at заполняется временем пуша, но сырье остается в локальном файле sync.db в качестве кэша.

4. Справочные руководства

Используйте следующие операционные заметки для работы с сервисом:

  • Подключение к SQLite БД — как зайти в базу sync.db через графический клиент (TablePlus, DBeaver) или через консоль с локального компьютера.
  • Логи и статистика — как читать структурированные логи демона в реальном времени и расшифровывать статистику проходов.
  • Интервалы и лимиты — как устроены паузы рейт-лимитера, как настроить джиттер и тайминги простоя демона при пустой очереди.
  • Служебные порты и docker-compose — как настроен проброс портов для панели управления и веб-админки sqlite-web на Raspberry Pi.