#ruby-on-rails #node.js #heroku
#ruby-on-rails #node.js #heroku
Вопрос:
Я создаю приложение Rails, которое обрабатывает загрузку файлов через CarrierWave. В настоящее время загрузка файлов большего размера блокирует сервер на значительное время. Я видел такие решения, как s3-swf-upload-plugin gem, которые пропускают локальный сервер и отправляют файлы прямо из браузера на S3, но для этого потребовались бы некоторые модификации для предварительной генерации уникальных имен файлов и синхронизации их с базой данных. Я уверен, что это не составило бы особых проблем, но новый Cedar stack от Heroku подсказал мне идею выгрузки этих длительных запросов в node.js экземпляр, запущенный в том же приложении. Я не очень разбираюсь в подобных вещах, поэтому извините за мою формулировку, если она немного не соответствует действительности.
Возможно ли что-то подобное? Как бы вы настроили вещи таким образом, чтобы определенные запросы (в данном случае связанные с загрузкой файлов) обрабатывались приложением node, включенным в тот же репозиторий heroku, что и основное приложение rails?
Комментарии:
1. Рассматривали ли вы возможность запуска отдельного приложения heroku для загрузок?
2. Даже если бы они были в разных экземплярах, я думаю, вопрос о том, как их интегрировать вместе, все еще остается актуальным. Кроме того, я не уверен, как будет осуществляться совместное использование базы данных между двумя отдельными приложениями heroku.
3. Вы можете получить строку подключения к базе данных из ENV[‘DATABASE_URL’], и вы должны иметь возможность использовать ее во втором приложении. Фактически, с выделенной базой данных вы могли бы получить к ней доступ даже из приложения за пределами heroku: devcenter.heroku.com/articles/external-database-access
4. Это полезно знать, но основная часть вопроса касается наилучшего способа плавной интеграции двух отдельных приложений. Не могли бы вы просто установить форму из приложения rails для отправки в приложение node, чтобы приложение node тем временем начало обрабатывать загрузку и перенаправлять обратно в приложение rails? Как бы вы справились с передачей статуса операции между ними?
5. ДА. Я резюмировал это в полном ответе.
Ответ №1:
Я не думаю, что возможно смешивать Rails и Node в одном приложении. Однако вы могли бы получить примерно одинаковую функциональность, используя два отдельных приложения, которые взаимодействуют друг с другом.
Вы можете использовать ENV[‘DATABASE_URL’] для определения строки подключения к вашей базе данных. Используйте консоль heroku, чтобы установить ее в качестве переменной ENV для вашего приложения Node (например, heroku config:add OTHER_DB=your_connection_string
), тогда вы сможете использовать ту же строку подключения для подключения к той же базе данных из вашего другого приложения heroku. Вы даже можете получить к нему доступ за пределами heroku, если у вас есть выделенная база данных, смотрите: http://devcenter.heroku.com/articles/external-database-access
Для бесшовной интеграции между двумя приложениями вы могли бы создать форму, отображаемую приложением Rails post на URL приложения Node. В дополнение к загрузке файла, включите в эту форму через скрытые поля ввода любые другие переменные, которые вам нужны для передачи в приложение Node. Когда загрузка в приложение Node завершена, это может перенаправить клиента обратно в приложение Rails, передав любой статус или переменные в качестве параметров get.
Запустите два приложения под двумя поддоменами одного домена, и вы даже сможете обмениваться файлами cookie между ними.
Комментарии:
1. Я не понимаю, почему приложение rails отправляет сообщения на URL приложения Node. Почему бы не вызвать Rails URL из node, чтобы получить HTML?
2. @Luke: как это решение сработало для вас? Действительно ли это уменьшило время ожидания загрузки ваших файлов?
Ответ №2:
Вам нужны два приложения. Я делаю именно то, что описано в этом вопросе. Я хотел большие потоковые загрузки, и поскольку Rack записывает загрузки во временный файл перед передачей их обработчику, это невозможно сделать с Rails.
Node.js , с другой стороны, делает это прекрасно. Итак, есть два приложения Heroku, веб-приложение Rails и Node.js (Экспресс) веб-приложение. Веб-приложение Rails использует SWFUpload в качестве решения на стороне клиента. Приложение Rails и Node.js оба приложения имеют секретный ключ в качестве переменной конфигурации Heroku. Когда пользователю приходит время для загрузки, клиентский Javascript запрашивает URL-адрес загрузки с сервера Rails. Сервер Rails формирует URL-адрес загрузки с параметром Expires и вычисляет подпись с использованием секретного ключа. Обработчик Javascript на стороне клиента передает этот URL вместе с SWFUpload (свойство upload_url). Пользователь выбирает файлы для загрузки, и SWFUpload начинает размещать их в upload_url. The Node.js приложение проверяет, что срок действия URL-адреса не истек и что подпись действительна. Он обрабатывает данные формы с помощью огромной библиотеки.
Еще одна деталь. Для Flash требуется Node.js приложение для обслуживания crossdomain.xml это разрешает межсайтовый запрос.
Мой Node.js приложение не касается базы данных; но если бы это было так, я бы использовал DATABASE_URL, как предлагалось ранее. Обратите внимание, что вы не можете совместно использовать DATABASE_URL за пределами Heroku, если у вас нет выделенной базы данных. DATABASE_URLs для общих баз данных недоступны извне Heroku (в отличие от некоторых других сервисов, таких как RedisToGo).