Current section
Files
Jump to
Current section
Files
lib/cachex/actions/fetch.ex
defmodule Cachex.Actions.Fetch do
@moduledoc false
# Command module to enable fetching on cache misses.
#
# This is a replacement for the `get()` command in Cachex v2 which would accept
# a `:fallback` option to fetch on cache miss. It operates in the same way, except
# that the function to use when fetching is an explicit argument.
#
# If the fetch function is not provided, the `fetch()` command will try to lookup
# a default fetch function from the cache state and use that instead. If neither
# exist, an error will be returned.
alias Cachex.Actions.Get
alias Cachex.Services.Courier
# provide needed macros
import Cachex.Spec
##############
# Public API #
##############
@doc """
Retrieves an entry from a cache, falling back to fetch fetching on a miss.
The fallback argument can be treated as optional if a default fetch function is
attached to the global cache at startup, in which case it will be executed instead.
The fallback function is only executed if the key being retrieved does not exist
in the cache; otherwise it is immediately returned. Any fetched values will be
placed in the cache in order to allow read-through caches.
"""
def execute(cache() = cache, key, fallback, _options) do
with {:ok, nil} <- Get.execute(cache, key, []) do
Courier.dispatch(cache, key, generate_task(fallback, key))
end
end
###############
# Private API #
###############
# Generates a courier task based on the arity of the fallback function.
defp generate_task(fallback, key) do
case :erlang.fun_info(fallback)[:arity] do
0 -> fn -> fallback.() end
1 -> fn -> fallback.(key) end
end
end
end