Exponential backoff retries for fetching feeds

This commit is contained in:
Shadowfacts 2022-04-18 18:14:58 -04:00
parent bbc729b5ca
commit a7a296b342
1 changed files with 37 additions and 16 deletions

View File

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