본문 바로가기

오류모음집/python

TypeError: 'ThreadPoolExecutor' object does not support the asynchronous context manager protocol

반응형

 

 

발생 경위 :  비동기 함수에 ThreadPool 올림

# fmt: off
async def coin_present_websocket(connection_class: connection) -> None:
    """두 개의 코인 웹소켓을 동시에 실행."""
    async with ThreadPoolExecutor(max_workers=2) as executor:
        loop = asyncio.get_running_loop()

        # 클라이언트 클래스를 매개변수로 전달하여 작업 실행
        korea_task = loop.run_in_executor(
            executor, asyncio.run, run_coin_websocket(connection_class, "BTC", "korea")
        )
        foreign_task = loop.run_in_executor(
            executor, asyncio.run, run_coin_websocket(connection_class, "BTC", "foreign")
        )

        # 두 작업이 완료될 때까지 기다림
        await asyncio.gather(
            korea_task,
            foreign_task,
            return_exceptions=False,
        )

 

 

발생 이유: ThreadPoolExecutor은 비동기 지원을 안함

 

 

해결 방안

async def coin_present_websocket(connection_class) -> None:
    """두 개의 코인 웹소켓을 동시에 실행."""
    loop = asyncio.get_running_loop()

    # 스레드 풀을 생성
    with ThreadPoolExecutor(max_workers=2) as executor:
        # run_in_executor 사용하여 비동기 작업 실행
        korea_task = loop.run_in_executor(
            executor,
            lambda: asyncio.run(run_coin_websocket(connection_class, "BTC", "korea")),
        )
        foreign_task = loop.run_in_executor(
            executor,
            lambda: asyncio.run(run_coin_websocket(connection_class, "BTC", "foreign")),
        )

        # 두 작업이 완료될 때까지 기다림
        await asyncio.gather(
            korea_task,
            foreign_task,
            return_exceptions=False,
        )

 

run_in_executor 메서드를 직접 호출하고 결과를 수집하는 방식으로 변경 

이러면 각 비동기 작업을 스레드에서 실행할 수 있음

반응형