Как создать асинхронные HTTP-запросы, предлагая при этом объектный интерфейс? - PullRequest
2 голосов
/ 24 января 2012

Каков хороший способ предоставить простой в использовании интерфейс в стиле объекта для HTTP API, при этом позволяя выполнять асинхронные HTTP-запросы? Например, учитывая следующий код:

user = User.find(1) # /api/v1/users/1
f = user.foo # /api/v1/users/1/foo
b = user.bar # /api/v1/users/1/bar

Вызовы методов foo и bar могут логически вызываться параллельно, но, если возможно, я бы хотел, чтобы вызывающий пользователь имел чистый способ объявить свое намерение для параллельных вызовов, не вдаваясь в детали базовая HTTP-библиотека.

Я не думаю, что невидимая автоматизация распараллеливания является хорошей идеей, так что вызывающий код явно говорит о своих ожиданиях. Но я думаю, что что-то вроде следующего синтаксиса блока может быть чрезвычайно полезным для разработчиков, которые могут использовать интерфейс, когда они знают, что набор запросов не зависит друг от друга.

# possible implementation?
user = User.find(1)
User.parallel do
  f = user.foo
  b = user.bar
end

Возможно ли это? Как я могу сделать это, используя Ruby 1.9.2?

Ответы [ 2 ]

1 голос
/ 25 января 2012

Прозрачное распараллеливание обычно осуществляется через то, что называется будущим.В ruby, у ленивых и многообещающих драгоценных камней есть реализация фьючерсов.Вот пример с обещанием gem:

require 'future'
user = User.find(1)
f = future{user.foo}
b = future{user.bar}

Будущее будет выполнять вычисления в блоке в фоновом потоке, и любая попытка работать с f или b будет блокироваться, если фоновый поток уже не запущен взавершение.

Как разработчик библиотеки, если ваша библиотека является поточно-ориентированной, во многих случаях это будет хорошо, хотя, вероятно, она не так хорошо масштабируется в ruby.

1 голос
/ 24 января 2012

То, как это работает с использованием асинхронного SQL, выглядит примерно так:

User.where(:id => 1).async_each do |user|
  Foo.where(:id => user.foo_id).async_each do |foo|
    # ... Do stuff with foo ...
  end
  Bar.where(:id => user.bar_id).async_each do |bar|
    # ... Do stuff with foo ...
  end
end

Это мой опыт работы с асинхронным сиквелом, похожим на ActiveRecord.

Имейте в виду, что это множество обратных вызовов, сложенных вместе, поэтому, если вы не будете осторожны, все может измениться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...