Add campaign layer, GPU model caching, file browser cleanup
- Campaigns: new table, CRUD API, React context + provider
- Sessions: scoped to campaigns, paths under campaigns/{id}/
- File browser: scoped per campaign, removed copy/paste/autoPlay
- Sidebar: campaign selector dropdown at top
- Transcribe: GPU model cached/released via job counter
- Jobs: status text updates dynamically in real-time
- Auto-redirect: blocked when summarize job is active
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
"""
|
||||
Minimal background job runner.
|
||||
|
||||
GPU jobs use a shared counter so the Whisper model stays cached between
|
||||
back-to-back transcriptions and is only released when no more GPU work
|
||||
is queued.
|
||||
"""
|
||||
import threading
|
||||
import traceback
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
@@ -9,10 +14,23 @@ from .errors import PipelineError
|
||||
from .logging_config import get_logger
|
||||
|
||||
log = get_logger(__name__)
|
||||
_executor = ThreadPoolExecutor(max_workers=2) # transcription is GPU-bound anyway; no benefit to more workers
|
||||
_executor = ThreadPoolExecutor(max_workers=1)
|
||||
_gpu_jobs_queued = 0
|
||||
_gpu_lock = threading.Lock()
|
||||
|
||||
|
||||
def submit(job_id: str, fn, *args, **kwargs):
|
||||
def _unload_gpu():
|
||||
"""Release the cached Whisper model from GPU memory."""
|
||||
from .pipeline.transcribe import unload_models
|
||||
unload_models()
|
||||
|
||||
|
||||
def submit(job_id: str, fn, *args, requires_gpu=False, **kwargs):
|
||||
if requires_gpu:
|
||||
with _gpu_lock:
|
||||
global _gpu_jobs_queued
|
||||
_gpu_jobs_queued += 1
|
||||
|
||||
def _run():
|
||||
log.info("Job %s starting", job_id)
|
||||
db.update_job(job_id, status="running", progress="Starting...")
|
||||
@@ -37,5 +55,13 @@ def submit(job_id: str, fn, *args, **kwargs):
|
||||
error=f"Unexpected error: {e}", error_stage="unknown",
|
||||
error_detail=traceback.format_exc(),
|
||||
)
|
||||
finally:
|
||||
if requires_gpu:
|
||||
with _gpu_lock:
|
||||
global _gpu_jobs_queued
|
||||
_gpu_jobs_queued -= 1
|
||||
if _gpu_jobs_queued <= 0:
|
||||
log.info("No more GPU jobs queued — unloading Whisper model")
|
||||
_unload_gpu()
|
||||
|
||||
_executor.submit(_run)
|
||||
|
||||
Reference in New Issue
Block a user