···38383939- `mix atex.lexicons` now adds `@moduledoc false` to generated modules to stop
4040 them from automatically cluttering documentation.
4141+- `Atex.IdentityResolver.Cache.ETS` now uses ConCache instead of ETS directly,
4242+ with a 1-hour TTL for cached identity information.
41434244## [0.6.0] - 2025-11-25
4345
+35-22
lib/atex/identity_resolver/cache/ets.ex
···11defmodule Atex.IdentityResolver.Cache.ETS do
22+ @moduledoc """
33+ ConCache-based implementation for Identity Resolver caching.
44+55+ Stores identity information (DID and handle mappings) with a 1-hour TTL.
66+ Uses two separate cache entries per identity to allow lookups by either DID or handle.
77+ """
88+29 alias Atex.IdentityResolver.Identity
310 @behaviour Atex.IdentityResolver.Cache
411 use Supervisor
51266- @table :atex_identities
1313+ @cache :atex_identities_cache
1414+ @ttl_ms :timer.hours(1)
715816 def start_link(opts) do
99- Supervisor.start_link(__MODULE__, opts)
1717+ Supervisor.start_link(__MODULE__, opts, name: __MODULE__)
1018 end
11191220 @impl Supervisor
1321 def init(_opts) do
1414- :ets.new(@table, [:set, :public, :named_table])
1515- Supervisor.init([], strategy: :one_for_one)
2222+ children = [
2323+ {ConCache,
2424+ [
2525+ name: @cache,
2626+ ttl_check_interval: :timer.minutes(5),
2727+ global_ttl: @ttl_ms
2828+ ]}
2929+ ]
3030+3131+ Supervisor.init(children, strategy: :one_for_one)
1632 end
17331834 @impl Atex.IdentityResolver.Cache
1935 @spec insert(Identity.t()) :: Identity.t()
2036 def insert(identity) do
2121- # TODO: benchmark lookups vs match performance, is it better to use a "composite" key or two inserts?
2222- :ets.insert(@table, {{identity.did, identity.handle}, identity})
3737+ ConCache.put(@cache, {:did, identity.did}, identity)
3838+ ConCache.put(@cache, {:handle, identity.handle}, identity)
2339 identity
2440 end
25412642 @impl Atex.IdentityResolver.Cache
2743 @spec get(String.t()) :: {:ok, Identity.t()} | {:error, atom()}
2844 def get(identifier) do
2929- lookup(identifier)
4545+ case ConCache.get(@cache, {:did, identifier}) do
4646+ nil ->
4747+ case ConCache.get(@cache, {:handle, identifier}) do
4848+ nil -> {:error, :not_found}
4949+ identity -> {:ok, identity}
5050+ end
5151+5252+ identity ->
5353+ {:ok, identity}
5454+ end
3055 end
31563257 @impl Atex.IdentityResolver.Cache
3358 @spec delete(String.t()) :: :noop | Identity.t()
3459 def delete(identifier) do
3535- case lookup(identifier) do
6060+ case get(identifier) do
3661 {:ok, identity} ->
3737- :ets.delete(@table, {identity.did, identity.handle})
6262+ ConCache.delete(@cache, {:did, identity.did})
6363+ ConCache.delete(@cache, {:handle, identity.handle})
3864 identity
39654066 _ ->
4167 :noop
4242- end
4343- end
4444-4545- defp lookup(identifier) do
4646- case :ets.match(@table, {{identifier, :_}, :"$1"}) do
4747- [] ->
4848- case :ets.match(@table, {{:_, identifier}, :"$1"}) do
4949- [] -> {:error, :not_found}
5050- [[identity]] -> {:ok, identity}
5151- end
5252-5353- [[identity]] ->
5454- {:ok, identity}
5568 end
5669 end
5770end