regenerate something when the sentences changed
This commit is contained in:
@@ -20,6 +20,7 @@ class _Job:
|
||||
done: threading.Event
|
||||
lock: threading.Lock
|
||||
running: bool = True
|
||||
cancelled: bool = False
|
||||
error: str | None = None
|
||||
thread: threading.Thread | None = None
|
||||
|
||||
@@ -89,6 +90,26 @@ class SubtitleTranslationService:
|
||||
return None
|
||||
return self.snapshot(document)
|
||||
|
||||
def invalidate(self, video_hash: str) -> None:
|
||||
"""Stop an in-flight job so stale translations cannot be written back."""
|
||||
with self._lock:
|
||||
job = self._jobs.pop(video_hash, None)
|
||||
if job is None:
|
||||
return
|
||||
with job.lock:
|
||||
job.cancelled = True
|
||||
|
||||
def refresh(self, video_hash: str) -> None:
|
||||
"""Drop saved Chinese subtitles and translate the current sentences again."""
|
||||
self.invalidate(video_hash)
|
||||
self.repository.clear_sentence_translations(video_hash)
|
||||
if not getattr(self.ai_tutor, "available", False):
|
||||
return
|
||||
try:
|
||||
self._start_if_needed(video_hash)
|
||||
except (KeyError, ValueError, AITutorError):
|
||||
logger.exception("Could not restart subtitle translation: video=%s", video_hash)
|
||||
|
||||
def ensure(self, video_hash: str) -> SubtitleTranslationResponse:
|
||||
if not getattr(self.ai_tutor, "available", False):
|
||||
raise AITutorError("AI translation is not configured.")
|
||||
@@ -119,8 +140,15 @@ class SubtitleTranslationService:
|
||||
existing = self._jobs.get(video_hash)
|
||||
if existing is not None:
|
||||
with existing.lock:
|
||||
still_running = existing.running or (
|
||||
existing.thread is not None and existing.thread.is_alive()
|
||||
still_running = (
|
||||
not existing.cancelled
|
||||
and (
|
||||
existing.running
|
||||
or (
|
||||
existing.thread is not None
|
||||
and existing.thread.is_alive()
|
||||
)
|
||||
)
|
||||
)
|
||||
if still_running:
|
||||
return existing
|
||||
@@ -140,8 +168,17 @@ class SubtitleTranslationService:
|
||||
thread.start()
|
||||
return job
|
||||
|
||||
def _persist(self, job: _Job, translations: dict[int, str]) -> None:
|
||||
with job.lock:
|
||||
if job.cancelled:
|
||||
return
|
||||
self.repository.save_sentence_translations(job.video_hash, translations)
|
||||
|
||||
def _run_job(self, job: _Job) -> None:
|
||||
try:
|
||||
with job.lock:
|
||||
if job.cancelled:
|
||||
return
|
||||
document = self.repository.get_document(job.video_hash)
|
||||
if document is None:
|
||||
raise AITutorError("Course is not available.")
|
||||
@@ -162,16 +199,18 @@ class SubtitleTranslationService:
|
||||
payload,
|
||||
course_title=(video["title"] if video is not None else "") or "",
|
||||
existing=existing,
|
||||
persist=lambda part: self.repository.save_sentence_translations(
|
||||
job.video_hash,
|
||||
part,
|
||||
),
|
||||
persist=lambda part: self._persist(job, part),
|
||||
)
|
||||
if translated:
|
||||
self.repository.save_sentence_translations(job.video_hash, translated)
|
||||
self._persist(job, translated)
|
||||
with job.lock:
|
||||
job.error = None
|
||||
if not job.cancelled:
|
||||
job.error = None
|
||||
except Exception as exc: # noqa: BLE001 - surface job failure to clients
|
||||
with job.lock:
|
||||
cancelled = job.cancelled
|
||||
if cancelled:
|
||||
return
|
||||
logger.exception("Subtitle translation job failed: video=%s", job.video_hash)
|
||||
with job.lock:
|
||||
job.error = str(exc)
|
||||
|
||||
Reference in New Issue
Block a user