Я изучаю Эликсир с Фениксом. Я легко создал несколько серверов REST API, но есть еще одно требование, которое мне нужно выполнить. Мне нужно иметь возможность выполнять параллельные или асинхронные задачи для вызова / выполнения некоторого API из внутреннего интерфейса и поместить эти результаты в ответ JSON.
Вот как бы я это реализовал примерно из Go и C #
// Golang
userCount := make(chan int)
usersList := make(chan []Users)
go getAggregateUserCounts(userCount)
go getGetUsersList(usersList)
// do other heavy tasks from here
httpJsonResponse(map[string]interface{}{
"test": 1,
"user_count": <-userCount,
"users_list": <- usersList ,
})
// C# or dotnetcore
public async Task<JsonResult> GetJson(string dbName, string collection)
{
using(var client = new MongoDBCon())
{
// some heavy computations
var documents = await col.FindAsync<Users>(FilterDefinition<Users>.Empty);
return Json(new {
users_count: await documents.ToListAsync().Result.Count,
users: await users.GetusersList()
});
}
}
Пока что у меня есть эликсир:
// Elixir
def start do
IO.puts "starting.."
response = %{}
1..3
|> Enum.map(fn(id) -> async_get_request(id) end)
|> Enum.each(
fn(_) ->
item = get_result()
IO.inspect :"#{item[:user][:id]}"
IO.inspect item[:user]
# Map.put(response, :"#{item[:user][:id]}", item[:user])
end)
IO.puts "done.."
IO.inspect response
end
def start2 do
IO.puts "start2.."
res = %{
"item" => Task.async(fn -> IO.puts "weee" end)
}
end
def get_request(id) do
sleep = :rand.uniform(10)
:timer.sleep(sleep)
%{user: %{id: id, sleep: sleep}}
end
def async_get_request(id) do
caller = self()
spawn(fn ->
send(caller, {:result, get_request(id)})
end)
end
def get_result do
receive do
{:result, result} -> result
end
end
результат
iex(3)> Para.start
starting..
%{id: 2, sleep: 1}
%{id: 3, sleep: 3}
%{id: 1, sleep: 9}
done..
%{}
что я хочу - это
%{
id: 2, {id: 2, sleep: 1},
id: 3, {id: 3, sleep: 3},
id: 1, {id: 1, sleep: 9}
}
Приведенный выше пример предназначен только для обучения или практики, но для реального мира я бы предпочел добавить значения на карту с помощью некоторых параллельных задач.
Я не уверен, возможно ли это с эликсиром.
%{
"users_count": AsyncUsersModule.GetUsersTotal(),
"users_list": AsyncUsersModule.GetUsersList()
}
и ответ в json должен быть
{
"users_count": 10000,
"users_list": []
}
Я знаю, что мне все еще нужно много практиковаться и читать, мне просто нужна помощь.