Elixir: Making Concurrent API Calls 
angelcool@fedora-laptop$
angelcool@fedora-laptop$date
Fri Apr 12 07:51:16 PM PDT 2024
angelcool@fedora-laptop$ls lib/
coolprogram.ex coordinator.ex worker.ex
angelcool@fedora-laptop$cat lib/coolprogram.ex
defmodule CoolProgram do
def temperature_of(cities) do
coordinator_pid = spawn(CoolProgram.Coordinator, :loop, [[], Enum.count(cities)])
cities |> Enum.each(fn city ->
worker_pid = spawn(CoolProgram.Worker, :loop, [])
send(worker_pid, {coordinator_pid, city})
end)
end
end
angelcool@fedora-laptop$cat lib/coordinator.ex
defmodule CoolProgram.Coordinator do

def loop(results \\ [], results_expected) do
receive do
{:ok, result} ->
new_results = [result|results]
if results_expected == Enum.count(new_results) do
send(self(), :exit)
end
loop(new_results, results_expected)
:exit ->
IO.puts(results |> Enum.sort |> Enum.join(", "))
_->
loop(results, results_expected)
end
end

end
angelcool@fedora-laptop$cat lib/worker.ex
defmodule CoolProgram.Worker do

def temperature_of(location) do
result = url_for(location)
|> HTTPoison.get
|> parse_response
case result do
{:ok, temp} ->
"#{location}: #{temp}° C"
:error ->
"#{location} not found"
end
end

defp url_for(location) do
location = URI.encode(location)
"http://api.openweathermap.org/data/2.5/weather?q=#{location}&appid=#{apikey()}"
end

defp parse_response({:ok, %HTTPoison.Response{body: body, status_code: 200}}) do
body
|> JSON.decode!
|> compute_temperature()
end

defp parse_response(_) do
:error
end

defp compute_temperature(json) do
try do
temp = (json["main"]["temp"]-273.15)
|> Float.round(1)
{:ok, temp}
rescue
_-> :error
end
end

defp apikey do
"XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
end

def loop do
receive do
{sender_pid, location}->
send(sender_pid, {:ok, temperature_of(location)})
_->
IO.puts "don't know how to process this message"
end
loop()
end
end
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$iex -S mix
Compiling 1 file (.ex)
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> cities=["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami", "Temecula", "Buenos Aires", "Ojai" ]
["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami",
"Temecula", "Buenos Aires", "Ojai"]
iex(2)> CoolProgram.temperature_of(cities)
:ok
Buenos Aires: 17.0° C, Los Angeles: 14.7° C, Merida: 25.0° C, Mexico City: 22.8° C, Miami: 22.0° C, Ojai: 14.2° C, San Diego: 15.2° C, Singapore: 30.8° C, Temecula: 13.1° C
iex(3)>


Comments
Comments are not available for this entry.
2024 By Angel Cool