Сервер Rails, работающий в нескольких потоках - Как сделать API-вызовы сторонними разработчиками поточно-ориентированными? - PullRequest
1 голос
/ 03 марта 2020

У меня есть приложение RoR, работающее на трех разных серверах, каждый из которых работает по 5 потоков. Мое приложение выполняет вызовы стороннего API. При выполнении нескольких одновременных запросов я сталкиваюсь с проблемами состояния гонки, при которых ресурс в этой сторонней системе может стать недоступным, когда другой запрос пытается получить к нему доступ. Я нарисовал эту (очень) быструю диаграмму для иллюстрации.

diagram

Таким образом, пользователь запрашивает удаление ресурса и вскоре после того, как другой пользователь запрашивает Для чтения ресурса запросы на чтение по той или иной причине быстрее попадают в стороннюю систему, поэтому он успешно возвращает его, пока другой запрос удаляет его. Прежде чем моя система получает запрос на удаление и помечает ресурс как недоступный, она немедленно отправляет новый запрос на редактирование этого ресурса, который теперь удален из сторонней системы. Это приводит к ошибке в моем приложении, где оно может стать не синхронизированным c. Это всего лишь пример, и он не совсем то, что происходит (или единственное, что происходит), но он хорошо иллюстрирует проблему.

Я знаю, что есть способы предотвратить локальное возникновение таких условий гонки в ActiveRecord, но каков хороший способ обрабатывать вызовы сторонних API? Есть ли способ обработать все логи c, которые обрабатывают вызовы API синхронно, без ущерба для многопоточной природы серверов?

1 Ответ

1 голос
/ 04 марта 2020

При работе с внешней службой вы не можете доверять собственному представлению о состоянии, в котором находятся их ресурсы. Даже если вы синхронизируете c все ваши запросы для вашей собственной системы, что-то еще может изменить ресурсы. Что если пользователь оставит окно редактирования открытым на несколько часов, а ресурс будет удален, а затем отправит изменения? Каждый запрос должен быть подготовлен для обработки ресурсов в любом возможном состоянии.

В этом случае все три запроса должны обрабатывать случай, когда ресурс не найден: доступ к ресурсу, его удаление или редактирование. Если пользователь пытается редактировать, а ресурс не существует, возможно, вы увидите сообщение типа «извините, этот ресурс не был найден или удален».

В качестве альтернативы, вместо удаления ресурсов, вы можете деактивировать их, если возможный. Это позволяет определить разницу между ресурсом, который не существует, и ресурсом, который был удален. Когда пользователь пытается получить доступ или отредактировать деактивированный ресурс, вы можете дать ему лучшее сообщение об ошибке («ресурс был удален» против «ресурс не найден») и, возможно, предложить восстановить ресурс.

Если доступно, вы может использовать такие функции, как веб-хуки и обратные вызовы, чтобы получать информацию об изменениях и обновлять собственное внутреннее состояние внешних ресурсов. Даже в этом случае они будут иметь задержку и не могут быть полностью доверенными.

В любом случае, каждый запрос не может доверять тому, что они знают состояние внешних ресурсов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...