91 lines
5.1 KiB
Markdown
91 lines
5.1 KiB
Markdown
---
|
||
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).
|