From dcd170f86dad47339cb96eb4fecf73ee41fcc983 Mon Sep 17 00:00:00 2001 From: liyingjun Date: Fri, 3 Jun 2016 13:16:36 +0800 Subject: [PATCH] Microversion 2.33 adds pagination support for hypervisors When there are thousands of compute nodes, it would be slow to get the whole hypervisor list, and it is bad for user experience to display thousands of items in a table in horizon. This patch is proposed to support pagination for hypervisor by adding `limit` and `marker` to the list api. Implements blueprint: pagination-for-hypervisor Change-Id: Ie7f8b5c733b383f3e69fa23188e56257e503b5f7 --- nova/db/api.py | 13 +++++++++++++ nova/db/sqlalchemy/api.py | 22 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index d3c64f972..a664be73c 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -244,6 +244,19 @@ def compute_node_get_all(context): return IMPL.compute_node_get_all(context) +def compute_node_get_all_by_pagination(context, limit=None, marker=None): + """Get compute nodes by pagination. + :param context: The security context + :param limit: Maximum number of items to return + :param marker: The last item of the previous page, the next results after + this value will be returned + + :returns: List of dictionaries each containing compute node properties + """ + return IMPL.compute_node_get_all_by_pagination(context, + limit=limit, marker=marker) + + def compute_node_get_all_by_host(context, host): """Get compute nodes by host name diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d821fa3e4..682b8546c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -564,7 +564,7 @@ def service_update(context, service_id, values): ################### -def _compute_node_select(context, filters=None): +def _compute_node_select(context, filters=None, limit=None, marker=None): if filters is None: filters = {} @@ -582,11 +582,22 @@ def _compute_node_select(context, filters=None): if "hypervisor_hostname" in filters: hyp_hostname = filters["hypervisor_hostname"] select = select.where(cn_tbl.c.hypervisor_hostname == hyp_hostname) + if marker is not None: + try: + compute_node_get(context, marker) + except exception.ComputeHostNotFound: + raise exception.MarkerNotFound(marker) + select = select.where(cn_tbl.c.id > marker) + if limit is not None: + select = select.limit(limit) + # Explictly order by id, so we're not dependent on the native sort + # order of the underlying DB. + select = select.order_by(asc("id")) return select -def _compute_node_fetchall(context, filters=None): - select = _compute_node_select(context, filters) +def _compute_node_fetchall(context, filters=None, limit=None, marker=None): + select = _compute_node_select(context, filters, limit=limit, marker=marker) engine = get_engine(context) conn = engine.connect() @@ -648,6 +659,11 @@ def compute_node_get_all(context): return _compute_node_fetchall(context) +@pick_context_manager_reader +def compute_node_get_all_by_pagination(context, limit=None, marker=None): + return _compute_node_fetchall(context, limit=limit, marker=marker) + + @pick_context_manager_reader def compute_node_search_by_hypervisor(context, hypervisor_match): field = models.ComputeNode.hypervisor_hostname