Fix rebuild blocking FastAPI event loop
Switch /rebuild endpoint from subprocess.run (blocks event loop) to asyncio.create_subprocess_exec, preventing auth failures on concurrent requests during build. Update site submodule pointer.
This commit is contained in:
+16
-12
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import subprocess
|
|
||||||
import time
|
import time
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -248,21 +248,25 @@ async def delete_story(slug: str, user: dict = Depends(require_auth)) -> JSONRes
|
|||||||
|
|
||||||
@app.post("/rebuild")
|
@app.post("/rebuild")
|
||||||
async def rebuild(user: dict = Depends(require_auth)) -> JSONResponse:
|
async def rebuild(user: dict = Depends(require_auth)) -> JSONResponse:
|
||||||
"""Trigger an astro build of the site."""
|
"""Trigger an astro build of the site (non-blocking)."""
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
["npm", "run", "build"],
|
"npm", "run", "build",
|
||||||
cwd=site_dir,
|
cwd=site_dir,
|
||||||
capture_output=True,
|
stdout=asyncio.subprocess.PIPE,
|
||||||
text=True,
|
stderr=asyncio.subprocess.PIPE,
|
||||||
timeout=120,
|
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=120)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
proc.kill()
|
||||||
|
raise HTTPException(504, "Build timed out after 120s")
|
||||||
return JSONResponse({
|
return JSONResponse({
|
||||||
"success": result.returncode == 0,
|
"success": proc.returncode == 0,
|
||||||
"stdout": result.stdout[-3000:] if result.stdout else "",
|
"stdout": stdout.decode()[-3000:] if stdout else "",
|
||||||
"stderr": result.stderr[-3000:] if result.stderr else "",
|
"stderr": stderr.decode()[-3000:] if stderr else "",
|
||||||
})
|
})
|
||||||
except subprocess.TimeoutExpired:
|
except HTTPException:
|
||||||
raise HTTPException(504, "Build timed out after 120s")
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(500, str(e))
|
raise HTTPException(500, str(e))
|
||||||
|
|||||||
+1
-1
Submodule site updated: 422ffe76fa...c3573b09a3
Reference in New Issue
Block a user