Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: LSDV-5425-1: Fix possible performance regression introduced in #4588 #4623

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions label_studio/core/utils/db.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional, TypeVar
import logging

from core.feature_flags import flag_set
from django.db import models
from django.db.models import Subquery
from django.db.models import Model, QuerySet, Subquery

if TYPE_CHECKING:
from users.models import User
Expand All @@ -16,14 +16,16 @@ class SQCount(Subquery):
output_field = models.IntegerField()


def fast_first(queryset):
ModelType = TypeVar('ModelType', bound=Model)

def fast_first(queryset: QuerySet[ModelType]) -> Optional[ModelType]:
"""Replacement for queryset.first() when you don't need ordering,
queryset.first() works slowly in some cases
"""
try:
return queryset.all()[0]
except IndexError:
return None

if queryset[:1]:
return queryset[0]
return None


def should_run_bulk_update_in_transaction(organization_created_by_user: "User") -> bool:
Expand Down
2 changes: 1 addition & 1 deletion label_studio/tasks/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ def post_process_bulk_update_stats(cls, tasks) -> None:
class AnnotationMixin:
def has_permission(self, user: "User") -> bool:
"""Called by Annotation#has_permission"""
return True
return True
24 changes: 14 additions & 10 deletions label_studio/tasks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
string_is_url,
temporary_disconnect_list_signal,
)
from core.utils.db import should_run_bulk_update_in_transaction
from core.utils.db import fast_first, should_run_bulk_update_in_transaction
from core.utils.params import get_env
from data_import.models import FileUpload
from data_manager.managers import PreparedTaskManager, TaskManager
Expand Down Expand Up @@ -189,13 +189,15 @@ def get_locked_by(cls, user, project=None, tasks=None):
"""Retrieve the task locked by specified user. Returns None if the specified user didn't lock anything."""
lock = None
if project is not None:
lock = TaskLock.objects.filter(
user=user, expire_at__gt=now(), task__project=project
).first()
lock = fast_first(
TaskLock.objects.filter(
user=user, expire_at__gt=now(), task__project=project
)
)
elif tasks is not None:
locked_task = tasks.filter(
locks__user=user, locks__expire_at__gt=now()
).first()
jombooth marked this conversation as resolved.
Show resolved Hide resolved
locked_task = fast_first(
tasks.filter(locks__user=user, locks__expire_at__gt=now())
)
if locked_task:
return locked_task
else:
Expand Down Expand Up @@ -357,9 +359,11 @@ def resolve_uri(self, task_data, project):
):
# permission check: resolve uploaded files to the project only
file_upload = None
file_upload = FileUpload.objects.filter(
project=project, file=prepared_filename
).first()
file_upload = fast_first(
FileUpload.objects.filter(
project=project, file=prepared_filename
)
)
if file_upload is not None:
if flag_set(
"ff_back_dev_2915_storage_nginx_proxy_26092022_short",
Expand Down
Loading