#ruby-on-rails #ruby #http
Вопрос:
Я пытаюсь вызвать api (из контроллера), сохранить полученный ответ JSON в переменной, а затем получить доступ к частям значения переменной по желанию (на мой взгляд). Следующий код зависает:
в контроллере:
parsed_response = JSON.parse(HTTP.get('http://localhost:3000/api/v2/storefront/products')) @products = parsed_response['data']
в поле зрения:
lt;%= @products %gt;
Вышесказанное ничего не отображает, зависает процесс, и мне приходится kill -9
выключать сервер. Что я здесь делаю не так, это каким-то образом делает HTTP.get
запрос более одного раза подряд, что приводит к зависанию процесса? Связано ли это с тем, что #parse и #get вызываются одновременно в одной строке?
(Я использую здесь gem ‘http’)
Комментарии:
1. Если я загружу этот URL-адрес в свой браузер, он отлично отобразит ответный пакет JSON.
2. Что такое ваш веб-сервер? Пума?
3. Да, мой веб-сервер-Puma (я запускаю его в режиме разработки на своем локальном компьютере).
4. Тогда я предполагаю, что это
Rack::Lock
«виновато». Попробуйте установитьconfig.allow_concurrency=true
в среде разработки (илиconfig.threadsafe!
) — это может помочь. Но, честно говоря, я бы пересмотрел решение — http-запросы к собственным конечным точкам-невероятная трата ресурсов…
Ответ №1:
Я предполагаю, что ваш сервер (puma, unicorn,..) принимает ограниченное количество параллельных HTTP-соединений.
Предположим, что ваше приложение принимает только одно соединение за раз:
- Ваш запрос
localhost:3000/page_1
, поэтому вы занимаете эту связь. Никто не сможет подключиться к вашему серверу, пока это соединение не закончится. localhost:3000/page_1
хочет подключитьсяlocalhost:3000/page_2
, он должен подождать, пока активное соединение не закончится. Поскольку он не может подключиться, он ждет… до истечения тайм-аута или до тех пор, пока вы не убьете свой сервер.
Комментарии:
1. Я думаю, что это должно быть как-то связано с моим кодом, с тех пор я обнаружил, что это работает;
response = (HTTP.get('http://localhost:3000/api/v2/storefront/products')) parsed_response = JSON.parse(response) @products = parsed_response['data']
И поскольку это работает как с рендерингом браузера @products, так и с вызовом API, который происходит непосредственно перед этим с контроллера, это определяет, что мой сервер может принимать параллельные http-соединения, не так ли? Возможно, это метод цепочки в 1-й исходной строке? Но если так, то почему?