PayDayLoan.Loader behaviour (pay_day_loan v0.7.0)
Defines the PDL loader behaviour.
The loader is responsible for fetching a batch of data (bulk_load/1
) from
the cache's source (e.g., a database). For each element that is fetched,
we check if there is an existing element in the cache backend.
If no existing element is found for a key, we call new/2
with the
corresponding key and value. This gives the loader an opportunity to alter
what is stored in the backend from what is returned by the loader. For
example, we may be using a process backend and all we need to store is the
pid.
If an existing value is found for a key, we call refresh/3
with the
existing backend value, the key, and the load datum. For example, with a
process backend this may involve making a GenServer or Agent update call
before returning the pid to the backend.
The key_exists?/1
function is a hook for the key cache.
Link to this section Summary
Callbacks
Fetch values to be loaded into cache. For example, perform a database lookup and return the data normalized in some form that your cache elements will understand.
Should return true if a key exists in the cache's source. This should be a
fast-executing call - for example, with a database source -
SELECT count(1) FROM cache_source WHERE id = #{key}
.
Create a new cache element before sending it to the backend.
Update a cache element before storing it.
Link to this section Callbacks
bulk_load(keys)
@callback bulk_load(keys :: [PayDayLoan.key()]) :: [ {PayDayLoan.key(), PayDayLoan.load_datum()} ]
Fetch values to be loaded into cache. For example, perform a database lookup and return the data normalized in some form that your cache elements will understand.
new
or refresh
will be called for each returned element as
appropriate.
Note that there is no requirement that each key passed in be represented in the output.
key_exists?(key)
@callback key_exists?(key :: PayDayLoan.key()) :: boolean()
Should return true if a key exists in the cache's source. This should be a
fast-executing call - for example, with a database source -
SELECT count(1) FROM cache_source WHERE id = #{key}
.
You can stub this method to always return true if you want to effectively skip key caching.
new(key, load_datum)
@callback new(key :: PayDayLoan.key(), load_datum :: PayDayLoan.load_datum()) :: {:ok, term()} | {:error, term()} | :ignore
Create a new cache element before sending it to the backend.
For example, this may create a process and the resulting pid is what is
actually stored in the backend, or it may simply manipulate the load datum
before it is stored. To store the load datum directly in the backend,
just return {:ok, load_datum}
. To signal an error which will cause the
load to fail for this key, return {:error, <error payload>}
.
refresh(existing_value, key, load_datum)
@callback refresh( existing_value :: term(), key :: PayDayLoan.key(), load_datum :: PayDayLoan.load_datum() ) :: {:ok, term()} | {:error, term()} | :ignore
Update a cache element before storing it.
This is called when a load occurs for a key that already has a value in
the cache. You can use this callback to resolve the differences or to
update the value before sending it on to the backend. For example, with
a process-based cache (e.g. using PayDayLoan.EtsBackend
), the
existing_value
is the backing processes pid and you may need to call
something like Agent.update(existing_value, key, <update function>)
and
return existing_value
unchanged (since the same pid will still be stored
on the backend).
To pass the load datum directly through to the backend, return
{:ok, load_datum}
. To signal an error, return
{:error, <error payload>}
. To ignore this datum, return :ignore
. In
both the :ignore
and :error
cases, the key will not be reloaded until
it is requested again.