diff --git a/config/config.exs b/config/config.exs index 1ef86460..adbe62ba 100644 --- a/config/config.exs +++ b/config/config.exs @@ -88,7 +88,8 @@ config :music_library, Oban, {Oban.Plugins.Cron, crontab: [ # every 12 hours - {"0 */12 * * *", MusicLibrary.Worker.ApplyScrobbleRules} + {"0 */12 * * *", MusicLibrary.Worker.ApplyScrobbleRules}, + {"0 */12 * * *", MusicLibrary.Worker.PruneAssetCache} ]} ] diff --git a/lib/music_library/assets/cache.ex b/lib/music_library/assets/cache.ex index 8b63d318..00dfd362 100644 --- a/lib/music_library/assets/cache.ex +++ b/lib/music_library/assets/cache.ex @@ -14,4 +14,24 @@ defmodule MusicLibrary.Assets.Cache do [] -> :not_found end end + + def total_content_size do + :ets.foldl( + fn {_key, _inserted_at, content}, acc -> acc + byte_size(content) end, + 0, + __MODULE__ + ) + end + + def prune(older_than_seconds) do + threshold = + DateTime.utc_now() + |> DateTime.add(older_than_seconds * -1, :second) + |> DateTime.to_unix() + + :ets.select_delete( + __MODULE__, + [{{:"$1", :"$2", :"$3"}, [{:<, :"$2", threshold}], [true]}] + ) + end end diff --git a/lib/music_library/worker/prune_asset_cache.ex b/lib/music_library/worker/prune_asset_cache.ex new file mode 100644 index 00000000..f7aa266a --- /dev/null +++ b/lib/music_library/worker/prune_asset_cache.ex @@ -0,0 +1,18 @@ +defmodule MusicLibrary.Worker.PruneAssetCache do + use Oban.Worker, queue: :default, max_attempts: 3 + + require Logger + + alias MusicLibrary.Assets.Cache + + @one_week_seconds 60 * 60 * 24 * 7 + + @impl Oban.Worker + def perform(_) do + prune_count = Cache.prune(@one_week_seconds) + + Logger.info(fn -> + "Pruned #{prune_count} old cached assets. Cache size now #{Cache.total_content_size()} bytes." + end) + end +end