Перейти к содержанию

Runbook: пропали/не обновляются тикеры и счётчики

1. Когда использовать

Признаки инцидента:

  1. В шапке/виджетах счётчики пустые или «зависли».
  2. После действий в комментариях (прочитано, вопрос, ответ) значения не меняются.
  3. В API значения одни, в UI другие.
  4. У части пользователей счётчики корректны, у части нет.

2. Быстрая классификация проблемы

Сначала определить, какой контур сломан:

  1. Системные тикеры (unreadCommentsCount, questionsCount, badge, overDueTasksCount и т.д.). Их порядок в панели навигации жёстко зафиксирован в коде фронтенда и не настраивается.
  2. Кастомные тикеры (админка /administration/tickers, MenuItemTicker). Их порядок отображения управляется позицией строки в списке настроек (в обратном порядке).
  3. Чат-счётчики (/api/chats/counters, unread по чатам/подпискам).
  4. Только UI-обновление (в API уже верно, но экран не подтянул изменения).

3. Как это работает (по коду)

3.1 Backend API

  • GET /api/tickers/all — основной снимок для SPA (системные + кастомные + ассистентские).
  • GET /api/tickers/system — системные тикеры (можно частично по списку ключей).
  • GET /api/tickers/custom — кастомные тикеры.
  • GET /api/tickers/refresh-cache — принудительный refresh user cache.
  • GET /api/tickers/refresh-subcat-cache/{subcatId} — refresh по подкатегории.

3.2 Источник значений

Системные тикеры:

  1. TickersService.GetSystem -> GetSystemByUserIds.
  2. Если включён UseSystemTickersCache, чтение идёт из TickersResultsCache.
  3. При cache-miss/недостатке данных выполняется пересчёт:
  4. dbo.UserTickers_refresh,
  5. затем чтение через dbo.GetSystemTickers.

Кастомные тикеры:

  1. Схема/доступность тикеров — из настроек меню и прав.
  2. Значения — из UserMenuItemTickersCache/UserMenuItemTickers (через TCTickerNavigationItem.GetUserTickersData).
  3. Refresh пользовательских значений:
  4. dbo.UserMenuItemTickers_refresh,
  5. dbo.SubcatTickers_refresh.

3.3 Realtime и pull в SPA

  1. Backend шлёт SystemTickersUpdated, если после пересчёта есть реальное отличие от кеша.
  2. SPA регулярно перечитывает tickers/all через cron (tickers) и при goOnline/userActive.
  3. От signal/eventbus (ReadComments, NewComment, QuestionComment, RefreshMTF, UpdateSystemTickersEventBusMessage) SPA делает частичный tickers/system.
  4. После comment-операций interceptor публикует событие обновления тикеров.
  5. Для чат-бейджей отдельно используется chats/counters (cron + signal + tab visibility).

4. Что смотреть при разборе (чек-лист)

  1. Зафиксировать user id, время, какой именно счётчик «не сходится».
  2. Снять API-снимок:
  3. GET /api/tickers/all,
  4. GET /api/tickers/system,
  5. GET /api/chats/counters (если проблема чатовая).
  6. Сравнить API и UI:
  7. если API уже неверный -> backend/data/cache;
  8. если API верный, UI неверный -> signal/cron/store.
  9. Для системных тикеров проверить, не «завис» ли кеш:
  10. вызвать GET /api/tickers/refresh-cache,
  11. повторить GET /api/tickers/system.
  12. Для кастомных тикеров проверить админ-настройку и доступность тикера пользователю.
  13. Для кейсов после комментариев проверить, что был триггер обновления (eventbus/signal).
  14. Проверить, активна ли master-tab у пользователя (часть реакций фильтруется по active tab).
  15. Если проблема локальна для отдельных пользователей — проверить группы/права и фактический набор доступных тикеров.

5. Симптом -> вероятная причина -> проверка

Симптом Вероятная причина Что проверить первым
В API tickers/system значение уже неверное stale cache или не выполнен пересчёт refresh-cache + повтор tickers/system
Кастомный тикер есть в админке, но не виден пользователю нет прав на пункт меню/тикер membership пользователя в группах + MenuItemTickerGroup
После mark-as-answered/read счётчик в UI не изменился не отработал signal/eventbus путь приход SystemTickersUpdated/ReadComments/RefreshMTF
Чат-бейдж не совпадает с остальными тикерами divergence между tickers/* и chats/counters ответ GET /api/chats/counters и cron chatTickers
Только у одного пользователя «зависло» персональный cache/state refresh-cache, состояние master-tab, повторный API-снимок

6. SQL для быстрой диагностики

declare @user_id int = 0;
declare @ticker_id int = 0;

-- Кастомные значения по пользователю
select
        umit.UserID,
        umit.MenuItemTickerId,
        umit.ItemCount
from dbo.UserMenuItemTickers umit
where umit.UserID = @user_id
order by
        umit.MenuItemTickerId;

-- Настройки тикеров
select
        mit.Id,
        mit.MenuItemID,
        mit.TickerType,
        mit.SqlSPName,
        mit.DataSourceSettingId
from dbo.MenuItemTicker mit
where @ticker_id = 0 or
      mit.Id = @ticker_id
order by
        mit.Id;

-- Привязка тикера к группам
select
        mtg.MenuItemTickerID,
        mtg.GroupID
from dbo.MenuItemTickerGroup mtg
where @ticker_id = 0 or
      mtg.MenuItemTickerID = @ticker_id
order by
        mtg.MenuItemTickerID,
        mtg.GroupID;

-- Системные тикеры (результат расчёта)
exec dbo.GetSystemTickers
        @UserId = @user_id,
        @OnlineUserOnlyF = 0;

7. Что приложить в задачу разработчикам

  1. userId, timezone, время инцидента.
  2. Скриншот UI со значением счётчика.
  3. Ответы tickers/all, tickers/system, chats/counters (если применимо).
  4. Результаты SQL-блока выше.
  5. Был ли вызван refresh-cache и что изменилось после него.

Связанные документы

  • docs/domains/grids/admin.md
  • docs/domains/chat/data-flow.md
  • docs/domains/comments/data-flow.md
  • docs/domains/notifications/data-flow.md
  • docs/reference/realtime/signalr-ui-map.md