Add caching for emoji pack sharing

This commit is contained in:
Ekaterina Vaartis 2019-08-12 13:13:01 +03:00
commit ee620ecbf1
4 changed files with 50 additions and 3 deletions

View file

@ -102,10 +102,14 @@ defmodule Pleroma.Application do
build_cachex("rich_media", default_ttl: :timer.minutes(120), limit: 5000),
build_cachex("scrubber", limit: 2500),
build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500),
build_cachex("web_resp", limit: 2500)
build_cachex("web_resp", limit: 2500),
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10)
]
end
defp emoji_packs_expiration,
do: expiration(default: :timer.seconds(5 * 60), interval: :timer.seconds(60))
defp idempotency_expiration,
do: expiration(default: :timer.seconds(6 * 60 * 60), interval: :timer.seconds(60))

View file

@ -1,6 +1,8 @@
defmodule Pleroma.Web.EmojiAPI.EmojiAPIController do
use Pleroma.Web, :controller
require Logger
def reload(conn, _params) do
Pleroma.Emoji.reload()
@ -12,6 +14,8 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIController do
"emoji"
)
@cache_seconds_per_file Pleroma.Config.get!([:emoji, :shared_pack_cache_seconds_per_file])
def list_packs(conn, _params) do
pack_infos =
case File.ls(@emoji_dir_path) do
@ -66,13 +70,49 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIController do
end)
end
defp make_archive(name, pack, pack_dir) do
defp create_archive_and_cache(name, pack, pack_dir, md5) do
files =
['pack.yml'] ++
(pack["files"] |> Enum.map(fn {_, path} -> to_charlist(path) end))
{:ok, {_, zip_result}} = :zip.zip('#{name}.zip', files, [:memory, cwd: to_charlist(pack_dir)])
cache_ms = :timer.seconds(@cache_seconds_per_file * Enum.count(files))
Cachex.put!(
:emoji_packs_cache,
name,
# if pack.yml MD5 changes, the cache is not valid anymore
%{pack_yml_md5: md5, pack_data: zip_result},
# Add a minute to cache time for every file in the pack
ttl: cache_ms
)
Logger.debug("Create an archive for the '#{name}' shared emoji pack, \
keeping it in cache for #{div(cache_ms, 1000)}s")
zip_result
end
defp make_archive(name, pack, pack_dir) do
# Having a different pack.yml md5 invalidates cache
pack_yml_md5 = :crypto.hash(:md5, File.read!(Path.join(pack_dir, "pack.yml")))
maybe_cached_pack = Cachex.get!(:emoji_packs_cache, name)
zip_result =
if is_nil(maybe_cached_pack) do
create_archive_and_cache(name, pack, pack_dir, pack_yml_md5)
else
if maybe_cached_pack[:pack_yml_md5] == pack_yml_md5 do
Logger.debug("Using cache for the '#{name}' shared emoji pack")
maybe_cached_pack[:pack_data]
else
create_archive_and_cache(name, pack, pack_dir, pack_yml_md5)
end
end
zip_result
end