diff --git a/frappe/desk/search.py b/frappe/desk/search.py index 4c9a92e698..4b913dab66 100644 --- a/frappe/desk/search.py +++ b/frappe/desk/search.py @@ -15,6 +15,7 @@ from frappe.database.schema import SPECIAL_CHAR_PATTERN from frappe.model.db_query import get_order_by from frappe.permissions import has_permission from frappe.utils import cint, cstr, escape_html, unique +from frappe.utils.caching import redis_cache from frappe.utils.data import make_filter_tuple @@ -32,8 +33,13 @@ class LinkSearchResults(TypedDict): label: NotRequired[str] +def should_cache(doctype, txt, *args, **kwargs): + return not txt + + # this is called by the Link Field @frappe.whitelist() +@redis_cache(ttl=60 * 5, user=True, condition=should_cache) def search_link( doctype: str, txt: str, diff --git a/frappe/utils/caching.py b/frappe/utils/caching.py index f2f1f9aecd..62be7f83b6 100644 --- a/frappe/utils/caching.py +++ b/frappe/utils/caching.py @@ -167,13 +167,19 @@ def site_cache(ttl: int | None = None, maxsize: int | None = None) -> Callable: return time_cache_wrapper -def redis_cache(ttl: int | None = 3600, user: str | bool | None = None, shared: bool = False) -> Callable: +def redis_cache( + ttl: int | None = 3600, + user: str | bool | None = None, + shared: bool = False, + condition: Callable | None = None, +) -> Callable: """Decorator to cache method calls and its return values in Redis args: ttl: time to expiry in seconds, defaults to 1 hour user: `true` should cache be specific to session user. shared: `true` should cache be shared across sites + condition: A callable that returns `True` if the cache should be used, `False` otherwise. """ def wrapper(func: Callable | None = None) -> Callable: @@ -187,6 +193,9 @@ def redis_cache(ttl: int | None = 3600, user: str | bool | None = None, shared: @wraps(func) def redis_cache_wrapper(*args, **kwargs): + if condition and not condition(*args, **kwargs): + return func(*args, **kwargs) + func_call_key = f"{func_key}::{hash(__generate_request_cache_key(args, kwargs))}" cached_val = frappe.cache.get_value(func_call_key, user=user, shared=shared) if cached_val is not None: