Current section

Files

Jump to
cachex lib cachex actions import.ex
Raw

lib/cachex/actions/import.ex

defmodule Cachex.Actions.Import do
@moduledoc false
# Command module to allow import cache entries from a list.
#
# This command should be considered expensive and should be use sparingly. Due
# to the requirement of being compatible with distributed caches, this cannot
# use a simple `put_many/4` call; rather it needs to walk the full list. It's
# provided as it's the backing implementation of the `Cachex.restore/3` command.
import Cachex.Spec
##############
# Public API #
##############
@doc """
Imports all cache entries from a list into a cache.
This action should only be used in the case of exports and/or debugging, due
to the memory overhead involved, as well as the potential slowness of walking
a large import set.
"""
def execute(cache() = cache, entries, _options),
do: {:ok, Enum.reduce(entries, 0, &import(cache, &1, &2, now()))}
###############
# Private API #
###############
# Imports an entry directly when no TTL is included.
#
# As this is a direct import, we just use `Cachex.put/4` with the provided
# key and value from the existing entry record - nothing special here.
defp import(cache, entry(key: k, expiration: nil, value: v), c, _t) do
Cachex.put!(cache, k, v, const(:notify_false))
c + 1
end
# Skips over entries which have already expired.
#
# This occurs in the case there was an existing modification time and expiration
# but the expiration time would already have passed (so there's no point in
# adding the record to the cache just to throw it away in future).
defp import(_cache, entry(modified: m, expiration: e), c, t) when m + e < t,
do: c
# Imports an entry, using the current time to offset the TTL value.
#
# This is required to shift the TTLs set in a backup to match the current
# import time, so that the rest of the lifetime of the key is the same. If
# we didn't do this, the key would live longer in the cache than intended.
defp import(cache, entry(key: k, modified: m, expiration: e, value: v), c, t) do
Cachex.put!(cache, k, v, const(:notify_false) ++ [expire: m + e - t])
c + 1
end
end