View Source Pow.Store.Backend.MnesiaCache (Pow v1.0.38)
GenServer based key value Mnesia cache store with auto expiration.
When the MnesiaCache starts, it will initialize invalidators for all stored
keys using the expire
value. If the expire
datetime is past, it will
call the invalidator immediately.
Mnesia will create a Mnesia.Node
directory in the current working directory
to write files to. This can be changed by setting the -mnesia dir
config:
config :mnesia, dir: '/path/to/dir'
The directory path should be accessible, otherwise MnesiaCache will crash on startup.
:mnesia
should be added to :extra_applications
in mix.exs
for it to be
included in releases.
Distribution
The MnesiaCache is built to handle multi-node setup.
If you initialize with extra_db_nodes: Node.list()
, it will automatically
connect to the cluster. You can also use MFA:
extra_db_nodes: {Node, :list, []}
. This is useful for when nodes are
dynamically connected before MnesiaCache startup in the supervision tree.
If there is no other nodes available, the data persisted to disk will be loaded, but if a cluster is running, the data in the existing cluster nodes will be loaded instead of the local data. This could potentially cause data loss, but is an accepted risk as all data stored by Pow should be ephemeral.
When a cache key expires, the expiration will be verified before deletion to ensure that it hasn't been updated by another node. When a key is updated on a node, the node will ping all other nodes to refresh their invalidators so the new TTL is used.
All nodes spun up will by default persist to disk. If you start up multiple nodes from the same physical directory you have to make sure that each node has a unique directory path configured. This can be done using different config files, or by using a system environment variable:
config :mnesia, dir: to_charlist(System.get_env("MNESIA_DIR"))
You can use Pow.Store.Backend.MnesiaCache.Unsplit
to automatically recover
from network split issues. All partitioned nodes will have their table
flushed and reloaded from the oldest node in the cluster.
Usage
To start the GenServer, add it to your application start/2
function:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo,
MyAppWeb.Endpoint,
Pow.Store.Backend.MnesiaCache
# # Or in a distributed system:
# {Pow.Store.Backend.MnesiaCache, extra_db_nodes: {Node, :list, []}},
# Pow.Store.Backend.MnesiaCache.Unsplit # Recover from netsplit
]
opts = [strategy: :one_for_one, name: MyAppWeb.Supervisor]
Supervisor.start_link(children, opts)
end
# ...
end
Update configuration with cache_store_backend: Pow.Store.Backend.MnesiaCache
.
Initialization options
:extra_db_nodes
- list of nodes or MFA returning a list of nodes in cluster to connect to.:table_opts
- options to add to table definition. This value defaults to[disc_copies: [node()]]
.:timeout
- timeout value in milliseconds for how long to wait until the cache table has initiated. Defaults to 15 seconds.
Configuration options
:ttl
- integer value in milliseconds for ttl of records (required).:namespace
- string value to use for namespacing keys, defaults to "cache".:writes
- set to:async
to do asynchronous writes. Defaults to:sync
.
Summary
Functions
Returns a specification to start this module under a supervisor.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec start_link(Pow.Store.Backend.Base.config()) :: GenServer.on_start()