perf: fix false parallelism — sequential awaits disguised as concurrent #87

Closed
opened 2026-03-20 13:16:53 +00:00 by cal · 0 comments
Owner

Problem

Several places create coroutine objects and then await them sequentially, which looks like parallelism but executes serially. In Python, coro = some_async_func() does NOT start execution — it only begins on await.

Locations

commands/transactions/management.py lines 137–143

pending_task = transaction_service.get_pending_transactions(...)
frozen_task = transaction_service.get_frozen_transactions(...)
processed_task = transaction_service.get_processed_transactions(...)

pending_transactions = await pending_task    # runs first
frozen_transactions = await frozen_task      # runs second
processed_transactions = await processed_task  # runs third

services/stats_service.py lines 132–163 (get_player_stats)

batting_task = self.get_batting_stats(player_id, season)
pitching_task = self.get_pitching_stats(player_id, season)
batting_stats = await batting_task      # sequential despite variable names
pitching_stats = await pitching_task

Fix

Replace with asyncio.gather():

pending, frozen, processed = await asyncio.gather(
    transaction_service.get_pending_transactions(...),
    transaction_service.get_frozen_transactions(...),
    transaction_service.get_processed_transactions(...),
)

Impact

HIGH — These are user-facing commands where each API call adds 50–200ms of latency that could overlap.

## Problem Several places create coroutine objects and then `await` them sequentially, which looks like parallelism but executes serially. In Python, `coro = some_async_func()` does NOT start execution — it only begins on `await`. ## Locations ### `commands/transactions/management.py` lines 137–143 ```python pending_task = transaction_service.get_pending_transactions(...) frozen_task = transaction_service.get_frozen_transactions(...) processed_task = transaction_service.get_processed_transactions(...) pending_transactions = await pending_task # runs first frozen_transactions = await frozen_task # runs second processed_transactions = await processed_task # runs third ``` ### `services/stats_service.py` lines 132–163 (`get_player_stats`) ```python batting_task = self.get_batting_stats(player_id, season) pitching_task = self.get_pitching_stats(player_id, season) batting_stats = await batting_task # sequential despite variable names pitching_stats = await pitching_task ``` ## Fix Replace with `asyncio.gather()`: ```python pending, frozen, processed = await asyncio.gather( transaction_service.get_pending_transactions(...), transaction_service.get_frozen_transactions(...), transaction_service.get_processed_transactions(...), ) ``` ## Impact **HIGH** — These are user-facing commands where each API call adds 50–200ms of latency that could overlap.
cal added the
ai-working
label 2026-03-20 13:18:34 +00:00
cal removed the
ai-working
label 2026-03-20 13:21:31 +00:00
cal closed this issue 2026-03-20 14:22:50 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/major-domo-v2#87
No description provided.