diff --git a/lib/frenzy/update_feeds.ex b/lib/frenzy/update_feeds.ex index 2f71087..54c6c4a 100644 --- a/lib/frenzy/update_feeds.ex +++ b/lib/frenzy/update_feeds.ex @@ -24,6 +24,11 @@ defmodule Frenzy.UpdateFeeds do {:noreply, state} end + def handle_cast({:update_feed, feed_id, retry_count}, state) do + update_feed(Repo.get(Feed, feed_id), retry_count) + {:noreply, state} + end + def handle_info(:update_feeds, state) do update_feeds() schedule_update() @@ -103,22 +108,22 @@ defmodule Frenzy.UpdateFeeds do Logger.info("Converted #{count} read items to tombstones") end - defp update_feed(feed) do + defp update_feed(feed, retry_count \\ 0) do Logger.debug("Updating #{feed.feed_url}") case URI.parse(feed.feed_url) do %URI{scheme: "gemini"} = uri -> - update_feed_gemini(feed, uri) + update_feed_gemini(feed, uri, retry_count) %URI{scheme: scheme} when scheme in ["http", "https"] -> - update_feed_http(feed) + update_feed_http(feed, retry_count) %URI{scheme: scheme} -> Logger.warn("Unhandled scheme for feed: #{scheme}") end end - defp update_feed_http(feed) do + defp update_feed_http(feed, retry_count) do case Network.http_get(feed.feed_url) do {:ok, %Tesla.Env{ @@ -148,29 +153,45 @@ defmodule Frenzy.UpdateFeeds do end {:error, reason} -> - Logger.error("Couldn't load feed #{feed.feed_url}: #{inspect(reason)}") - - if Frenzy.sentry_enabled?() do - Sentry.capture_message("Error loading HTTP feed: #{inspect(reason)}", - extra: %{feed_id: feed.id, feed_url: feed.feed_url} + if retry_count < 5 do + Process.send_after( + self(), + {:update_feed, feed, retry_count + 1}, + trunc(:math.pow(4, retry_count)) * 1000 ) + else + Logger.error("Couldn't load feed #{feed.feed_url}: #{inspect(reason)}") + + if Frenzy.sentry_enabled?() do + Sentry.capture_message("Error loading HTTP feed: #{inspect(reason)}", + extra: %{feed_id: feed.id, feed_url: feed.feed_url} + ) + end end end end - defp update_feed_gemini(feed, feed_uri) do + defp update_feed_gemini(feed, feed_uri, retry_count) do case Network.gemini_request(feed_uri) do {:ok, %Gemini.Response{meta: content_type, body: body}} -> do_update_feed(feed, content_type, body) {:error, reason} -> - Logger.error("Couldn't load feed #{feed.feed_url}: #{inspect(reason)}") - - if Frenzy.sentry_enabled?() do - Sentry.capture_message( - "Error loading Gemini feed: #{inspect(reason)}", - extra: %{feed_id: feed.id, feed_url: feed.feed_url} + if retry_count < 5 do + Process.send_after( + self(), + {:update_feed, feed, retry_count + 1}, + trunc(:math.pow(4, retry_count)) * 1000 ) + else + Logger.error("Couldn't load feed #{feed.feed_url}: #{inspect(reason)}") + + if Frenzy.sentry_enabled?() do + Sentry.capture_message( + "Error loading Gemini feed: #{inspect(reason)}", + extra: %{feed_id: feed.id, feed_url: feed.feed_url} + ) + end end end end