MPP.Tempo.ConCacheStore (mpp v0.6.2)

Copy Markdown View Source

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

check_and_mark(key, value)

@spec check_and_mark(String.t(), term()) :: :ok | {:error, :already_exists}

Atomically reserves a dedup key in the default ConCache.

check_and_mark(key, value, opts)

@spec check_and_mark(String.t(), term(), keyword()) :: :ok | {:error, :already_exists}

Atomically reserves a dedup key, optionally using a non-default ConCache name from opts.

Same as check_and_mark/2 when opts is [].

child_spec(opts \\ [])

@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.

get(key)

@spec get(String.t()) :: {:ok, term()} | :not_found

Looks up a dedup key in the default ConCache.

get(key, opts)

@spec get(
  String.t(),
  keyword()
) :: {:ok, term()} | :not_found

Looks up a dedup key, optionally using a non-default ConCache name from opts.

Same as get/1 when opts is [].

put(key, value)

@spec put(String.t(), term()) :: :ok

Stores a dedup key in the default ConCache.

put(key, value, opts)

@spec put(String.t(), term(), keyword()) :: :ok

Stores a dedup key, optionally using a non-default ConCache name from opts.

Same as put/2 when opts is [].