What would be the best approach to poll a weather API? I want to continually call the function get_weather_from_locations() which returns an array of locations and their weather (high / low). Essentially, I want to display to user the latest weather for each location and update every minute or so.
def init(:ok) do
ny_weather = %{}
la_weather = %{}
{:ok, {ny_weather, la_weather}}
end
def handle_call({:poll, name}, _from, state) do
{ny_weather, la_weather} = state
# TODO: call API and push the new weather result onto ny_weather and la_weather respectively
{:reply, state}
end
You can use Process.send_after/4 to schedule a message to the GenServer after a given number of milliseconds. The message will be received in a handle_info callback, where you can reschedule the next poll:
def init(:ok) do
ny_weather = %{}
la_weather = %{}
send(self(), :poll) # Immediately schedule the first poll
{:ok, {ny_weather, la_weather}}
end
def handle_info(:poll, state) do
# TODO: perform the call and update the state
# Re-schedule the next poll in 1 minute (60_000 ms):
Process.send_after(self, :poll, 60_000)
{:noreply, state}
end
Use info to schedule polling, in handle_info/2 you can cache the weather result in state.
Use call to get the cached weather result, in handle_call/3 return weather result in state.
handle_call returns a tuple, when you are sending back a response, the tuple should be {:reply, whatever_value_you_want, state} , the first item :reply means you want to send a response back to the caller, the second item is the actual response, and the third item is the new state of your GenServer. If you don’t want to respond, then return a tuple {:noreply, state}.