<commit_before>import logging

from django.conf import settings
from django.contrib import messages
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.utils.translation import ugettext as _

logger = logging.getLogger('pretix.presale.async')


class AsyncAction:
    task = None
    success_url = None
    error_url = None

    def do(self, *args):
        if settings.HAS_CELERY:
            from pretix.celery import app

            if hasattr(self.task, 'task') and isinstance(self.task.task, app.Task):
                return self._do_celery(args)
            else:
                raise TypeError('Method has no task attached')
        else:
            return self._do_sync(args)

    def get_success_url(self, value):
        return self.success_url

    def get_error_url(self):
        return self.error_url

    def get_check_url(self, task_id, ajax):
        return self.request.path + '?async_id=%s' % task_id + ('&ajax=1' if ajax else '')

    def get(self, request, *args, **kwargs):
        if 'async_id' in request.GET and settings.HAS_CELERY:
            return self.get_result(request)
        return self.http_method_not_allowed(request)

    def get_result(self, request):
        from celery.result import AsyncResult
        res = AsyncResult(request.GET.get('async_id'))
        if 'ajax' in self.request.GET:
            data = {
                'async_id': res.id,
                'ready': res.ready()
            }
            if res.ready():
                if res.successful() and not isinstance(res.info, Exception):
                    smes = self.get_success_message(res.info)
                    if smes:
                        messages.success(self.request, smes)
                    # TODO: Do not store message if the ajax client stats that it will not redirect
                    # but handle the mssage itself
                    data.update({
                        'redirect': self.get_success_url(res.info),
                        'message': self.get_success_message(res.info)
                    })
                else:
                    messages.error(self.request, self.get_error_message(res.info))
                    # TODO: Do not store message if the ajax client stats that it will not redirect
                    # but handle the mssage itself
                    data.update({
                        'redirect': self.get_error_url(),
                        'message': self.get_error_message(res.info)
                    })
            return JsonResponse(data)
        else:
            if res.ready():
                if res.successful():
                    return self.success(res.info)
                else:
                    return self.error(res.info)
            return render(request, 'pretixpresale/waiting.html')
<commit_msg>Try to improve async task performance by using more long-running requests<commit_after>import logging

import celery.exceptions
from django.conf import settings
from django.contrib import messages
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.utils.translation import ugettext as _

logger = logging.getLogger('pretix.presale.async')


class AsyncAction:
    task = None
    success_url = None
    error_url = None

    def do(self, *args):
        if settings.HAS_CELERY:
            from pretix.celery import app

            if hasattr(self.task, 'task') and isinstance(self.task.task, app.Task):
                return self._do_celery(args)
            else:
                raise TypeError('Method has no task attached')
        else:
            return self._do_sync(args)

    def get_success_url(self, value):
        return self.success_url

    def get_error_url(self):
        return self.error_url

    def get_check_url(self, task_id, ajax):
        return self.request.path + '?async_id=%s' % task_id + ('&ajax=1' if ajax else '')

    def get(self, request, *args, **kwargs):
        if 'async_id' in request.GET and settings.HAS_CELERY:
            return self.get_result(request)
        return self.http_method_not_allowed(request)

    def get_result(self, request):
        from celery.result import AsyncResult
        res = AsyncResult(request.GET.get('async_id'))
        if 'ajax' in self.request.GET:
            if not res.ready():
                try:
                    res.get(timeout=0.5)
                except celery.exceptions.TimeoutError:
                    pass

            ready = res.ready()
            data = {
                'async_id': res.id,
                'ready': ready
            }
            if ready:
                if res.successful() and not isinstance(res.info, Exception):
                    smes = self.get_success_message(res.info)
                    if smes:
                        messages.success(self.request, smes)
                    # TODO: Do not store message if the ajax client stats that it will not redirect
                    # but handle the mssage itself
                    data.update({
                        'redirect': self.get_success_url(res.info),
                        'message': self.get_success_message(res.info)
                    })
                else:
                    messages.error(self.request, self.get_error_message(res.info))
                    # TODO: Do not store message if the ajax client stats that it will not redirect
                    # but handle the mssage itself
                    data.update({
                        'redirect': self.get_error_url(),
                        'message': self.get_error_message(res.info)
                    })
            return JsonResponse(data)
        else:
            if res.ready():
                if res.successful():
                    return self.success(res.info)
                else:
                    return self.error(res.info)
            return render(request, 'pretixpresale/waiting.html')

{'fraction_non_alphanumeric': 0.08433936955063716, 'fraction_numerical': 0.0006706908115358819, 'mean_word_length': 1.6736889287315104, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5811251', 'n_tokens_mistral': 1595, 'n_tokens_neox': 1511, 'n_words': 416}