Как распараллелить внешние вызовы API с помощью Elixir, чтобы сделать их очень быстрыми

Я работаю над приложением Phoenix, которое использует API Instagram через Эликстаграмма библиотека. Есть конкретная страница, на которой мне нужно отобразить группу пользователей, которых нужно получить из API… Вот код «до» (последовательный):

def users_list(%Account{favourite_users: users}) do  
  Elixtagram.configure
  users
  |> Enum.map(fn(u) -> Elixtagram.user(u.ig_id).username end)
  |> Enum.join(", ")
end  

Здесь я просто передаю список идентификаторов Instagram и возвращаю строку имен пользователей, разделенных запятыми. Очевидная проблема здесь заключается в том, что Elixtagram выполняет вызов API, который может занять относительно большое количество миллисекунд, и глупо ждать завершения каждого из них, прежде чем запускать следующий, особенно когда мы используем язык с таким легкодоступным параллелизм как Эликсир.

Вот «фиксированный» код:

def users_list(%Account{favourite_users: users}) do  
  Elixtagram.configure
  users
  |> Enum.map(fn(u) -> Task.async(fn -> Elixtagram.user(u.ig_id).username end) end)
  |> Enum.map(&Task.await/1)
  |> Enum.join(", ")
end  

Разница здесь в том, что вместо блокировки для каждого запроса в Enum.map я заполняю список асинхронными задачами, которые затем жду в следующей строке. Это означает, что количество запросов, которые мы делаем здесь, мало влияет на производительность кода (пока мы не перегрузим сеть…).

Удачи в ваших параллельных приключениях, друзья!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *