es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Múltiples solicitudes concurrentes en vistas asíncronas de Django.

Desde la versión 3.1, Django admite vistas asíncronas. Tengo una aplicación de Django en ejecución en uvicorn. Estoy intentando escribir una vista asíncrona que pueda manejar múltiples solicitudes de forma concurrente, pero no tengo éxito.

Algunos ejemplos comunes que he visto incluyen realizar múltiples operaciones de E/S lenta desde dentro de la vista:

async def slow_io(n, result):
    await asyncio.sleep(n)
    return result

async def my_view(request, *args, **kwargs):
    task_1 = asyncio.create_task(slow_io(3, 'Hola'))
    task_2 = asyncio.create_task(slow_io(5, 'Mundo'))
    result = await task_1 + await task_2
    return HttpResponse(result)

Esto nos dará “HolaMundo” después de 5 segundos en lugar de 8 porque las solicitudes se ejecutan de forma concurrente.

Lo que quiero es manejar simultáneamente múltiples solicitudes para my_view. Por ejemplo, espero que este código maneje 2 solicitudes simultáneas en 5 segundos, pero tarda 10.

async def slow_io(n, result):
    await asyncio.sleep(n)
    return result

async def my_view(request, *args, **kwargs):
    result = await slow_io(5, 'resultado')
    return HttpResponse(result)

Ejecuto uvicorn con este comando:

uvicorn --host 0.0.0.0 --port 8000 main.asgi:application --reload

La documentación de Django dice:

Los principales beneficios son la capacidad para atender cientos de conexiones sin utilizar hilos de Python.

Entonces es posible.

¿Qué me falta?

ACTUALIZACIÓN:
Parece que mi configuración de prueba estaba incorrecta. Abrí múltiples pestañas en el navegador y las actualicé todas al mismo tiempo. Consulta mi respuesta para obtener más detalles.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Es posible manejar simultáneamente múltiples solicitudes a una vista asíncrona en Django utilizando async-await. El ejemplo de operaciones de E/S lentas dentro de la función de vista se puede utilizar para lograr esto, como se muestra en el fragmento de código a continuación:

    import asyncio
    
    async def slow_io(n, result):
        await asyncio.sleep(n)
        return result
    
    async def my_view(request, *args, **kwargs):
        # Ejecutar operaciones de E/S lentas de forma concurrente utilizando asyncio.gather
        results = await asyncio.gather(
            slow_io(5, 'result1'),
            slow_io(5, 'result2')
        )
        return HttpResponse(f'{results[0]} - {results[1]}')
    

    Este código manejaría dos solicitudes simultáneas y devolvería sus resultados en 5 segundos. Para ejecutar la aplicación de Django con vistas asíncronas en Uvicorn, se puede utilizar el siguiente comando:

    uvicorn --host 0.0.0.0 --port 8000 myproject.asgi:application
    

    Aquí, ‘myproject’ debe ser reemplazado por el nombre del proyecto Django y ‘.asgi:application’ especifica el objeto de aplicación ASGI que se utilizará para ejecutar la aplicación.

    Si la aplicación todavía no maneja las solicitudes de forma concurrente, puede ser debido a una configuración de prueba incorrecta. Abrir múltiples pestañas en un navegador y actualizarlas simultáneamente puede no ser una forma precisa de probar la concurrencia, y se recomienda utilizar una herramienta como Apache Bench o wrk para probar el rendimiento de la aplicación bajo carga.

Comments are closed.