GonkaHub работает больше месяца. Реальные пользователи, реальные ноды, реальные деньги на кошельках. Но код, который был ОК для MVP, не годится для продакшна. Хардкоженные значения, дублированные уведомления, magic numbers в пяти местах. Январь-февраль 2026 — время исправлять шорткаты.

EU-сервер и latency

Первый сервер стоял в датацентре где-то в Азии. Проблема: ноды блокчейна Gonka географически ближе к Европе — node1.gonka.ai, node2.gonka.ai, node3.gonka.ai. Ping до них с азиатского сервера — 180-250ms. С европейского — 30-50ms.

Latency бьёт по всему. Каждый запрос к API ноды добавляет задержку. Check node status каждые 30 секунд — это десятки запросов в минуту. Update epoch info — batch запросы к нескольким нодам одновременно. 200ms туда, 200ms обратно — в сумме получается секунды.

Поднял второй сервер в EU. Docker Compose такой же, база одна — PostgreSQL на отдельном хосте. Два бэкенда обновляют одну базу, конфликтов нет: Celery tasks идемпотентные, REST API read-heavy.

Bonus: redundancy. Если один сервер упал, второй продолжает работать. Downtime не было с тех пор, как появился EU-сервер.

Реальный avg_block_time вместо 6.0

В коде было hardcoded значение:

AVG_BLOCK_TIME = 6.0  # seconds

Казалось мелочью. Но block time влияет на всё: время эпохи, расчёт наград, прогноз завершения эпохи.

Реальный avg_block_time в сети Gonka — 5.7-6.3 секунды. Зависит от нагрузки, количества валидаторов, состояния сети. Один хардкоженный 6.0 искажал расчёты на 3-7%.

Фикс: вычислять avg_block_time из реальных данных. Каждые 10 минут Celery task запрашивает последние 100 блоков, считает среднее:

@shared_task
def update_avg_block_time():
    """Обновление avg_block_time из последних 100 блоков"""
    blocks = fetch_blocks(limit=100)
    if len(blocks) < 2:
        return

    time_diffs = []
    for i in range(len(blocks) - 1):
        diff = blocks[i].timestamp - blocks[i+1].timestamp
        time_diffs.append(diff)

    avg = sum(time_diffs) / len(time_diffs)
    cache.set('avg_block_time', avg, timeout=None)

Теперь все расчёты используют реальное значение из кеша. Точность прогнозов выросла.

Дедупликация Telegram-нотификаций

Инвесторы получали двойные уведомления. Node jailed — два сообщения. Epoch completed — два сообщения.

Причина: Celery retries + несколько workers. Если таска упала с ошибкой, Celery retry её через 30 секунд. Два worker'а обработали одно событие — два уведомления.

Фикс: идемпотентность через проверку. Перед отправкой проверяю, отправлял ли уже нотификацию с таким event_type + target_id за последние 5 минут:

def send_alert(event_type, severity, message, target_id):
    """Идемпотентная отправка алерта"""
    cache_key = f"alert:{event_type}:{target_id}"
    if cache.get(cache_key):
        return False  # Уже отправляли

    send_telegram_message(message)
    cache.set(cache_key, True, timeout=300)  # 5 минут
    return True

Дубликаты исчезли.

GPU_WEIGHT_FACTOR: constants вместо magic numbers

Magic number 437 (потом 293) использовался в 5+ файлах. Расчёт наград, конвертация токенов, display в UI. Менял в одном месте — забывал в другом.

Создал apps/staking/constants.py:

GPU_WEIGHT_FACTOR = 293
REWARD_PRECISION = 18
MIN_STAKE_AMOUNT = 10000

Заменил все magic numbers на импорты. Одно место правки, один source of truth.

Task management и worker concurrency

Celery beat schedule пересмотрел. Некоторые таски бегали каждые 10 секунд — не нужно. Другие раз в час — слишком редко.

CELERY_BEAT_SCHEDULE = {
    'check-node-alerts': {
        'task': 'apps.staking.tasks.check_node_alerts',
        'schedule': 30.0,
    },
    'update-epoch-info': {
        'task': 'apps.staking.tasks.update_epoch_info',
        'schedule': 60.0,
    },
    'update-avg-block-time': {
        'task': 'apps.staking.tasks.update_avg_block_time',
        'schedule': 600.0,
    },
}

Worker concurrency подобрал под реальную нагрузку: 8 workers, 500 tasks per child (memory leak prevention), prefetch 2.

Node operations runbook

Последний кусок — документация для себя будущего:

## Node stuck on epoch
1. Check logs: docker compose logs -f gonka_backend
2. Verify API: curl node1.gonka.ai/status
3. Force update: docker compose exec gonka_backend python manage.py update_epoch

Сухо, по делу, работает.

Результат

GonkaHub в продакшне на EU-сервере с февраля 2026. Latency к нодам упал с 200ms до 40ms. Реальный avg_block_time вместо hardcoded 6.0 — расчёты точнее. Дедупликация нотификаций — никаких дублей. Constants вместо magic numbers — один source of truth. Celery schedule оптимизирован, worker concurrency подобрана. Runbook для операций.

MVP превратился в production-ready систему. Пользователи не видят разницы — но я знаю, что под капотом теперь всё по-взрослому.