I am learning Elixir with Phoenix. I built a few REST API servers, easily, but there is one more requirement that I need to implement. I need to be able to do parallel or async tasks to call/execute some API from the Backend, and put those results to a JSON response.
This is how I would implement it roughly from Go and 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()
});
}
}
So far, this is what I have for elixir:
// 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
the result is
iex(3)> Para.start
starting..
%{id: 2, sleep: 1}
%{id: 3, sleep: 3}
%{id: 1, sleep: 9}
done..
%{}
what I want is to have, is
%{
id: 2, {id: 2, sleep: 1},
id: 3, {id: 3, sleep: 3},
id: 1, {id: 1, sleep: 9}
}
The above example is just for learning or practice, but for real world, I would prefer adding values to the map by some parallel tasks.
I'm not sure if this is even possible with elixir.
%{
"users_count": AsyncUsersModule.GetUsersTotal(),
"users_list": AsyncUsersModule.GetUsersList()
}
and response in json should be
{
"users_count": 10000,
"users_list": []
}
I know I still need lots of practice and reading, I just need some help.