legendary-doc-site/apps/admin/kaffy/lib/kaffy/cache/table.ex
2020-07-27 20:28:41 +00:00

72 lines
1.9 KiB
Elixir

defmodule Kaffy.Cache.Table do
@moduledoc false
@table_name :kaffy_cache
@expire_suffix "_expires"
@doc """
Prepare keys and add key value to the cache
"""
def add_to_cache(key, suffix, value, expire_after \\ 600) do
string_key = stringify_key([key, suffix])
expiration_key = stringify_key([key, suffix, @expire_suffix])
expiration_date = DateTime.utc_now() |> DateTime.add(expire_after)
cache_value(string_key, value)
cache_value(expiration_key, expiration_date)
end
@doc false
defp cache_value(key, value) do
create_table(@table_name)
:ets.insert(@table_name, {key, value})
end
@doc """
Create a new ETS table if undefined
"""
def create_table(name \\ @table_name) do
case :ets.info(name) do
:undefined -> :ets.new(name, [:named_table])
ref -> ref
end
end
@doc """
Get value from the cache ETS table, check if the key is expired
return nil if key doesn't exist or if it's expired
"""
def get_from_cache(key, suffix) do
create_table(@table_name)
final_key = stringify_key([key, suffix])
expiration_key = stringify_key([key, suffix, @expire_suffix])
case :ets.lookup(@table_name, final_key) do
[] ->
nil
[{_k, value}] ->
case :ets.lookup(@table_name, expiration_key) do
[] ->
:ets.delete(@table_name, final_key)
:ets.delete(@table_name, expiration_key)
nil
[{_, expiration_date}] ->
now = DateTime.utc_now()
case DateTime.compare(expiration_date, now) do
:lt ->
:ets.delete(@table_name, final_key)
:ets.delete(@table_name, expiration_key)
nil
_eq_or_gt ->
value
end
end
end
end
@doc false
defp stringify_key(list), do: list |> Enum.map(fn x -> to_string(x) end) |> Enum.join("_")
end