From 1d2d72b8ce781f2907e5ae4d4cfd3385fcce3ab9 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sun, 6 Apr 2025 20:52:57 +0100 Subject: [PATCH] Improve retry strategies for Last.fm refresh --- lib/last_fm/api.ex | 28 ++++++++++++++++++++++++++++ lib/last_fm/refresh.ex | 9 ++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/last_fm/api.ex b/lib/last_fm/api.ex index d2eef0cb..09a48997 100644 --- a/lib/last_fm/api.ex +++ b/lib/last_fm/api.ex @@ -24,6 +24,34 @@ defmodule LastFm.API do defp map_error(16), do: :transient_error defp map_error(26), do: :suspended_api_key defp map_error(29), do: :rate_limit_exceeded + + @doc """ + Returns true if the error is retryable, false otherwise. + """ + def retryable_error?(error) + when error in [ + :transient_error, + :service_offline, + :rate_limit_exceeded, + :operation_failed + ], + do: true + + def retryable_error?(_error), do: false + + @doc """ + Returns the recommended retry delay in milliseconds for retryable errors. + Returns nil for non-retryable errors. + """ + # 1 minute + def retry_delay(:rate_limit_exceeded), do: 60_000 + # 30 seconds + def retry_delay(:service_offline), do: 30_000 + # 5 seconds + def retry_delay(:transient_error), do: 5_000 + # 5 seconds + def retry_delay(:operation_failed), do: 5_000 + def retry_delay(_), do: nil end def get_recent_tracks(config) do diff --git a/lib/last_fm/refresh.ex b/lib/last_fm/refresh.ex index 215f6a0b..40152818 100644 --- a/lib/last_fm/refresh.ex +++ b/lib/last_fm/refresh.ex @@ -92,9 +92,12 @@ defmodule LastFm.Refresh do Feed.update(tracks) {:noreply, config, config.refresh_interval} - {:error, _reason} -> - # TODO: think about failure scenario - error is logged at the API level - {:noreply, config, config.refresh_interval} + {:error, error} -> + if API.ErrorResponse.retryable_error?(error) do + {:noreply, config, API.ErrorResponse.retry_delay(error)} + else + {:stop, error, config} + end end end end