Наш проект состоит из нескольких микросервисов. Эти микросервисы образуют границу, точка входа к которой строго не определена, то есть каждый из микросервисов может быть запрошен и может запрашивать другие сервисы.
Ситуация, которую нам нужно обработать в этом ограниченном контексте микросервиса, следующая: клиент (другое приложение) отправляет запрос на выполнение некоторой логики и изменение данных (PATCH), время ожидания запроса истекает, пока запрос обрабатывается, клиент запускает тот же запрос для повторения операция успешно завершена, второй запрос обрабатывается таким же образом и завершается в течение своего времени, и клиент получает ответ.
Теперь произошло то, что одно и то же было обработано два раза из-за первого тайм-аута.
Нам нужно убедиться, что тот же запрос не будет обработан, и приложение ответит прежним ответом и кодом состояния.
Последующий запрос идентифицируется тем же UUID.
Теперь я понимаю, что клиент должен делать запросы более точно, или у нас должна быть единая точка входа запроса в контексте, ограниченном микросервисами, но в корпоративных проектах команда не владеет всей системой, поэтому мы немного ограничены решениями. мы предлагаем для проблемы. Имея это в виду, пытаясь не изобретать велосипед, мне приходит на ум:
Микросервисы должны использовать какое-то совместное использование сеанса (spring-session?) с возможностью поиска запроса по его id
до того, как он будет обработан, и в описанном случае, когда первый обрабатывается, а второй поступает, ждать завершения 1-й и ответить второму данными первого, время ожидания которого истекло для клиента.
С чем я борюсь, так это с тем, чтобы представить себе обработку асинхронности ответа на второй запрос и прослушивание состояния сеанса первого запроса.
Если будет использоваться spring-session (например, с hazelcast), мне не хватает какого-то конкретного обработчика состояния сеанса, который будет запущен при завершении запроса. Есть ли что-то подобное для прослушивания?
Код еще не написан. Это архитектурный мысленный эксперимент, который я хочу обсудить.
Если не уверены в понимании, прочитайте второй раз, пожалуйста, тогда я буду рад расширить.
РЕДАКТИРОВАТЬ: первая идея:
процесс будет выглядеть следующим образом (с нумерацией на изображении):
- (1) первый запрос запущен
- (3) обработка началась; (2) время запроса истекло;
- (4) клиент повторяет тот же запрос; программа знает, что она уже получала такой же запрос, потому что она знает req. я бы.
- программа проверяет кеш и состояние этого идентификатора запроса «ожидание», поэтому она ЖДЕТ (асинхронно).
- вычисленный результат первого запроса сохраняется в кеше - оранжевый квадрат
- (5) программа отвечает на первый запрос данными, которые предназначались для первого запроса
Идея состоит в том, что проверка результата и ответ на повторный запрос будут выполняться в цепочке фильтров, поэтому он фактически не попадет в контроллер, когда второй запрос асинхронно ожидает выполнения операции, инициированной первым запросом (я вижу, что у hazelcast есть некоторые события, когда строки добавляются/обновляются/удаляются из кеша - не знаю, работает ли он еще) и после завершения просто отвечают (каким-то образом пишут в HttpServletResponse). результат будет сохранен в кэше в фильтре postHandling.
Спасибо за понимание.