Search code examples
djangodjango-rest-frameworktimeoutdjango-1.11

Aborting long running request in Django


I want to abort a request to an API which takes longer than 5 seconds. I know the client-side code can have a timeout of 5 seconds and that will ensure it doesn't wait any longer than that to get a response, but the Django server would still be processing the request even though the client won't be receiving it at the end. As far as I know, even if I configure this on nginx or gunicorn, those will still act as clients for the Django server app and the same problem will occur - that nginx will not wait for more than 5 seconds, but Django will continue processing the request.

Is there any way I can somehow abort this request processing in Django (application server code level) itself?

For context on the specific use case: This API parses a file and we have a size limit of 5 MB on that file. Even then, for some reason, sometimes, the file parsing takes more than 20-30 seconds, which is why we want to abort the request for this API if it exceeds a certain threshold.


Solution

  • You would have to raise a specific exception after a certain time.

    In order to make sure you always return the same error you could use a custom error handler.

    from rest_framework.views import exception_handler
    
    def custom_exception_handler(exc, context):
        if isinstance(exc, MyTimeoutException):
            return Response(
                {'detail': 'Your request timed out.'},
                status=status.HTTP_408_REQUEST_TIMEOUT)
    
        response = exception_handler(exc, context)
    
    
        return response
    
    REST_FRAMEWORK = {
        'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
    }