pay_day_loan v0.5.1 PayDayLoan.Loader behaviour

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.

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

Callbacks

bulk_load(keys)
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)
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)
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)
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.