Files

5.1 KiB
Raw Permalink Blame History

title
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/scheduleSpecialistService::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;
    • при HttpExceptionInterfaceScheduleErrorHandlerService::handleHttpException возвращает массив диагностики;
    • при прочих исключениях — handleGeneralException.

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.