72 lines
1.9 KiB
Elixir
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
|