Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exponential Backoff #14

Open
sntran opened this issue Jan 4, 2018 · 3 comments
Open

Exponential Backoff #14

sntran opened this issue Jan 4, 2018 · 3 comments

Comments

@sntran
Copy link
Owner

sntran commented Jan 4, 2018

Implement Exponential Backoff to conform with Google's best practice:

https://developers.google.com/maps/documentation/directions/web-service-best-practices#exponential-backoff

@jowi-dev
Copy link
Contributor

jowi-dev commented Nov 8, 2020

Is this still open? I could probably tackle it if need be

@sntran
Copy link
Owner Author

sntran commented Nov 8, 2020

@jowi-dev I'd love your help on this!

@lovebes
Copy link

lovebes commented Aug 9, 2024

I asked Perplexiity.ai to code up a sample Elixir using the example Python script in that referenced website:

defmodule Timezone do
  @api_key "YOUR_KEY_HERE"
  @timezone_base_url "https://maps.googleapis.com/maps/api/timezone/json"

  def get_timezone(lat, lng, timestamp) do
    params = URI.encode_query(%{
      "location" => "#{lat},#{lng}",
      "timestamp" => timestamp,
      "key" => @api_key
    })
    url = "#{@timezone_base_url}?#{params}"

    fetch_timezone(url, 0.1, 5)
  end

  defp fetch_timezone(url, current_delay, max_delay) do
    case Req.get(url) do
      {:ok, %Req.Response{status: 200, body: body}} ->
        result = Jason.decode!(body)
        handle_response(result)

      {:ok, %Req.Response{status: status}} when status != 200 ->
        IO.puts("Received non-200 response: #{status}")
        retry_or_fail(url, current_delay, max_delay)

      {:error, %Req.Error{reason: reason}} ->
        IO.puts("HTTP request failed: #{inspect(reason)}")
        retry_or_fail(url, current_delay, max_delay)
    end
  end

  defp handle_response(%{"status" => "OK", "timeZoneId" => time_zone_id}), do: {:ok, time_zone_id}
  defp handle_response(%{"status" => status, "errorMessage" => error_message}) when status != "OK" do
    IO.puts("API error: #{error_message}")
    {:error, error_message}
  end

  defp retry_or_fail(url, current_delay, max_delay) when current_delay > max_delay do
    raise "Too many retry attempts."
  end

  defp retry_or_fail(url, current_delay, max_delay) do
    IO.puts("Waiting #{current_delay} seconds before retrying.")
    :timer.sleep(round(current_delay * 1000))
    fetch_timezone(url, current_delay * 2, max_delay)
  end
end

I'll try to get to use this as a reference to create the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants