fix(swarm-updates): offload tarball build to worker thread
tar_working_tree (walks repo + gzips several MB) and detect_git_sha (shells out) were called directly on the event loop, so /swarm-updates/push and /swarm-updates/push-self froze every other request until the tarball was ready. Wrap both in asyncio.to_thread.
This commit is contained in:
@@ -136,8 +136,12 @@ async def api_push_update(
|
|||||||
) -> PushUpdateResponse:
|
) -> PushUpdateResponse:
|
||||||
targets = await _resolve_targets(repo, req)
|
targets = await _resolve_targets(repo, req)
|
||||||
tree_root = _master_tree_root()
|
tree_root = _master_tree_root()
|
||||||
sha = detect_git_sha(tree_root)
|
# Both `detect_git_sha` (shells out) and `tar_working_tree` (walks the repo
|
||||||
tarball = tar_working_tree(tree_root, extra_excludes=req.exclude)
|
# + gzips a few MB) are synchronous CPU+I/O. Running them directly on the
|
||||||
|
# event loop blocks every other request until the tarball is built — the
|
||||||
|
# dashboard freezes on /swarm-updates push. Offload to a worker thread.
|
||||||
|
sha = await asyncio.to_thread(detect_git_sha, tree_root)
|
||||||
|
tarball = await asyncio.to_thread(tar_working_tree, tree_root, extra_excludes=req.exclude)
|
||||||
log.info(
|
log.info(
|
||||||
"swarm_updates.push sha=%s tarball=%d hosts=%d include_self=%s",
|
"swarm_updates.push sha=%s tarball=%d hosts=%d include_self=%s",
|
||||||
sha or "(not a git repo)", len(tarball), len(targets), req.include_self,
|
sha or "(not a git repo)", len(tarball), len(targets), req.include_self,
|
||||||
|
|||||||
@@ -76,8 +76,10 @@ async def api_push_update_self(
|
|||||||
) -> PushUpdateResponse:
|
) -> PushUpdateResponse:
|
||||||
targets = await _resolve_targets(repo, req)
|
targets = await _resolve_targets(repo, req)
|
||||||
tree_root = _master_tree_root()
|
tree_root = _master_tree_root()
|
||||||
sha = detect_git_sha(tree_root)
|
# Offload sync I/O (git shell-out + tar+gzip of the repo) so the event
|
||||||
tarball = tar_working_tree(tree_root, extra_excludes=req.exclude)
|
# loop stays responsive while the tarball is being built.
|
||||||
|
sha = await asyncio.to_thread(detect_git_sha, tree_root)
|
||||||
|
tarball = await asyncio.to_thread(tar_working_tree, tree_root, extra_excludes=req.exclude)
|
||||||
log.info(
|
log.info(
|
||||||
"swarm_updates.push_self sha=%s tarball=%d hosts=%d",
|
"swarm_updates.push_self sha=%s tarball=%d hosts=%d",
|
||||||
sha or "(not a git repo)", len(tarball), len(targets),
|
sha or "(not a git repo)", len(tarball), len(targets),
|
||||||
|
|||||||
Reference in New Issue
Block a user