python - ¿Cómo ejecutar la función de rutina cuando se usa sync_to_async en Django?

CorePress2024-01-24  10

Tengo el método add_event que llama al método _post como asíncrono usando sync_to_async en Django. pero cuando pruebo el método dentro del shell de Django, ni siquiera ejecuta mi función asíncrona _post y en su lugar devuelve un objeto de rutina.

Este es mi método:

@classmethod
def add_event(cls, data):
    async_post_request = sync_to_async(
        cls._post, thread_sensitive=True
    )
    response = async_post_request(
        url=cls.ADD_EVENT,
        data=data,
        headers=cls.get_headers(),
        json_response=False,
    )
    return response

Captura de pantalla del shell de Django:



------------------------------------

Dado que la función asíncrona devuelve una corrutina, debes esperarla o ejecutarla con asyncio. Dado que lo llama desde un contexto de sincronización, debe usar la última opción:

import asyncio

@classmethod
def add_event(cls, data):
    async_post_request = sync_to_async(
        cls._post, thread_sensitive=True
    )
    response = asyncio.run(async_post_request(
        url=cls.ADD_EVENT,
        data=data,
        headers=cls.get_headers(),
        json_response=False,
    ))
    return response

2

mi versión de Python es 3.6.12 y no tiene un método de ejecución. Además, en Django docs no hay función de ejecución. docs.djangoproject.com/en/dev/topics/async/#sync-to-async

-Ali Soltani

27/03/2021 a las 10:17

Asyncio.run no se recomienda en Django ya que no es seguro para operaciones IO. En tal caso, querrás utilizar await async_to_sync(func)(...). Lo que esencialmente haría que esta doble envolturapped async_to_sync(sync_to_async(func, thread_SENSITIVE=True))(...) que es completamente inútil. Simplemente ejecute func(...); solo perderá eficiencia si realiza una doble envoltura.

- JayTurnr

7 de enero de 2022 a las 21:18



------------------------------------

Probablemente sea mejor reescribir la función IO _get para que sea asincrónica de forma nativa. Utilice una biblioteca http asíncrona como aiohttp. Luego puedes usar async_to_sync(cls._get)(...) desde add_event. Actualmente estás convirtiendo una función de sincronización a asíncrona solo para volver a convertirla directamente en sincronización, lo que hace que Django cambie innecesariamente.tch en una salida de asincronía. Lo que le cuesta alrededor de 4 milisegundos por cada llamada, y no hay ningún beneficio en acelerar porque la función seguirá ejecutándose sincrónicamente de todos modos.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare