mirror of https://github.com/jumpserver/jumpserver
perf: 优化任务列表执行时间 性能快了10倍
parent
ce94348d45
commit
cd0348cca1
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
import os
|
||||
import re
|
||||
from collections import defaultdict
|
||||
|
||||
from celery.result import AsyncResult
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
@ -166,16 +167,58 @@ class CeleryTaskViewSet(
|
|||
i.next_exec_time = now + next_run_at
|
||||
return queryset
|
||||
|
||||
def generate_summary_state(self, execution_qs):
|
||||
model = self.get_queryset().model
|
||||
executions = execution_qs.order_by('-date_published').values('name', 'state')
|
||||
summary_state_dict = defaultdict(
|
||||
lambda: {
|
||||
'states': [], 'state': 'green',
|
||||
'summary': {'total': 0, 'success': 0}
|
||||
}
|
||||
)
|
||||
for execution in executions:
|
||||
name = execution['name']
|
||||
state = execution['state']
|
||||
|
||||
summary = summary_state_dict[name]['summary']
|
||||
|
||||
summary['total'] += 1
|
||||
summary['success'] += 1 if state == 'SUCCESS' else 0
|
||||
|
||||
states = summary_state_dict[name].get('states')
|
||||
if states is not None and len(states) >= 5:
|
||||
color = model.compute_state_color(states)
|
||||
summary_state_dict[name]['state'] = color
|
||||
summary_state_dict[name].pop('states', None)
|
||||
elif isinstance(states, list):
|
||||
states.append(state)
|
||||
|
||||
return summary_state_dict
|
||||
|
||||
def loading_summary_state(self, queryset):
|
||||
if isinstance(queryset, list):
|
||||
names = [i.name for i in queryset]
|
||||
execution_qs = CeleryTaskExecution.objects.filter(name__in=names)
|
||||
else:
|
||||
execution_qs = CeleryTaskExecution.objects.all()
|
||||
summary_state_dict = self.generate_summary_state(execution_qs)
|
||||
for i in queryset:
|
||||
i.summary = summary_state_dict.get(i.name, {}).get('summary', {})
|
||||
i.state = summary_state_dict.get(i.name, {}).get('state', 'green')
|
||||
return queryset
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
page = self.generate_execute_time(page)
|
||||
page = self.loading_summary_state(page)
|
||||
serializer = self.get_serializer(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
||||
queryset = self.generate_execute_time(queryset)
|
||||
queryset = self.loading_summary_state(queryset)
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ class CeleryTask(models.Model):
|
|||
name = models.CharField(max_length=1024, verbose_name=_('Name'))
|
||||
date_last_publish = models.DateTimeField(null=True, verbose_name=_("Date last publish"))
|
||||
|
||||
__summary = None
|
||||
__state = None
|
||||
|
||||
@property
|
||||
def meta(self):
|
||||
task = app.tasks.get(self.name, None)
|
||||
|
@ -25,23 +28,43 @@ class CeleryTask(models.Model):
|
|||
|
||||
@property
|
||||
def summary(self):
|
||||
if self.__summary is not None:
|
||||
return self.__summary
|
||||
executions = CeleryTaskExecution.objects.filter(name=self.name)
|
||||
total = executions.count()
|
||||
success = executions.filter(state='SUCCESS').count()
|
||||
return {'total': total, 'success': success}
|
||||
|
||||
@summary.setter
|
||||
def summary(self, value):
|
||||
self.__summary = value
|
||||
|
||||
@staticmethod
|
||||
def compute_state_color(states: list, default_count=5):
|
||||
color = 'green'
|
||||
states = states[:default_count]
|
||||
if not states:
|
||||
return color
|
||||
if states[0] == 'FAILURE':
|
||||
color = 'red'
|
||||
elif 'FAILURE' in states:
|
||||
color = 'yellow'
|
||||
return color
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
last_five_executions = CeleryTaskExecution.objects.filter(name=self.name).order_by('-date_published')[:5]
|
||||
if self.__state is not None:
|
||||
return self.__state
|
||||
last_five_executions = CeleryTaskExecution.objects.filter(
|
||||
name=self.name
|
||||
).order_by('-date_published').values('state')[:5]
|
||||
states = [i['state'] for i in last_five_executions]
|
||||
color = self.compute_state_color(states)
|
||||
return color
|
||||
|
||||
if len(last_five_executions) > 0:
|
||||
if last_five_executions[0].state == 'FAILURE':
|
||||
return "red"
|
||||
|
||||
for execution in last_five_executions:
|
||||
if execution.state == 'FAILURE':
|
||||
return "yellow"
|
||||
return "green"
|
||||
@state.setter
|
||||
def state(self, value):
|
||||
self.__state = value
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Celery Task")
|
||||
|
|
Loading…
Reference in New Issue