Python 비동기 처리에서 asyncio.gather와 as_completed 선택 기준
문제 상황
외부 API 100개를 동시에 호출해서 데이터를 수집하는 작업이 있었다. 처음엔 asyncio.gather()를 사용했는데, 일부 API가 느리거나 타임아웃될 때 전체 응답을 기다려야 하는 문제가 있었다.
# 기존 코드
results = await asyncio.gather(*tasks)
# 가장 느린 작업이 끝날 때까지 대기
as_completed 도입
완료된 작업부터 처리하고 싶어서 asyncio.as_completed()로 변경했다.
for coro in asyncio.as_completed(tasks):
try:
result = await coro
process_result(result) # 완료되는 즉시 처리
except Exception as e:
logger.error(f"Task failed: {e}")
이렇게 하니 빠른 API 응답부터 바로 DB에 저장할 수 있어서 체감 속도가 개선되었다.
선택 기준
gather 사용:
- 모든 결과가 필요할 때
- 결과 순서가 중요할 때
- 간단한 병렬 처리
as_completed 사용:
- 완료된 것부터 처리해야 할 때
- 진행률 표시가 필요할 때
- 일부 실패를 허용해야 할 때
# gather with return_exceptions
results = await asyncio.gather(*tasks, return_exceptions=True)
for result in results:
if isinstance(result, Exception):
handle_error(result)
프로젝트에서는 as_completed로 변경 후 사용자에게 실시간으로 진행 상황을 보여줄 수 있게 되어 만족스러웠다.