From e133fbf301ee14c93db9b9bc930ab2463122544c Mon Sep 17 00:00:00 2001 From: Alexandru DAMIAN Date: Tue, 17 Feb 2015 17:24:29 +0000 Subject: [PATCH] bitbake: toasterui: UI query performance improvements We reduce the number of queries by using "select_related" to bring in more data in a single query. Improvements in project page refresh, recipes table and tasks table. (Bitbake rev: eefdae12120f879b555ba0a353277a18675eecbc) Signed-off-by: Alexandru DAMIAN Signed-off-by: Richard Purdie --- bitbake/lib/toaster/orm/models.py | 11 +++++++---- bitbake/lib/toaster/toastergui/views.py | 15 +++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index 0f85c8fd0a..54cd5354de 100644 --- a/bitbake/lib/toaster/orm/models.py +++ b/bitbake/lib/toaster/orm/models.py @@ -362,11 +362,14 @@ class Task(models.Model): return "Not Executed" def get_description(self): - helptext = HelpText.objects.filter(key=self.task_name, area=HelpText.VARIABLE, build=self.build) + if '_helptext' in vars(self) and self._helptext != None: + return self._helptext try: - return helptext[0].text - except IndexError: - return '' + self._helptext = HelpText.objects.get(key=self.task_name, area=HelpText.VARIABLE, build=self.build).text + except HelpText.DoesNotExit: + self._helptext = None + + return self._helptext build = models.ForeignKey(Build, related_name='task_build') order = models.IntegerField(null=True) diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index eb323ec81d..a2e92068c5 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py @@ -75,8 +75,9 @@ def _project_recent_build_list(prj): 'build_time_page_url': reverse('buildtime', args=(y.pk,)), "errors": y.errors_no, "warnings": y.warnings_no, - "completeper": y.completeper(), - "eta": y.eta().strftime('%s')+"000"}, Build.objects.filter(buildrequest = x)), + "completeper": y.completeper() if y.outcome == Build.IN_PROGRESS else "0", + "eta": y.eta().strftime('%s')+"000" if y.outcome == Build.IN_PROGRESS else "0", + }, Build.objects.filter(buildrequest = x)), }, list(prj.buildrequest_set.filter(Q(state__lt=BuildRequest.REQ_COMPLETED) or Q(state=BuildRequest.REQ_DELETED)).order_by("-pk")) + list(prj.buildrequest_set.filter(state__in=[BuildRequest.REQ_COMPLETED, BuildRequest.REQ_FAILED]).order_by("-pk")[:3])) @@ -828,6 +829,8 @@ def tasks_common(request, build_id, variant, task_anchor): else: queryset = _get_queryset(Task, queryset_all, filter_string, search_term, ordering_string, 'order') + queryset = queryset.select_related("recipe", "build") + # compute the anchor's page if anchor: request.GET = request.GET.copy() @@ -1023,14 +1026,14 @@ def recipes(request, build_id): if retval: return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id) (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe) - queryset = Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)) + queryset = Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)).select_related("layer_version", "layer_version__layer") queryset = _get_queryset(Recipe, queryset, filter_string, search_term, ordering_string, 'name') recipes = _build_page_range(Paginator(queryset, pagesize),request.GET.get('page', 1)) # prefetch the forward and reverse recipe dependencies deps = { }; revs = { } - queryset_dependency=Recipe_Dependency.objects.filter(recipe__layer_version__build_id = build_id) + queryset_dependency=Recipe_Dependency.objects.filter(recipe__layer_version__build_id = build_id).select_related("depends_on", "recipe") for recipe in recipes: deplist = [ ] for recipe_dep in [x for x in queryset_dependency if x.recipe_id == recipe.id]: @@ -1804,7 +1807,7 @@ if toastermain.settings.MANAGED: (filter_string, search_term, ordering_string) = _search_tuple(request, BuildRequest) # we don't display in-progress or deleted builds queryset_all = buildrequests.exclude(state = BuildRequest.REQ_DELETED) - queryset_all = queryset_all.annotate(Count('brerror')) + queryset_all = queryset_all.select_related("build", "build__project").annotate(Count('brerror')) queryset_with_search = _get_queryset(BuildRequest, queryset_all, filter_string, search_term, ordering_string, '-updated') @@ -2179,7 +2182,7 @@ if toastermain.settings.MANAGED: # return all project settings return HttpResponse(jsonfilter( { "error": "ok", - "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().order_by("id")), + "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")), "builds" : _project_recent_build_list(prj), "variables": map(lambda x: (x.name, x.value), prj.projectvariable_set.all()), "machine": {"name": prj.projectvariable_set.get(name="MACHINE").value},