Files
docs/apps/backend-scenarios/schedule-messenger.md
T

91 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Асинхронное сообщение GetScheduleMessage (Backend)
---
# Сценарий 2.3: `GetScheduleMessage` и `GetScheduleMessageHandler`
## Бизнес-цель
Получение расписания спроектировано через **Symfony Messenger**, чтобы:
- отделить HTTP-слой от интеграции с MIS и работы с кешем;
- унифицировать вызовы (тот же message может диспатчиться из других мест);
- заложить возможность смены транспорта с `sync` на очередь без переписывания контроллера.
По факту конфигурации в `config/packages/messenger.yaml` маршрут для `App\Message\GetScheduleMessage` указывает на транспорт **`sync://`**, то есть обработка **синхронная в том же PHP-процессе**, а не отложенная очередь.
## Точки входа
| Тип | Где создаётся сообщение | Класс |
| --- | --- | --- |
| HTTP | `GET /specialist/schedule``SpecialistService::getSchedule` | `App\Message\GetScheduleMessage` |
| Messenger | обработчик | `App\MessageHandler\GetScheduleMessageHandler` |
CLI для этого сообщения отдельно не зарегистрирован в коде репозитория.
## Пошаговый алгоритм
1. `SpecialistService::getSchedule` создаёт `new GetScheduleMessage($dto->toQueryString(), $dto->onlineMode)` и диспатчит через `MessageBusInterface`.
2. `GetScheduleMessageHandler::__invoke`:
- стартует `PerformanceTrackerService`;
- **кеш-hit**: `ScheduleCacheService::getCachedSchedule` — при успехе возвращает данные + `_meta.source = cached`;
- **кеш-miss**: `InfoclinicaClientService::getSchedule($queryString, $isOnlineMode)` (второй аргумент — в коде хендлера; фактическая сигнатура клиента может отличаться — см. раздел Edge cases);
- при успешном ответе MIS — `ScheduleCacheService::saveSchedule` и ответ с `_meta.source = api`;
- при `HttpExceptionInterface``ScheduleErrorHandlerService::handleHttpException` возвращает массив диагностики;
- при прочих исключениях — `handleGeneralException`.
## Mermaid
```mermaid
sequenceDiagram
participant SC as SpecialistController
participant SS as SpecialistService
participant BUS as MessageBus
participant H as GetScheduleMessageHandler
participant CACHE as ScheduleCacheService
participant MIS as InfoclinicaClientService
participant ERR as ScheduleErrorHandlerService
SC->>SS: getSchedule(ScheduleDto)
SS->>BUS: dispatch(GetScheduleMessage)
BUS->>H: __invoke
H->>CACHE: getCachedSchedule
alt hit
CACHE-->>H: данные слотов
else miss
H->>MIS: getSchedule (HTTP)
alt MIS OK
MIS-->>H: JSON нормализован
H->>CACHE: saveSchedule
else HTTP error
MIS-->>ERR: HttpException
ERR-->>H: error payload
end
end
H-->>SS: результат массива
SS-->>SC: JsonResponse
```
## Внешние зависимости
| Система | Роль |
| --- | --- |
| PostgreSQL (`Schedule`) | кеш слотов |
| Инфоклиника | `GET /api/reservation/intervals?{query}` (см. `InfoclinicaClientService`) |
| Логирование | канал `infoclinica-cache`, `infoclinica-error` (через `withName`) |
## Обработка ошибок и edge cases
- **Ошибка HTTP MIS** — не исключение наружу; возвращается массив с `status_code`, `response` и др. Контроллер отдаёт его как JSON `200` с этим телом (поведение «мягкой ошибки» — важно для фронта).
- **Рассинхрон сигнатур**: в `GetScheduleMessageHandler` вызов `getSchedule` с двумя аргументами должен соответствовать PHP-интерфейсу клиента; при несоответствии будет `ArgumentCountError` на старте (сигнал провести рефакторинг интерфейса `InfoclinicaClientServiceInterface` и реализации).
- **sync-транспорт**: нет повторного выполнения из failed queue для этого message в штатной конфигурации (в отличие от реальной async-очереди).
## Ссылки на классы
- `apps/backend/src/Message/GetScheduleMessage.php`
- `apps/backend/src/MessageHandler/GetScheduleMessageHandler.php`
- `apps/backend/src/Service/Specialist/SpecialistService.php`
- `apps/backend/config/packages/messenger.yaml` (`routing` для `GetScheduleMessage`)
Дополнительно: кеш в БД — [schedule-cache.md](./schedule-cache.md).