AshCache.Calculations.CalculateThrough (AshCache v0.1.0)

Copy Markdown View Source

Caching for a module calculation, one entry per record.

AshCache.Resource.Transformers.AttachCacheHooks puts this module in the calculation's place and hands it the original as the :calculation option. init/1, describe/1 and load/3 are passed to the original, so Ash still loads everything the original needs.

For a batch of records, each record is looked up on its own; the original runs once, only for the records that were not found, and the results go back in the records' order. nil and [] are real results and are cached. An {:error, _} or :unknown from the original is returned unchanged and nothing is cached.

The key (AshCache.Key) holds the calculation's arguments, the actor, the tenant, every attribute of the record and the value of every field the original loads: the fields its load/3 names (asked again with a fresh query of the resource) and the calculation's own load option. So a change to anything the calculation can read gives a new key, and a stale result is never served; old entries simply expire after the ttl. Writes and AshCache.invalidate/1 do not touch these entries.

strict_loads?/0 is false, so related records are loaded with all their attributes. A callback without options cannot tell what the original says, and loading more is always safe.

A load with context: %{ash_cache: :bypass} skips the cache.

Known limit: identical misses running at the same time each run the original; there is no AshCache.Coalesce for calculations.

Summary

Functions

has_calculate?()

has_expression?()

Callback implementation for Ash.Resource.Calculation.has_expression?/0.