Current section

Files

Jump to
elixir_cache lib cache persistent_term.ex
Raw

lib/cache/persistent_term.ex

defmodule Cache.PersistentTerm do
@moduledoc """
`:persistent_term` adapter for storing rarely-written, frequently-read cached values.
This adapter stores values in Erlang's `:persistent_term` storage, which provides
extremely fast read access at the cost of more expensive writes and deletes.
It is best suited for configuration values or other data that changes infrequently.
TTL is not supported — values persist until explicitly deleted.
## Example
```elixir
defmodule MyApp.Cache do
use Cache,
adapter: Cache.PersistentTerm,
name: :my_app_persistent_cache,
opts: []
end
```
"""
use Task, restart: :permanent
@behaviour Cache
@impl Cache
def opts_definition, do: []
@impl Cache
def start_link(opts) do
Task.start_link(fn ->
_table_name = opts[:table_name]
Process.hibernate(Function, :identity, [nil])
end)
end
@impl Cache
def child_spec({cache_name, opts}) do
%{
id: "#{cache_name}_elixir_cache_persistent_term",
start: {Cache.PersistentTerm, :start_link, [Keyword.put(opts, :table_name, cache_name)]}
}
end
@impl Cache
@spec get(atom, atom | String.t(), Keyword.t()) :: ErrorMessage.t_res(any)
def get(cache_name, key, _opts \\ []) do
{:ok, :persistent_term.get({cache_name, key}, nil)}
rescue
exception ->
{:error, ErrorMessage.internal_server_error(Exception.message(exception), %{cache: cache_name, key: key})}
end
@impl Cache
@spec put(atom, atom | String.t(), pos_integer | nil, any, Keyword.t()) :: :ok | ErrorMessage.t()
def put(cache_name, key, _ttl \\ nil, value, _opts \\ []) do
:persistent_term.put({cache_name, key}, value)
:ok
rescue
exception ->
{:error, ErrorMessage.internal_server_error(Exception.message(exception), %{cache: cache_name, key: key})}
end
@impl Cache
@spec delete(atom, atom | String.t(), Keyword.t()) :: :ok | ErrorMessage.t()
def delete(cache_name, key, _opts \\ []) do
:persistent_term.erase({cache_name, key})
:ok
rescue
exception ->
{:error, ErrorMessage.internal_server_error(Exception.message(exception), %{cache: cache_name, key: key})}
end
end