Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

275
Vistas
¿Cómo puedo tener una fachada sincrónica sobre las API asyncpg con Python asyncio?

Imagine una aplicación web aiohttp asíncrona que es compatible con una base de datos Postgresql conectada a través asyncpg y no realiza otras E/S. ¿Cómo puedo tener una capa intermedia que aloje la lógica de la aplicación, que no sea asíncrona? (Sé que simplemente puedo hacer que todo sea asíncrono, pero imagine que mi aplicación tiene una lógica de aplicación masiva , solo limitada por la E/S de la base de datos, y no puedo tocar todo).

Pseudocódigo:

 async def handler(request): # call into layers over layers of application code, that simply emits SQL ... def application_logic(): ... # This doesn't work, obviously, as await is a syntax # error inside synchronous code. data = await asyncpg_conn.execute("SQL") ... # What I want is this: data = asyncpg_facade.execute("SQL") ...

¿Cómo se puede construir una fachada síncrona sobre asyncpg , que permita que la lógica de la aplicación haga llamadas a la base de datos? Las recetas que flotan, como usar async.run() o asyncio.run_coroutine_threadsafe() , etc., no funcionan en este caso, ya que venimos de un contexto asíncrono. Supongo que esto no puede ser imposible, ya que ya existe un bucle de eventos que, en principio, podría ejecutar la asyncpg asyncpg.

Pregunta de bonificación: ¿cuál es la razón de diseño para hacer que await inside sync sea un error de sintaxis? ¿No sería bastante útil permitir la await desde cualquier contexto que se originó en una corrutina, de modo que tuviéramos medios simples para descomponer una aplicación en bloques de construcción funcionales?

EDITAR Bonificación adicional: más allá de la muy buena respuesta de Paul , que permanece dentro de la "zona segura", me interesarían las soluciones que eviten bloquear el hilo principal (lo que lleva a algo más gevent-ish). Vea también mi comentario sobre la respuesta de Paul ...

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Debe crear un subproceso secundario donde ejecute su código asíncrono. Inicializa el subproceso secundario con su propio bucle de eventos, que se ejecuta para siempre. Ejecute cada función asíncrona llamando a run_coroutine_threadsafe() y llamando a result() en el objeto devuelto. Esa es una instancia de concurrent.futures.Future, y su método result() no regresa hasta que el resultado de la rutina esté listo desde el subproceso secundario.

Entonces, su hilo principal es, en efecto, llamar a cada función asíncrona como si fuera una función de sincronización. El subproceso principal no continúa hasta que finaliza cada llamada de función. Por cierto, no importa si su función de sincronización se está ejecutando realmente en un contexto de bucle de eventos o no.

Las llamadas a result(), por supuesto, bloquearán el ciclo de eventos del hilo principal. Eso no se puede evitar si desea obtener el efecto de ejecutar una función asíncrona desde el código de sincronización.

No hace falta decir que esto es algo feo y sugiere una estructura de programa incorrecta. Pero está tratando de convertir un programa heredado, y puede ayudar con eso.

 import asyncio import threading from datetime import datetime def main(): def thr(loop): asyncio.set_event_loop(loop) loop.run_forever() loop = asyncio.new_event_loop() t = threading.Thread(target=thr, args=(loop, ), daemon=True) t.start() print("Hello", datetime.now()) t1 = asyncio.run_coroutine_threadsafe(f1(1.0), loop).result() t2 = asyncio.run_coroutine_threadsafe(f1(2.0), loop).result() print(t1, t2) if __name__ == "__main__": main() >>> Hello 2021-10-26 20:37:00.454577 >>> Hello 1.0 2021-10-26 20:37:01.464127 >>> Hello 2.0 2021-10-26 20:37:03.468691 >>> 1.0 2.0
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda