Skip to content

Commit

Permalink
improve taskexec admin listing performance
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierdalang committed Mar 4, 2024
1 parent 9be62ee commit f324019
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ pre-commit install
- refactor: removed non-execution related data from the database (clarifying the fact tha the source of truth is the registry)
- refactor: better support for concurrent workers
- refactor: better names for models and decorators
- refactor: optimise task exec admin listing when `results`, `stdout` or `stderr` holds large data
- infra: included a demo project
- infra: improved testing, including for concurrency behaviour
- infra: updated compatibility to Django 3.2/4.1/4.2 and Python 3.8-3.11
Expand Down
11 changes: 7 additions & 4 deletions django_toosimple_q/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class TaskExecAdmin(ReadOnlyAdmin):
"started_",
"finished_",
"replaced_by_",
"result_",
"result_preview",
"task_",
]
list_display_links = ["task_name"]
Expand Down Expand Up @@ -96,16 +96,19 @@ class TaskExecAdmin(ReadOnlyAdmin):
),
]

def get_queryset(self, request):
# defer stdout, stderr and results which may host large values
qs = super().get_queryset(request)
qs = qs.defer("stdout", "stderr", "result")
return qs

def arguments_(self, obj):
return format_html(
"{}<br/>{}",
truncatechars(str(obj.args), 32),
truncatechars(str(obj.kwargs), 32),
)

def result_(self, obj):
return truncatechars(str(obj.result), 32)

@admin.display(ordering="due")
def due_(self, obj):
return short_naturaltime(obj.due)
Expand Down
29 changes: 29 additions & 0 deletions django_toosimple_q/migrations/0015_taskexec_result_preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.1 on 2024-03-04 15:28

from django.db import migrations, models
from django.template.defaultfilters import truncatechars


def populate_result_preview(apps, schema_editor):
# Populate the new result preview field
TaskExec = apps.get_model("toosimpleq", "TaskExec")
for task_exec in TaskExec.objects.all():
task_exec.result_preview = truncatechars(str(task_exec.result), 255)
task_exec.save()


class Migration(migrations.Migration):
dependencies = [
("toosimpleq", "0014_alter_workerstatus_exit_code"),
]

operations = [
migrations.AddField(
model_name="taskexec",
name="result_preview",
field=models.CharField(
blank=True, editable=False, max_length=255, null=True
),
),
migrations.RunPython(populate_result_preview),
]
5 changes: 5 additions & 0 deletions django_toosimple_q/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from croniter import croniter, croniter_range
from django.db import models
from django.template.defaultfilters import truncatechars
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.timezone import now
Expand Down Expand Up @@ -86,6 +87,9 @@ def done(cls) -> List[str]:
max_length=32, choices=States.choices, default=States.QUEUED
)
result = PickledObjectField(blank=True, null=True)
result_preview = models.CharField(
max_length=255, blank=True, null=True, editable=False
)
error = models.TextField(blank=True, null=True)
replaced_by = models.ForeignKey(
"self", null=True, blank=True, on_delete=models.SET_NULL
Expand Down Expand Up @@ -122,6 +126,7 @@ def execute(self):
stdout, stderr = io.StringIO(), io.StringIO()
with redirect_stderr(stderr), redirect_stdout(stdout):
self.result = task.callable(*self.args, **self.kwargs)
self.result_preview = truncatechars(str(self.result), 255)
logger.info(f"{self} succeeded")
self.state = TaskExec.States.SUCCEEDED
except Exception:
Expand Down

0 comments on commit f324019

Please sign in to comment.