Skip to content

Commit 16e908f

Browse files
committed
feat: improve GitHub API caching with binary storage and better error handling
1 parent 3cb0761 commit 16e908f

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

lib/algora/admin/admin.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ defmodule Algora.Admin do
6161
:ok <- update_tickets(url, repo.id) do
6262
{:ok, repo}
6363
else
64+
{:error, "404 Not Found"} = error ->
65+
error
66+
6467
error ->
6568
Logger.error("Failed to backfill repo #{url}: #{inspect(error)}")
6669
{:error, error}

lib/algora/integrations/github/client.ex

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,12 @@ defmodule Algora.Github.Client do
88

99
@type token :: String.t()
1010

11+
defp migration?, do: System.get_env("MIGRATION", "false") == "true"
12+
1113
def http(host, method, path, headers, body) do
1214
# TODO: remove after migration
13-
if System.get_env("MIGRATION", "false") == "true" do
14-
cache_path = ".local/github/#{path}.json"
15-
16-
with :error <- read_from_cache(cache_path),
17-
{:ok, response_body} <- do_http_request(host, method, path, headers, body) do
18-
write_to_cache(cache_path, response_body)
19-
{:ok, response_body}
20-
else
21-
{:ok, cached_data} -> {:ok, cached_data}
22-
{:error, reason} -> {:error, reason}
23-
end
15+
if migration?() do
16+
run_cached(path, fn -> do_http_request(host, method, path, headers, body) end)
2417
else
2518
do_http_request(host, method, path, headers, body)
2619
end
@@ -63,20 +56,47 @@ defmodule Algora.Github.Client do
6356

6457
defp maybe_handle_error(body), do: {:ok, body}
6558

66-
defp read_from_cache(cache_path) do
59+
defp run_cached(path, fun) do
60+
case read_from_cache(path) do
61+
:not_found ->
62+
Logger.warning("❌ Cache miss for #{path}")
63+
write_to_cache!(fun.(), path)
64+
65+
res ->
66+
res
67+
end
68+
end
69+
70+
defp get_cache_path(path), do: ".local/github/#{path}.bin"
71+
72+
defp maybe_retry({:ok, %{"message" => "Moved Permanently"}}), do: :not_found
73+
defp maybe_retry({:ok, data}), do: {:ok, data}
74+
defp maybe_retry({:error, "404 Not Found"}), do: {:error, "404 Not Found"}
75+
defp maybe_retry(_error), do: :not_found
76+
77+
def read_from_cache(path) do
78+
cache_path = get_cache_path(path)
79+
6780
if File.exists?(cache_path) do
6881
case File.read(cache_path) do
69-
{:ok, content} -> Jason.decode(content)
70-
{:error, _} -> :error
82+
{:ok, content} ->
83+
content
84+
|> :erlang.binary_to_term()
85+
|> maybe_retry()
86+
87+
{:error, _} ->
88+
:not_found
7189
end
7290
else
73-
:error
91+
:not_found
7492
end
7593
end
7694

77-
defp write_to_cache(cache_path, data) do
95+
defp write_to_cache!(data, path) do
96+
cache_path = get_cache_path(path)
7897
File.mkdir_p!(Path.dirname(cache_path))
79-
File.write!(cache_path, Jason.encode!(data))
98+
File.write!(cache_path, :erlang.term_to_binary(data))
99+
data
80100
end
81101

82102
def fetch(access_token, url, method \\ "GET", body \\ nil)

0 commit comments

Comments
 (0)