Skip to content

Commit 5c53eee

Browse files
committed
Added more efficient caching logic for random projects by using the logic behind random devlogs
1 parent 64b22e4 commit 5c53eee

2 files changed

Lines changed: 101 additions & 12 deletions

File tree

lib/ftpdb/DB.ex

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,22 +258,108 @@ defmodule Ftpdb.DB do
258258
end)
259259
end
260260

261-
def random_projects(limit \\ 10) do
261+
defp get_max_project_id do
262262
{:ok, response} =
263-
client()
264-
|> Supabase.PostgREST.rpc("get_random_projects", %{limit_count: limit})
263+
Supabase.PostgREST.from(client(), "projects")
264+
|> Supabase.PostgREST.select(["id"])
265+
|> Supabase.PostgREST.order("id", desc: true)
266+
|> Supabase.PostgREST.limit(1)
267+
|> Map.put(:method, :get)
265268
|> Supabase.PostgREST.execute()
266269

267-
response.body
268-
|> Enum.map(fn item ->
269-
total_hours = item["stat_total_hours"] || 0
270-
duration = item["stat_total_duration_seconds"] || total_hours * 3600
270+
case response.body do
271+
[%{"id" => max_id}] -> max_id
272+
_ -> 0
273+
end
274+
end
271275

272-
item
273-
|> Map.drop(["stat_total_duration_seconds"])
274-
|> Map.put("total_duration_seconds", duration)
275-
|> Map.put("total_hours", total_hours)
276-
end)
276+
defp fetch_and_format_project_for_random(id) do
277+
result =
278+
Supabase.PostgREST.from(client(), "projects")
279+
|> Supabase.PostgREST.select([
280+
"id",
281+
"title",
282+
"banner_url",
283+
"stat_total_duration_seconds",
284+
"stat_hot_score",
285+
"stat_total_likes"
286+
])
287+
|> Supabase.PostgREST.eq("id", id)
288+
|> Map.put(:method, :get)
289+
|> Supabase.PostgREST.execute()
290+
291+
case result do
292+
{:ok, %{body: [item]}} when not is_nil(item) ->
293+
banner_url = item["banner_url"]
294+
295+
if is_nil(banner_url) or
296+
banner_url == "https://flavortown.hackclub.com/assets/default-banner-3d4e1b67.png" do
297+
nil
298+
else
299+
user_id = get_user_id(item["id"])
300+
301+
{user_avatar, user_display_name} =
302+
if user_id do
303+
case get_user_info(user_id) do
304+
[u] -> {u.avatar_url, u.display_name || "Unknown User"}
305+
_ -> {nil, "Unknown User"}
306+
end
307+
else
308+
{nil, "Unknown User"}
309+
end
310+
311+
duration = item["stat_total_duration_seconds"] || 0
312+
313+
%{
314+
id: to_string(item["id"]),
315+
title: item["title"],
316+
banner_url: banner_url,
317+
display_name: user_display_name,
318+
avatar_url: user_avatar,
319+
stat_hot_score: item["stat_hot_score"] || 0,
320+
stat_total_likes: item["stat_total_likes"] || 0,
321+
total_duration_seconds: duration,
322+
total_hours: div(duration, 3600)
323+
}
324+
end
325+
326+
_ ->
327+
nil
328+
end
329+
end
330+
331+
def random_projects(limit \\ 10) do
332+
max_id = get_max_project_id()
333+
334+
if max_id == 0 do
335+
[]
336+
else
337+
random_ids =
338+
1..(limit * 10)
339+
|> Enum.map(fn _ -> :rand.uniform(max_id) end)
340+
|> Enum.uniq()
341+
342+
random_ids
343+
|> Enum.reduce_while([], fn id, acc ->
344+
if length(acc) >= limit do
345+
{:halt, acc}
346+
else
347+
project =
348+
Cachex.fetch!(
349+
:random_project_cache,
350+
to_string(id),
351+
fn _key -> fetch_and_format_project_for_random(id) end,
352+
expiration: :timer.minutes(30)
353+
)
354+
355+
if project do
356+
{:cont, [project | acc]}
357+
else
358+
{:cont, acc}
359+
end
360+
end
361+
end)
362+
end
277363
end
278364

279365
def search_projects(query) when is_binary(query) do

lib/ftpdb/application.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ defmodule Ftpdb.Application do
1414
Supervisor.child_spec({Cachex, name: :random_devlog_cache},
1515
id: :random_devlog_cache_worker
1616
),
17+
Supervisor.child_spec({Cachex, name: :random_project_cache},
18+
id: :random_project_cache_worker
19+
),
1720
Supervisor.child_spec({Cachex, name: :user_id_cache}, id: :user_id_cache_worker),
1821
Supervisor.child_spec({Cachex, name: :hot_cache}, id: :hot_cache_worker),
1922
Supervisor.child_spec({Cachex, name: :top_week_cache}, id: :top_week_cache_worker),

0 commit comments

Comments
 (0)