Built-in ETS-based dedup store using ConCache (TTL-enabled ETS wrapper by Saša Jurić).
Requires the con_cache optional dependency:
{:con_cache, "~> 1.1"}Setup
Add to your supervision tree:
children = [
MPP.Tempo.ConCacheStore.child_spec(ttl: to_timeout(minute: 10))
]Then pass in method_config:
plug MPP.Plug,
method: MPP.Methods.Tempo,
method_config: %{
"rpc_url" => "https://rpc.moderato.tempo.xyz",
"store" => MPP.Tempo.ConCacheStore
}If you override the cache name in your supervision tree, pass the same name in
method_config:
children = [
MPP.Tempo.ConCacheStore.child_spec(name: :my_custom_dedup, ttl: to_timeout(minute: 10))
]
plug MPP.Plug,
method: MPP.Methods.Tempo,
method_config: %{
"rpc_url" => "https://rpc.moderato.tempo.xyz",
"store" => {MPP.Tempo.ConCacheStore, name: :my_custom_dedup}
}TTL and Challenge Expiry
The store's TTL must be ≥ your challenge expires_in to prevent replay.
If the cache evicts a tx hash before the challenge expires, the same tx can
be replayed. A good default is 2× the challenge expiry.
Example: if your Plug uses expires_in: 300 (5 min), set the store TTL to
at least to_timeout(minute: 10).
Options
:ttl— time-to-live for entries in milliseconds. Default: 5 minutes.:name— registered name for the ConCache process. Default::mpp_tempo_dedup. Override to avoid child ID collisions if your app already supervises other ConCache instances.:ttl_check_interval— how often to sweep expired entries. Default: 30 seconds.
Summary
Functions
Atomically reserves a dedup key in the default ConCache.
Atomically reserves a dedup key, optionally using a non-default ConCache name from opts.
Returns a child spec for the ConCache process.
Looks up a dedup key in the default ConCache.
Looks up a dedup key, optionally using a non-default ConCache name from opts.
Stores a dedup key in the default ConCache.
Stores a dedup key, optionally using a non-default ConCache name from opts.
Functions
Atomically reserves a dedup key in the default ConCache.
Atomically reserves a dedup key, optionally using a non-default ConCache name from opts.
Same as check_and_mark/2 when opts is [].
@spec child_spec(keyword()) :: Supervisor.child_spec()
Returns a child spec for the ConCache process.
Start under your application's supervision tree:
children = [
MPP.Tempo.ConCacheStore.child_spec(ttl: :timer.minutes(10))
]The child spec id is {MPP.Tempo.ConCacheStore, name} to avoid collisions
with other ConCache instances in the same supervisor.
Looks up a dedup key in the default ConCache.
Looks up a dedup key, optionally using a non-default ConCache name from opts.
Same as get/1 when opts is [].
Stores a dedup key in the default ConCache.
Stores a dedup key, optionally using a non-default ConCache name from opts.
Same as put/2 when opts is [].