Как сделать из асинхронного итератора обычный

У меня асинхронная программа, в ней есть очередь, куда я кладу обработанные результаты

queue = asyncio.Queue(2<<10)

Пока вот таким генератором данные забираю

def get_records(queue):
    while queue.qsize():
        r = queue.get_nowait()
        yield r
        self.q.task_done()

Но из-за того что он сейчас быстро заканчивается приходится переподключаться к базе:

        while True:
             async with pg.acquire() as connection:
                 await connection.copy_records_to_table(
                     'radarlog2',
                     records = get_records(queue)
                 )
             await asyncio.sleep(1)

Где pg это пут asyncpg. Где-то в недрах copy_records_to_table есть поддержка асинхронного итератора, но до него не доходит с ошибной что он не итерируемый.

Как бы сделать await queue.get() не блокируя евент луп?

  • loop.run_until_complete не работает с запущенным лупом

  • asyncio.run_coroutine_threadsafe блокирует

  • asgiref/sync стартует новые треды и весьма громоздкая конструкция


Ответы (1 шт):

Автор решения: eri

На сам вопрос пока ответа нет, но по конкретному примеру. Если собрать стек вызово вручную до https://github.com/MagicStack/asyncpg/blob/690048dbaaebac6172f003a9805bbb63abd28d8c/asyncpg/protocol/protocol.pyx#L461 , то через ридер получится то что нужно. Но слишком много мелкой копипасты.

→ Ссылка