fix(dashcam): prevent site freeze during import/convert
- _convert_bg now runs in real threading.Thread (not gevent greenlet) so ffmpeg proc.wait() doesn't block gevent event loop - _device_lock released before copy loop; only held for mount/unmount so /api/dash/files and other routes don't block during long copies - Date now shows time (Aug 9, 10:30 PM) on mobile video rows - Spacing added above converting spinner badge Co-authored-by: Copilot <[email protected]>
This commit is contained in:
+13
-11
@@ -559,17 +559,19 @@ def import_dashcam(
|
||||
"message": f"Failed to mount {device_path}.",
|
||||
}
|
||||
|
||||
try:
|
||||
summary = copy_files(source, destination_folder, relative_paths)
|
||||
summary["status"] = (
|
||||
"invalid_selection" if summary.pop("invalid_selection", False) else "ok"
|
||||
)
|
||||
if summary["status"] == "invalid_selection":
|
||||
summary["message"] = summary["errors"][0]
|
||||
summary["device"] = device_path
|
||||
return summary
|
||||
finally:
|
||||
if mounted_here:
|
||||
# Lock released — copy runs without blocking other requests
|
||||
try:
|
||||
summary = copy_files(source, destination_folder, relative_paths)
|
||||
summary["status"] = (
|
||||
"invalid_selection" if summary.pop("invalid_selection", False) else "ok"
|
||||
)
|
||||
if summary["status"] == "invalid_selection":
|
||||
summary["message"] = summary["errors"][0]
|
||||
summary["device"] = device_path
|
||||
return summary
|
||||
finally:
|
||||
if mounted_here:
|
||||
with _device_lock:
|
||||
unmount_device(mount_point)
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
import threading
|
||||
|
||||
import gevent
|
||||
from gevent import sleep
|
||||
@@ -35,7 +36,9 @@ def queue_convert(relative_path):
|
||||
if relative_path in _converting:
|
||||
return
|
||||
_converting.add(relative_path)
|
||||
gevent.spawn(_convert_bg, relative_path)
|
||||
gevent.sleep(0) # yield before spawning thread
|
||||
t = threading.Thread(target=_convert_bg, args=(relative_path,), daemon=True)
|
||||
t.start()
|
||||
|
||||
|
||||
def _convert_bg(relative_path):
|
||||
@@ -59,8 +62,7 @@ def _convert_bg(relative_path):
|
||||
tmp_path,
|
||||
]
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
while proc.poll() is None:
|
||||
sleep(1)
|
||||
proc.wait() # real thread — blocking wait is fine
|
||||
if proc.returncode == 0 and os.path.isfile(tmp_path) and os.path.getsize(tmp_path) > 0:
|
||||
os.replace(tmp_path, mp4_path)
|
||||
# Delete original now that MP4 is ready
|
||||
|
||||
Reference in New Issue
Block a user