-
Notifications
You must be signed in to change notification settings - Fork 78
Description
Enhancement: Support combining :key and :query options in cache_evict decorator
Summary
Add support for using both :key and :query options together in the @decorate cache_evict decorator. This enhancement allows developers to evict both specific cache entries and entries matching a query pattern in a single operation.
Current Behavior
Previously, when both :key and :query options were provided to the cache_evict decorator, the :query option would override the :key option, making it impossible to evict specific keys alongside query-based eviction in a single decorator call.
New Behavior
When both :key and :query options are provided, the decorator now executes both evictions in the following order:
- Query-based eviction - First, all entries matching the query are evicted
- Key-based eviction - Then, the specific key(s) are evicted
Motivation
This enhancement addresses common use cases where developers need to evict hierarchical or related data:
- User logout: Evict the user's cache entry and all their session entries
- Category deletion: Evict both the category entry (by ID and slug) and all products in that category
- Cleanup operations: Remove a primary record and all its dependent cached records
Without this feature, developers would need to:
- Use multiple decorator calls, or
- Manually evict keys before/after the decorated function, or
- Create complex queries that include specific keys
Examples
Note: The query examples below assume you are using the
Nebulex.Adapters.Localadapter, which uses ETS match specifications. If you're using a different adapter (e.g., Redis, Partitioned, etc.), the query syntax will vary according to that adapter's documentation.
Example 1: User logout with session cleanup
@decorate cache_evict(key: user_id, query: &query_for_user_sessions/1)
def logout_user(user_id) do
# Evicts the user entry and all session entries for this user
UserSessions.delete_all_for_user(user_id)
end
defp query_for_user_sessions(%{args: [user_id]} = _context) do
# Return a query that matches all session entries for the given user
[
{
{:entry, :"$1", %{user_id: :"$2", type: "session"}, :_, :_},
[{:"=:=", :"$2", user_id}],
[true]
}
]
endExample 2: Category deletion with products
@decorate cache_evict(
key: {:in, [category.id, category.slug]},
query: &query_for_category_products/1
)
def delete_category(category) do
# Evicts both category cache entries (by id and slug) and all
# product entries within that category
Products.delete_all_for_category(category.id)
end
defp query_for_category_products(%{args: [category]} = _context) do
[
{
{:entry, :"$1", %{category_id: :"$2"}, :_, :_},
[{:"=:=", :"$2", category.id}],
[true]
}
]
endImplementation Details
- Updated
action_block/6inNebulex.Caching.Decoratorsto properly quote and handle the combined case - Updated
eval_key/2to handle the{:"$nbx_query", q, k}tuple for combined eviction - Updated
do_evict/4to execute query-based eviction first, then key-based eviction - Added comprehensive tests validating the new behavior
- Updated documentation in both
Nebulex.Caching.OptionsandNebulex.Caching.Decorators - The implementation is adapter-agnostic and works with any cache adapter that supports query-based operations
- Documentation examples use
Nebulex.Adapters.Local(ETS match specifications) for illustration purposes
Documentation
The following documentation has been added/updated:
- Options documentation (
Nebulex.Caching.Options): Updated the:queryoption to explain the combined behavior - Decorator documentation (
Nebulex.Caching.Decorators):- Added a new subsection "Combining
:keyand:query" with detailed examples - Added examples in the main Examples section
- Updated best practices to include guidance on using both options for hierarchical data
- Added a new subsection "Combining
Breaking Changes
None. This is a backward-compatible enhancement. Existing code using only :key or only :query continues to work exactly as before.
Testing
- Added test case:
test "with both key and query" - Added test case:
test "with both key (multiple) and query" - All existing tests continue to pass
- Documentation builds successfully without warnings
Related Issues
This enhancement builds upon the query support added in #243 and external reference eviction support added in #244.