Работа с передним или фоновым изображением в Rails (Jruby, Torquebox)
Я загружаю фотографии с помощью ajax, манипуляции и загрузка в s3 занимают много времени. Я слышал, что лучше выполнять эти задачи в фоновом режиме. Мое приложение должно подождать, пока фотографии будут загружены. Но если я выберу фоновый способ, мне нужно будет работать с веб-сокетами или повторить ajax, чтобы проверить результат (ссылки на s3) (меня это не радует). Почему очень плохо делать сложные вычисления прямо в контроллере (на переднем плане)? Сейчас я использую Torquebox(Jruby), и, насколько я понимаю, он имеет идеальный параллелизм. Означает ли это, что ожидание загрузки на s3 не потребует ресурсов и все будет работать нормально? Пожалуйста, напишите о плюсах и минусах заднего / переднего плана в моей ситуации. Спасибо!
1 ответ
Обычно считается плохой практикой блокировать обработчик веб-запросов по сетевому запросу к сторонней службе. Если этот сервис станет медленным или недоступным, это может засорить все ваши веб-процессы, независимо от того, какой ruby вы используете. Это то, что вы называете "передним планом".
По сути, это поток вашей текущей настройки (на переднем плане):
- пользователь загружает изображение на ваш сайт, и ваш желаемый контроллер получает запрос.
- Ваш контроллер делает синхронный запрос на s3. Это блокирующий запрос.
- Ваш контроллер ждет
- Ваш контроллер ждет
- Ваш контроллер (продолжает) ждать
- наконец, (и это не гарантировано) вы получаете ответ от s3, и ваш код продолжает и отображает ваш заданный вид /json/text/ и т.д.
Очевидно, что шаги 3-5 являются очень плохой новостью для вашего сервера, и, как я уже говорил ранее, этот рабочий / поток / процесс (в зависимости от вашей среды сервера ruby /rails) будет "задерживаться" до получения ответа от s3 (который потенциально никогда не может случиться).
Вот тот же поток с фоновым заданием с некоторой справкой javascript во внешнем интерфейсе для уведомления:
- пользователь загружает изображение на ваш сайт, и ваш желаемый контроллер получает запрос.
- Ваш контроллер создает новый поток / процесс, чтобы сделать запрос к s3. Это неблокирующий подход. Вы устанавливаете флажок на запись, которая ссылается на ваш s3-образ src, например, выполнено: false, и ваш код переходит к шагу 3. Теперь ваш новый поток / процесс будет ожидать ответа от s3, и вы установите флаг "завершено" в значение true, когда s3 ответит.
- Вы визуализируете ваше представление /json/text/ и так далее и освободите свой рабочий / поток / процесс для этого запроса... хорошие новости!
Теперь для забавного внешнего интерфейса:
- ваш клиент получает ваш ответ, вызывая ваш javascript-интерфейс для запуска повторяющейся функции, подобной setInterval, которая "пингует" ваш сервер каждые 3 секунды, где ваш внутренний контроллер проверяет, установлен ли установленный вами флаг "завершен" ранее верно, и если так, ответьте / сделайте true.
- Ваш клиентский javascript получает ваш ответ и либо продолжает пинговать (пока вы не назначите, что он должен сдаться), либо прекращает пинговать, потому что ваше приложение ответило true.
Я надеюсь, что это ставит вас на правильный путь. Я полагал, что написание кода для этого ответа было хуже, потому что казалось, что вы ищете плюсы и минусы. Для реальных идей реализации, я бы посмотрел на следующее: