Bonfire.Common.Cache (Bonfire v0.9.12-social-beta.71)
View SourceHelpers for caching data and operations.
This module provides functions to efficiently cache values and function results, with automatic expiration. Use it to avoid repeating expensive operations.
Summary
Functions
Converts function arguments to a string representation for cache keys.
Efficiently preloads and caches data for a list of objects.
Retrieves a value from the cache with the given key.
Retrieves a value from the cache with the given key and unwraps the result.
Generates a cache key for a function and its arguments.
Takes a function (or module and function names) and a set of arguments for that function, and tries to fetch the previous result of running that function from the in-memory cache, and if it's not in the cache it executes the function, and caches and returns the result.
Stores a value in the cache with the given key and options.
Removes the entry associated with a key from the cache.
Clears all entries from the cache.
Removes the result of a given function ran using maybe_apply_cached/3
from the cache.
Functions
Converts function arguments to a string representation for cache keys.
For large argument lists, it creates a hash to keep keys at a reasonable length.
Examples
iex> Bonfire.Common.Cache.args_to_string(["hello"])
"\"hello\""
iex> Bonfire.Common.Cache.args_to_string("hello")
"\"hello\""
iex> Bonfire.Common.Cache.args_to_string([1, 2, 3, 4, 5])
"1, 2, 3, 4, 5"
iex> Bonfire.Common.Cache.args_to_string([0, [1, 2, 3, 4, 5]])
"0, [1, 2, 3, 4, 5]"
# For very long arguments, generates a hash
iex> Bonfire.Common.Cache.args_to_string(Enum.to_list(1..100))
"h:S-9J48qVhMunSA2R90s-Iw"
# Returns a hashed string
Efficiently preloads and caches data for a list of objects.
This function is useful when you need to fetch related data for a collection of objects (e.g. associations for a list of Ecto structs), and want to cache the results and minimize database queries.
Parameters
name
- A name for this type of preload, used as part of the cache keyobjects
- List of objects that need preloadingfun
- A function that takes a list of IDs and returns a map of{id, preloaded_data}
Examples
iex> users = [%{id: "01BX5ZZKBKACTAV9WEVGEMMVRZ", name: "Alice"}, %{id: "01BX5ZZKBKACTAV9WEVGEMMVS0", name: "Bob"}]
iex> loader = fn ids ->
...> # Simulating a database call that returns posts for users
...> Enum.map(ids, fn id -> {id, ["Post by User"]} end) |> Map.new()
...> end
iex> Bonfire.Common.Cache.cached_preloads_for_objects("user_posts", users, loader)
%{"01BX5ZZKBKACTAV9WEVGEMMVRZ" => ["Post by User"], "01BX5ZZKBKACTAV9WEVGEMMVS0" => ["Post by User"]}
# On subsequent calls, data will be retrieved from cache
Retrieves a value from the cache with the given key.
Returns {:ok, value}
if the key exists, {:ok, nil}
if the key does not exist, or {:error, reason}
if there was an error.
Options
:cache_store
- The cache store to use (defaults to :bonfire_cache)
Examples
iex> Bonfire.Common.Cache.put("fetch_me", "hello")
iex> Bonfire.Common.Cache.get("fetch_me")
{:ok, "hello"}
iex> Bonfire.Common.Cache.get("non_existent_key")
{:ok, nil}
Retrieves a value from the cache with the given key and unwraps the result.
Returns the value if the key exists or nil if it doesn't exist or there was an error.
Options
:cache_store
- The cache store to use (defaults to :bonfire_cache)
Examples
iex> Bonfire.Common.Cache.put("my_key", "my_value")
iex> Bonfire.Common.Cache.get!("my_key")
"my_value"
iex> Bonfire.Common.Cache.get!("missing_key")
nil
Generates a cache key for a function and its arguments.
This function is used internally by maybe_apply_cached/3
to create consistent cache keys based on function references and their arguments.
Examples
iex> Bonfire.Common.Cache.key_for_call(fn x -> x * 2 end, [21])
iex> # Returns something like "fn/1 in Bonfire.Common.Cache.key_for_call/2(21)"
iex> # FYI actual result in doctest is more like "Bonfire.Common.CashTest."doctest Bonfire.Common.Cache.key_for_call/2 (13)"/1(21)"
iex> Bonfire.Common.Cache.key_for_call({String, :upcase}, "hello")
"String.upcase(\"hello\")"
iex> Bonfire.Common.Cache.key_for_call({String, :upcase}, ["hello"])
"String.upcase(\"hello\")"
iex> Bonfire.Common.Cache.key_for_call({Map, :get}, [%{"a"=>1, b: 2}, :a])
"Map.get([{:b, 2}, {\"a\", 1}], :a)"
Takes a function (or module and function names) and a set of arguments for that function, and tries to fetch the previous result of running that function from the in-memory cache, and if it's not in the cache it executes the function, and caches and returns the result.
Uses the MFA (module name/function name/arguments used) to generate the cache key (see key_for_call/2
and args_to_string/1
).
Options
:cache_store
- The cache store to use (defaults to :bonfire_cache):cache_key
- Custom cache key to use (defaults to auto-generated key based on function and args):expire
- Time in milliseconds until the cache entry expires (defaults to 21600000ms):check_env
- When set to false, bypasses error-retry logic in dev environment (defaults to true)
Examples
iex> Bonfire.Common.Cache.maybe_apply_cached({String, :upcase}, ["hello"])
"HELLO"
iex> # Second call uses cached result
iex> Bonfire.Common.Cache.maybe_apply_cached({String, :upcase}, ["hello"])
"HELLO"
iex> Bonfire.Common.Cache.maybe_apply_cached(fn x -> x * 2 end, [21])
42
Stores a value in the cache with the given key and options.
Options
:cache_store
- The cache store to use (defaults to :bonfire_cache):expire
- Time in milliseconds until the cache entry expires (defaults to 21600000ms / 6 hours)
Examples
iex> Bonfire.Common.Cache.put("my_key", "my_value")
"my_value"
iex> Bonfire.Common.Cache.get("my_key")
{:ok, "my_value"}
iex> Bonfire.Common.Cache.put("expires_soon", "temporary", expire: 1000)
"temporary"
Removes the entry associated with a key from the cache.
Options
:cache_store
- The cache store to use (defaults todefault_cache_store/0
})
Examples
iex> Bonfire.Common.Cache.put("delete_me", "value")
iex> Bonfire.Common.Cache.remove("delete_me")
true
iex> Bonfire.Common.Cache.get!("delete_me")
nil
Clears all entries from the cache.
Options
:cache_store
- The cache store to use (defaults to :bonfire_cache)
Examples
iex> Bonfire.Common.Cache.remove_all()
iex> Bonfire.Common.Cache.put("key1", "value1")
iex> Bonfire.Common.Cache.put("key2", "value2")
iex> Bonfire.Common.Cache.remove_all()
2 # Returns the number of entries removed
iex> Bonfire.Common.Cache.get!("key1")
nil
Removes the result of a given function ran using maybe_apply_cached/3
from the cache.
This is useful when you know a cached value is stale and want to force re-computation on the next call.
Options
:cache_store
- The cache store to use (defaults todefault_cache_store/0
})
Examples
iex> Bonfire.Common.Cache.maybe_apply_cached({String, :upcase}, ["hello"])
"HELLO"
iex> Bonfire.Common.Cache.reset({String, :upcase}, ["hello"])
true
iex> # Will compute the result again
iex> Bonfire.Common.Cache.maybe_apply_cached({String, :upcase}, ["hello"])
"HELLO"