2015-06-17 2 views
2

Я пишу API для доступа к ресурсам на одном из моих серверов. Часть этого API будет обрабатывать HTTP-запросы. Во имя хорошего дизайна программного обеспечения я не хочу, чтобы мой API блокировал.Поддерживает ли Ruby неблокирующие HTTP-запросы без сторонней библиотеки?

Я довольно новичок в Ruby, но в Java я бы предоставил асинхронный API, который возвращает Futures ответа. В JavaScript я бы использовал обратные вызовы в своих методах.

Я искал другие вопросы переполнения стека, и https://github.com/eventmachine/em-http-request, кажется, делает то, что я хочу. Однако я не решаюсь полагаться на стороннюю библиотеку. Есть ли способ Ruby для решения этой проблемы или большинство разработчиков полагаются на сторонние библиотеки?

+1

Любая причина, вы не можете просто использовать [потоки] (http://stackoverflow.com/ вопросы/6643964/асинхронный HTTP-запрос-в-рубин)? – PinnyM

+0

вы всегда можете вернуться к 'IO.select' для реализации неблокирующих функций: http://stackoverflow.com/questions/6165735/understanding-io-select-when-reading-socket-in-ruby, если вы хотите, чтобы ваш api быстрее реагируйте, вам может быть намного лучше, используя что-то вроде sidekiq для асинхронных задач! – phoet

+0

Рассмотрите это: Ruby - это сторонняя библиотека/пакет, как и многие другие вещи, которые вы добавляете к машине после начальной установки ОС. Именно так работает OSS. Вы должны решить, в какой степени вы хотите пойти с «другим» программным обеспечением, но очень часто полагаться на хорошо написанные и хорошо проверенные библиотеки/драгоценные камни, независимо от того, происходят они от основных разработчиков или нет. (И только потому, что что-то происходит от основной команды, автоматически не означает, что это лучший выбор, это просто то, что связано.) –

ответ

3

Основываясь на моих тестах, MRI поддерживает неблокирующие HTTP-запросы просто с помощью потока. Тем не всегда позволяют параллелизм в Ruby, из-за GIL, но net/http по-видимому, один из исключений:

require 'net/http' 
require 'benchmark' 

uri = URI('http://stackoverflow.com/questions/30899019/') 

n = 10 
Benchmark.bm do |b| 
    b.report { n.times { Net::HTTP.get(uri) } } 
    b.report { threads = Array.new(n) { Thread.new { Net::HTTP.get(uri) } }; threads.each(&:join) } 
end 
#  user  system  total  real 
# 0.010000 0.010000 0.020000 ( 0.102024) 
# 0.020000 0.010000 0.030000 ( 0.025904) 
Смежные вопросы