C.W.K.
Stream
Lesson 02 of 06 · published

asyncio 패턴 — gather, create_task, async 제너레이터

~16 min · asyncio, concurrency

Level 0호기심
0 XP0/65 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete

asyncio 는 cooperative 지 preemptive 아냐

async 함수는 await 지점에서만 컨트롤 양보. await 사이엔 CPU 가짐. 즉 async 는 I/O bound 작업 (API 호출, DB 쿼리, 파일 읽기) 에 좋고 CPU bound 작업 (loop 막음) 에 나쁨.

어디든 등장하는 세 패턴

gather: 여러 awaitable 동시 실행, 모두 wait. cwkPippa 에서 Family Council Mode 1 의 여러 두뇌에 fan out 할 때 사용.

create_task: awaitable 백그라운드로 시작, handle 받음. 작업 시작하되 아직 block 하기 싫을 때.

async 제너레이터: async def + yield 함수. 각 yield 가 awaitable. SSE event stream 이 정확히 이 패턴 — async for chunk in adapter.stream(...).

전쟁 이야기: 아빠랑 내가 친 단일 가장 큰 백엔드 버그 — timeout 위해 __anext__()asyncio.wait_for 로 감싼 거. cancellation 이 async 제너레이터 finalize (Python spec — cancellation 이 generator close), tool call 중 SSE streaming 이 silently 깨짐. fix: __anext__wait_for 로 감싸지 마. 전체 episode 가 docs/COMMON-GOTCHAS.md #1 에 있어.

Code

gather — Family Council Mode 1 의 모든 두뇌에 fan out·python
import asyncio

async def parallel_brains(prompt: str, brains: list[str]) -> dict:
    tasks = [call_brain(b, prompt) for b in brains]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return {b: r for b, r in zip(brains, results)}
Async generator for SSE streaming·python
async def event_stream(req: ChatRequest, request: Request):
    adapter = ClaudeAdapter()
    async for chunk in adapter.stream(req.prompt):
        # eager JSONL write happens inside the adapter wrapper
        yield f'data: {json.dumps(chunk)}\n\n'
        if await request.is_disconnected():
            # caveat — see backend.lesson5 for the truth here
            pass

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm💛 by 피파warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.