Skip to content

Commit cb04889

Browse files
committed
fix: cache expensive ops in Admin.CampaignLive
1 parent 1fc454f commit cb04889

File tree

2 files changed

+52
-46
lines changed

2 files changed

+52
-46
lines changed

lib/algora/workspace/workspace.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ defmodule Algora.Workspace do
460460
end
461461
end
462462

463+
def ensure_repo_tech_stack(_token, %{tech_stack: tech_stack}) when tech_stack != [] do
464+
{:ok, tech_stack}
465+
end
466+
463467
def ensure_repo_tech_stack(token, repository) do
464468
with {:ok, languages} <- Github.list_repository_languages(token, repository.user.provider_login, repository.name) do
465469
top_languages =

lib/algora_web/live/admin/campaign_live.ex

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -236,82 +236,84 @@ defmodule AlgoraWeb.Admin.CampaignLive do
236236

237237
defp render_preview(_template, _data), do: nil
238238

239+
defp repo_key(%{"repo_url" => repo_url}) when repo_url != "" do
240+
case repo_url |> String.split("/") |> Enum.take(-2) do
241+
[owner, name] -> {owner, name}
242+
_ -> nil
243+
end
244+
end
245+
246+
defp repo_key(%{"org_handle" => org_handle}) when org_handle != "" do
247+
org_handle
248+
end
249+
250+
defp repo_key(_row), do: nil
251+
239252
defp assign_repo_names(socket) do
240-
new_handles =
253+
new_keys =
241254
socket.assigns.csv_data
242-
|> Enum.filter(&(&1["repo_url"] == "" and &1["org_handle"] != ""))
243-
|> Enum.map(& &1["org_handle"])
255+
|> Enum.map(&repo_key/1)
256+
|> Enum.reject(&is_nil/1)
244257
|> Enum.reject(&Map.has_key?(socket.assigns.repo_cache, &1))
245258
|> Enum.uniq()
246259

247260
new_cache =
248-
Map.new(new_handles, fn org_handle ->
261+
Map.new(new_keys, fn key ->
262+
filter =
263+
case key do
264+
{owner, name} ->
265+
token = Admin.token()
266+
267+
with {:ok, repository} <- Workspace.ensure_repository(token, owner, name),
268+
{:ok, _tech_stack} <- Workspace.ensure_repo_tech_stack(token, repository) do
269+
dynamic([r, _u], r.id == ^repository.id)
270+
else
271+
_ -> false
272+
end
273+
274+
org_handle ->
275+
dynamic([r, u], u.handle == ^org_handle)
276+
end
277+
249278
repo =
250279
Repo.one(
251280
from r in Repository,
252281
join: u in assoc(r, :user),
253-
where: u.handle == ^org_handle,
282+
where: ^filter,
254283
order_by: [desc: fragment("(?->>'stargazers_count')::integer", r.provider_meta)],
255284
select: %{
256285
repo_owner: u.provider_login,
257286
repo_name: r.name,
258-
tech_stack: fragment("COALESCE(?, ?)", u.tech_stack, r.tech_stack)
287+
tech_stack: fragment("COALESCE(NULLIF(?, '{}'), ?)", u.tech_stack, r.tech_stack)
259288
},
260289
limit: 1
261290
)
262291

263292
if repo && repo.tech_stack != [] do
264293
matches = Settings.get_tech_matches(List.first(repo.tech_stack))
265-
{org_handle, {repo, matches}}
294+
{key, {repo, matches}}
266295
else
267-
{org_handle, nil}
296+
{key, nil}
268297
end
269298
end)
270299

271300
updated_cache = Map.merge(socket.assigns.repo_cache, new_cache)
272301

273302
csv_data =
274-
Enum.map(socket.assigns.csv_data, fn row ->
275-
cond do
276-
is_binary(row["repo_url"]) and row["repo_url"] != "" ->
277-
repo_url = row["repo_url"]
278-
[owner, name] = repo_url |> String.split("/") |> Enum.take(-2)
279-
280-
token = Admin.token!()
281-
282-
with {:ok, repository} <- Workspace.ensure_repository(token, owner, name),
283-
{:ok, tech_stack} <- Workspace.ensure_repo_tech_stack(token, repository) do
284-
matches = if tech_stack == [], do: [], else: Settings.get_tech_matches(List.first(tech_stack))
285-
303+
Enum.map(socket.assigns.csv_data, fn
304+
row ->
305+
case Map.get(updated_cache, repo_key(row)) do
306+
{repo, matches} ->
286307
Map.merge(row, %{
287-
"repo_owner" => repository.user.provider_login,
288-
"repo_name" => repository.name,
289-
"tech_stack" => repository.tech_stack,
308+
"repo_owner" => repo.repo_owner,
309+
"repo_name" => repo.repo_name,
310+
"tech_stack" => repo.tech_stack,
290311
"matches" => Enum.map(matches, & &1.user.handle)
291312
})
292-
else
293-
error ->
294-
Logger.error("Failed to fetch repository #{owner}/#{name}: #{inspect(error)}")
295-
row
296-
end
297-
298-
org_handle = row["org_handle"] ->
299-
case Map.get(updated_cache, org_handle) do
300-
nil ->
301-
row
302-
303-
{repo, matches} ->
304-
Map.merge(row, %{
305-
"repo_owner" => repo.repo_owner,
306-
"repo_name" => repo.repo_name,
307-
"tech_stack" => repo.tech_stack,
308-
"matches" => Enum.map(matches, & &1.user.handle)
309-
})
310-
end
311-
312-
true ->
313-
row
314-
end
313+
314+
_ ->
315+
row
316+
end
315317
end)
316318

317319
csv_columns =

0 commit comments

Comments
 (0)