fix: move HEAD request out of critical path — non-blocking background thread
The 10s HEAD request for Content-Length blocked the download endpoint response. nginx proxy in front (bench.srv2.sechpoint.app:443 → :5000) timed out waiting, returned empty response → 'data is null' JS error. Now wget starts immediately, response returns instantly, and HEAD runs in a daemon thread to populate content_length for ETA later.
This commit is contained in:
parent
c31ad3409a
commit
adfb68fe6b
1 changed files with 15 additions and 12 deletions
|
|
@ -20,6 +20,7 @@ from logging.handlers import RotatingFileHandler
|
|||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
|
@ -262,17 +263,7 @@ async def upload_raw(request: Request):
|
|||
if free_gb < 50:
|
||||
logger.warning("Low disk: %.1f GB free — download may fail", free_gb)
|
||||
|
||||
# Try to get file size via HEAD request (for speed estimation)
|
||||
content_length = 0
|
||||
try:
|
||||
head_resp = http_requests.head(url, timeout=10, allow_redirects=True)
|
||||
cl = head_resp.headers.get("Content-Length")
|
||||
if cl:
|
||||
content_length = int(cl)
|
||||
logger.info("Download size from HEAD: %.1f GiB", content_length / (1024**3))
|
||||
except Exception:
|
||||
logger.info("Could not determine download size (HEAD failed — will skip ETA check)")
|
||||
|
||||
# Start wget immediately (HEAD request for size happens in background)
|
||||
logger.info("Starting background download: %s → %s", url, dest)
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
|
|
@ -288,10 +279,22 @@ async def upload_raw(request: Request):
|
|||
"vmid": vmid,
|
||||
"vm_name": vm_name,
|
||||
"start_time": time.time(),
|
||||
"content_length": content_length,
|
||||
"content_length": 0,
|
||||
"_last_logged_bytes": 0,
|
||||
}
|
||||
|
||||
# Fire-and-forget HEAD request to get file size for ETA (non-blocking)
|
||||
def _fetch_content_length():
|
||||
try:
|
||||
head_resp = http_requests.head(url, timeout=5, allow_redirects=True)
|
||||
cl = head_resp.headers.get("Content-Length")
|
||||
if cl and filename in _active_downloads:
|
||||
_active_downloads[filename]["content_length"] = int(cl)
|
||||
logger.info("Download size from HEAD: %.1f GiB", int(cl) / (1024**3))
|
||||
except Exception:
|
||||
pass
|
||||
threading.Thread(target=_fetch_content_length, daemon=True).start()
|
||||
|
||||
return JSONResponse({
|
||||
"phase": "downloading",
|
||||
"filename": filename,
|
||||
|
|
|
|||
Loading…
Reference in a new issue