프로그래밍파이썬 개발자(asyncio/백엔드)

파이썬에서 비동기 컨텍스트 관리자(async context manager)란 무엇이며, 어떻게 구현하며, 어디에서 필수적인가?

Hintsage AI 어시스턴트로 면접 통과

답변.

비동기 컨텍스트 관리자Async)는 __aenter____aexit__ 비동기 메서드를 정의하는 객체로, async with 구문에서 사용됩니다. 이 관리자들은 비동기 함수에서 리소스(예: 데이터베이스 연결, 파일, 세션 등)를 올바르게 열고 닫기 위해 필요합니다.

구현 예시:

class AsyncDBConnection: async def __aenter__(self): self.conn = await async_db_connect() return self.conn async def __aexit__(self, exc_type, exc, tb): await self.conn.close() async def main(): async with AsyncDBConnection() as conn: await conn.query('SELECT 1')

비동기 컨텍스트는 기술적 지연 때문에 이벤트 루프를 차단하지 않아 concurrent 프로그램의 성능을 높입니다.

함정 질문.

일반적인 with를 async def 내부에서 사용할 수 있습니까?

답변: 예, 하지만 컨텍스트 관리자 내의 작업이 awaitable(대기 필요)을 사용하는 경우, 반드시 async with가 필요합니다. 일반적인 with는 비동기 enter/exit를 지원하지 않으며, 이벤트 루프를 차단하거나 enter/exit 내부에서 await을 호출하면 오류가 발생합니다.

예시:

async def foo(): with open('file.txt') as f: # 괜찮습니다, 읽기는 동기적입니다. data = f.read() # 그러나 일반 컨텍스트 안에서는 await을 사용할 수 없으며, 오직 async with 안에서만 가능합니다.

주제의 미묘함을 잘 알지 못해 발생한 실제 오류 사례.


이야기

프로젝트: 비동기 API가 있는 웹 서비스.

문제: 데이터베이스 연결 관리자가 일반 with를 사용했지만 내부에서 await이 호출되었습니다. 이로 인해 RuntimeError("Cannot use 'await' outside async function") 오류가 발생하고 프로덕션에서 이벤트 루프가 차단되었습니다.


이야기

프로젝트: 웹소켓 채팅.

문제: 연결 작업 시 웹소켓 리소스가 닫히지 않았습니다 (일반 동기 관리자 사용), 이로 인해 메모리 누수와 응답하지 않는 연결이 발생했습니다.


이야기

프로젝트: 멀티스레드 비동기 작업 큐.

문제: 작업 관리자에서 __aexit__를 잘못 구현하였고, awaitable을 반환하는 것을 잊었습니다. 이로 인해 작업 완료가 보장되지 않았고 일부 작업이 시스템에 "걸렸습니다."