#database #asynchronous
Вопрос:
допустим, у меня есть веб-приложение, которое выбирает пользователя через REST:
GET /users/me
{
"id": 1,
"name": "John Doe",
"email": "john.doe@email.com"
}
Веб-приложение имеет возможность обновлять этого пользователя в форме, например, изменять name
.
Обычно это реализуется с помощью конечной точки REST, которая записывает изменения в базу данных ( UPDATE users SET name = 'My new name' where id = 1
) и возвращает результат в браузер.
Бизнес требует, чтобы эта система масштабировалась до миллионов одновременных пользователей, и одна из попыток сделать это-сделать эти типы запросов асинхронными. Изменение name
не должно быть действием, которое требует немедленного реагирования. Его можно поместить в очередь и записать в базу данных, когда будут доступны ресурсы. Пользовательский интерфейс может отразить это, сделав запрос, а затем предположив, что данные были/будут обновлены. Но если пользователь перезагрузит страницу, возможно, будут извлечены старые данные (потому что изменение еще не было записано). Затем нам нужно будет реализовать хранилище в браузере, чтобы гарантировать name
сохранение новых данных, и когда «новые» данные будут извлечены при перезагрузке, сравните что-то вроде a timestamp
, чтобы узнать, какое значение является последним.
Что мне интересно, так это от кого — то, у кого есть опыт в этом-это распространенный способ сделать это? На какие потенциальные подводные камни нам следует обратить внимание? Какова была бы альтернатива?
Ответ №1:
Распространенный способ сделать это-вернуть что-то вроде идентификатора процесса, который клиент может использовать для проверки обработки запроса. Таким образом, конечная точка ‘changeUserName’ вернет идентификатор процесса, а конечная точка ‘checkProcessStatus’ вернет статус запроса, поставленного в очередь.
В интерфейсе вы можете показать, что изменение находится в ожидании, и время от времени опрашивать, чтобы проверить, изменился ли статус. Таким образом, на стороне клиента вы можете сохранить новое имя и идентификатор процесса. Когда статус процесса меняется на «успешно», все в порядке, когда он завершается неудачей, вы всегда можете запросить старое имя и уведомить пользователя о том, что что-то пошло не так.
Кстати: вы всегда можете реализовать это позже, когда скорость станет проблемой. Сначала найдите простой способ узнать, сможете ли вы получить доступ к миллиону пользователей 😉
Правка: немного больше о том, как это может работать. Вы создаете очередь для хранения действий/вещей для обработки, например » обновить имя пользователя до действия [новое имя]». Эта запись в очереди имеет статус и идентификатор процесса, а также, возможно, дополнительную информацию. «checkProcessStatus» просто вернет статус записи, что очень дешево и вернет только что-то вроде «ожидание» и, возможно, отметку времени. В фоновом режиме очередь обрабатывается, и статус обновляется до успешного, неудачного или любого другого. Вы также можете предоставить дополнительную информацию, такую как сообщения об ошибках или обновленные значения. В следующий раз, когда клиент использует «checkProcessStatus», он увидит новый статус.
Комментарии:
1. Спасибо тебе за ответ, Томас. Последующий вопрос. Разве конечная точка «checkProcessStatus» не должна знать старое значение и новое значение и запрашивать то, что сохраняется в базе данных, чтобы узнать, было ли оно обработано? Или ему нужно будет заглянуть в очередь (скажем, rabbitmq). Похоже, это дорогостоящая операция. Кроме того, относительно вашего последнего комментария: есть ли какой-либо конкретный «более простой» способ «масштабирования», о котором вы думаете?
2.
checkProcessStatus
должно быть как можно дешевле. Таким образом, он возвращает только состояние процесса в очереди. Но когда это будет сделано, вы можете вернуть результат, если хотите, например, новое значение, которое было сохранено. Я обновлю свой ответ дополнительной информацией.