Skip to content

How-to: 並行処理パターンの選び方

FT188(threading)〜 FT192(asyncio)の知見をまとめたガイド。 nene2-python では UseCase 層は HTTP に依存しないため、並行処理の選択は UseCase または HTTP ハンドラー層で行う。


クイック選択表

用途推奨FT
FastAPI ハンドラー内の I/O 待ちasync def + awaitFT192
同期 UseCase を非ブロッキング実行AsyncUseCaseProtocolFT6, FT14
CPU バウンドをスレッドに逃がすasyncio.to_thread() または ThreadPoolExecutorFT188, FT191
CPU バウンドをプロセスに逃がすProcessPoolExecutor / multiprocessingFT190, FT191
バックグラウンドで外部コマンドsubprocessshell=False + allowlist)FT189
共有 in-memory キャッシュTtlCache[V](スレッドセーフ)FT119, FT171

asyncio(FT192)

FastAPI ルートは async def が基本。複数 I/O を並列化する場合:

python
import asyncio

async def execute(self, input_: ListNotesInput) -> ListNotesOutput:
    items_task = asyncio.create_task(self._repository.find_all_async(...))
    total_task = asyncio.create_task(self._repository.count_async())
    items, total = await asyncio.gather(items_task, total_task)
    return ListNotesOutput(items=items, total=total, ...)

注意: Pydantic v2 は floatint に切り捨て変換する。数値境界は Field(ge=..., le=...) で明示する。


threading(FT188)

GIL 下では CPU 並列化には不向きだが、ブロッキング I/O を async 化しないレガシー API との橋渡しに有効。

  • threading.Lock / asyncio.Lock — 共有状態の保護
  • ThreadPoolExecutor — 同期関数のオフロード(FT191 と組み合わせ)

subprocess(FT189)

必須ルール(CLAUDE.md / FT189 セキュリティ診断):

  1. shell=False のみ
  2. コマンド名を allowlist で検証
  3. タイムアウトと stdout サイズ上限
  4. ruff S603 は allowlist 検証後に # noqa: S603(理由を docstring に記載)

nene2 との整合

並行処理
UseCaseAsyncUseCaseProtocol または純粋同期(InMemory テスト可能)
HTTPasync def ハンドラー、BackgroundTasksbackground-tasks.md
Middleware同期 ASGI;ブロッキング処理をミドルウェア内に置かない
MCPUseCase をそのままツール化 — 並行は UseCase 内で完結

詳細レポート: FT188 · FT189 · FT190 · FT191 · FT192

MIT ライセンスの下でリリースされています。