Cache (project_id, node_type_name) -> project mapping per request.

When returning many nodes of the same project and same node type, this
prevents us from doing the same request over and over to MongoDB,
increasing performance.
This commit is contained in:
Sybren A. Stüvel 2016-05-23 15:18:23 +02:00
parent 75738efc0d
commit 8ff10828c6

View File

@ -107,8 +107,6 @@ def has_permissions(collection_name, resource, method, append_allowed_methods=Fa
def compute_aggr_permissions(collection_name, resource, check_node_type): def compute_aggr_permissions(collection_name, resource, check_node_type):
"""Returns a permissions dict.""" """Returns a permissions dict."""
projects_collection = current_app.data.driver.db['projects']
# We always need the know the project. # We always need the know the project.
if collection_name == 'projects': if collection_name == 'projects':
project = resource project = resource
@ -126,12 +124,8 @@ def compute_aggr_permissions(collection_name, resource, check_node_type):
# embedded project # embedded project
project = resource['project'] project = resource['project']
else: else:
project = projects_collection.find_one( project_id = resource['project']
ObjectId(resource['project']), project = _find_project_node_type(project_id, node_type_name)
{'permissions': 1,
'node_types': {'$elemMatch': {'name': node_type_name}},
'node_types.name': 1,
'node_types.permissions': 1})
# Every node should have a project. # Every node should have a project.
if project is None: if project is None:
@ -157,6 +151,32 @@ def compute_aggr_permissions(collection_name, resource, check_node_type):
return merge_permissions(project_permissions, node_type_permissions, node_permissions) return merge_permissions(project_permissions, node_type_permissions, node_permissions)
def _find_project_node_type(project_id, node_type_name):
"""Returns the project with just the one named node type."""
# Cache result per request, as many nodes of the same project can be checked.
cache = g.get('_find_project_node_type_cache')
if cache is None:
cache = g._find_project_node_type_cache = {}
try:
return cache[(project_id, node_type_name)]
except KeyError:
pass
projects_collection = current_app.data.driver.db['projects']
project = projects_collection.find_one(
ObjectId(project_id),
{'permissions': 1,
'node_types': {'$elemMatch': {'name': node_type_name}},
'node_types.name': 1,
'node_types.permissions': 1})
cache[(project_id, node_type_name)] = project
return project
def merge_permissions(*args): def merge_permissions(*args):
"""Merges all given permissions. """Merges all given permissions.