perf: unblock event loop for segment_efforts scan

Extract the synchronous segment-file scan into a plain function and
dispatch it via asyncio.to_thread so it runs in a thread pool instead
of blocking the event loop during concurrent fetches.
This commit is contained in:
Davide Scaini
2026-05-19 19:53:26 +02:00
parent 29c6e399c0
commit 835968e8fe
+16 -11
View File
@@ -351,13 +351,16 @@ async def activity_segment_efforts(
bincio_session: str | None = Cookie(default=None), bincio_session: str | None = Cookie(default=None),
) -> JSONResponse: ) -> JSONResponse:
"""Return segment efforts that belong to a specific activity for the logged-in user.""" """Return segment efforts that belong to a specific activity for the logged-in user."""
import asyncio
from bincio.segments import store as _seg_store from bincio.segments import store as _seg_store
user = deps._require_user(bincio_session) user = deps._require_user(bincio_session)
dd = deps._get_data_dir() dd = deps._get_data_dir()
efforts_dir = dd / user.handle / "segment_efforts"
result = [] def _collect() -> list[dict]:
if efforts_dir.exists(): efforts_dir = dd / user.handle / "segment_efforts"
import json as _json result: list[dict] = []
if not efforts_dir.exists():
return result
for ef_file in sorted(efforts_dir.glob("*.json")): for ef_file in sorted(efforts_dir.glob("*.json")):
seg_id = ef_file.stem seg_id = ef_file.stem
all_efforts = _seg_store.load_efforts(dd, user.handle, seg_id) all_efforts = _seg_store.load_efforts(dd, user.handle, seg_id)
@@ -370,11 +373,13 @@ async def activity_segment_efforts(
pr_elapsed = min(e.elapsed_s for e in all_efforts) pr_elapsed = min(e.elapsed_s for e in all_efforts)
for eff in matching: for eff in matching:
result.append({ result.append({
"segment_id": seg.id, "segment_id": seg.id,
"segment_name": seg.name, "segment_name": seg.name,
"segment_distance_m": seg.distance_m, "segment_distance_m": seg.distance_m,
"elapsed_s": eff.elapsed_s, "elapsed_s": eff.elapsed_s,
"pr_elapsed_s": pr_elapsed, "pr_elapsed_s": pr_elapsed,
"started_at": _seg_store._iso(eff.started_at), "started_at": _seg_store._iso(eff.started_at),
}) })
return JSONResponse(result) return result
return JSONResponse(await asyncio.to_thread(_collect))