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