浏览代码

perf(desk): Even faster desk (#9930)

* feat (perf): even faster desk

* fix: user not found bug

* feat: store db counts

* feat: use cached db.get_value

* style (sider): comparison to None should be 'if cond is None:'

* feat: add keys to user_cache_keys

* refactor: cache blocked modules and roles

Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com>
version-14
Shivam Mishra 5 年前
committed by GitHub
父节点
当前提交
977e6c23f2
找不到此签名对应的密钥 GPG 密钥 ID: 4AEE18F83AFDEB23
共有 3 个文件被更改,包括 54 次插入21 次删除
  1. +14
    -5
      frappe/boot.py
  2. +2
    -1
      frappe/cache_manager.py
  3. +38
    -15
      frappe/desk/desktop.py

+ 14
- 5
frappe/boot.py 查看文件

@@ -107,13 +107,20 @@ def load_desktop_data(bootinfo):
bootinfo.allowed_modules = get_modules_from_all_apps_for_user()
bootinfo.allowed_workspaces = get_desk_sidebar_items(True)

def get_allowed_pages():
return get_user_pages_or_reports('Page')
def get_allowed_pages(cache=False):
return get_user_pages_or_reports('Page', cache=cache)

def get_allowed_reports():
return get_user_pages_or_reports('Report')
def get_allowed_reports(cache=False):
return get_user_pages_or_reports('Report', cache=cache)

def get_user_pages_or_reports(parent, cache=False):
_cache = frappe.cache()

if cache:
has_role = _cache.get_value('has_role:' + parent, user=frappe.session.user)
if has_role:
return has_role

def get_user_pages_or_reports(parent):
roles = frappe.get_roles()
has_role = {}
column = get_column(parent)
@@ -184,6 +191,8 @@ def get_user_pages_or_reports(parent):
for report in reports:
has_role[report.name]["report_type"] = report.report_type

# Expire every six hours
_cache.set_value('has_role:' + parent, has_role, frappe.session.user, 21600)
return has_role

def get_column(doctype):


+ 2
- 1
frappe/cache_manager.py 查看文件

@@ -20,7 +20,8 @@ global_cache_keys = ("app_hooks", "installed_apps",

user_cache_keys = ("bootinfo", "user_recent", "roles", "user_doc", "lang",
"defaults", "user_permissions", "home_page", "linked_with",
"desktop_icons", 'portal_menu_items')
"desktop_icons", 'portal_menu_items', 'user_perm_can_read',
"has_role:Page", "has_role:Report")

doctype_cache_keys = ("meta", "form_meta", "table_columns", "last_modified",
"linked_doctypes", 'notifications', 'workflow' ,'energy_point_rule_map')


+ 38
- 15
frappe/desk/desktop.py 查看文件

@@ -21,19 +21,17 @@ class Workspace:
self.extended_charts = []
self.extended_shortcuts = []

user = frappe.get_user()
user.build_permissions()

user_doc = frappe.get_doc('User', frappe.session.user)
self.blocked_modules = user_doc.get_blocked_modules()
self.user = frappe.get_user()
self.allowed_modules = self.get_cached_value('user_allowed_modules', self.get_allowed_modules)
self.doc = self.get_page_for_user()

if self.doc.module in self.blocked_modules:
if self.doc.module not in self.allowed_modules:
raise frappe.PermissionError

self.user = user
self.allowed_pages = get_allowed_pages()
self.allowed_reports = get_allowed_reports()
self.can_read = self.get_cached_value('user_perm_can_read', self.get_can_read_items)

self.allowed_pages = get_allowed_pages(cache=True)
self.allowed_reports = get_allowed_reports(cache=True)
self.onboarding_doc = self.get_onboarding_doc()
self.onboarding = None

@@ -41,6 +39,31 @@ class Workspace:
self.restricted_doctypes = frappe.cache().get_value("domain_restricted_doctypes") or build_domain_restriced_doctype_cache()
self.restricted_pages = frappe.cache().get_value("domain_restricted_pages") or build_domain_restriced_page_cache()

def get_cached_value(self, cache_key, fallback_fn):
_cache = frappe.cache()

value = _cache.get_value(cache_key, user=frappe.session.user)
if value:
return value

value = fallback_fn()

# Expire every six hour
_cache.set_value(cache_key, value, frappe.session.user, 21600)
return value

def get_can_read_items(self):
if not self.user.can_read:
self.user.build_permissions()

return self.user.can_read

def get_allowed_modules(self):
if not self.user.allow_modules:
self.user.build_permissions()

return self.user.allow_modules

def get_page_for_user(self):
filters = {
'extends': self.page_name,
@@ -68,7 +91,7 @@ class Workspace:

# Check if user is allowed
allowed_roles = set(doc.get_allowed_roles())
user_roles = set(self.user.get_roles())
user_roles = set(frappe.get_roles())
if not allowed_roles & user_roles:
return None

@@ -83,7 +106,7 @@ class Workspace:
"extends": self.page_name,
'restrict_to_domain': ['in', frappe.get_active_domains()],
'for_user': '',
'module': ['not in', self.blocked_modules]
'module': ['in', self.allowed_modules]
})

pages = [frappe.get_doc("Desk Page", page['name']) for page in pages]
@@ -97,7 +120,7 @@ class Workspace:
item_type = item_type.lower()

if item_type == "doctype":
return (name in self.user.can_read and name in self.restricted_doctypes)
return (name in self.can_read and name in self.restricted_doctypes)
if item_type == "page":
return (name in self.allowed_pages and name in self.restricted_pages)
if item_type == "report":
@@ -140,9 +163,9 @@ class Workspace:
default_country = frappe.db.get_default("country")

def _doctype_contains_a_record(name):
exists = self.table_counts.get(name)
if not exists:
if not frappe.db.get_value('DocType', name, 'issingle'):
exists = self.table_counts.get(name, None)
if exists is None:
if not frappe.db.get_value('DocType', name, 'issingle', cache=True):
exists = frappe.db.count(name)
else:
exists = True


正在加载...
取消
保存