Make the audio file tab remember, and its Stop stop

The two switches were written to disk by the Save button at the far end of
the window, so a file transcribed with timestamps and cleanup was
transcribed without either the next time. They belong to the run rather than
to the form: they go to disk as they are ticked now, and the folder the last
file came from goes with them.

Stop only set a flag that was looked at between chunks, and a file under ten
minutes is one chunk, so for most files it was looked at after the work it
was meant to stop had already finished. Nothing that blocks is reached by a
flag. The request is inside urlopen, ffmpeg is inside communicate, and a
whisper on this machine is a process of ours that would grind on to the end
of the chunk with nobody left to hand the answer to. So the socket is shut
down under the read, ffmpeg is killed, and a local server is stopped and
left for the next run to start again.

Shutting the socket down rather than closing it is the point: close() alone
leaves a thread already inside recv() waiting for bytes that are never
coming now. The connection is registered before it has a socket, so a stop
landing in the few lines between making a connection and blocking on it
refuses the connection rather than missing it and letting urllib quietly
open another.
This commit is contained in:
yusufipk
2026-08-02 09:29:12 +03:00
parent fc333fcb8c
commit 7a507c52eb
7 changed files with 438 additions and 33 deletions
+36 -1
View File
@@ -7,6 +7,7 @@ made up a stamp nobody recorded.
"""
import contextlib
import time
import unittest
import wave
from unittest import mock
@@ -170,7 +171,7 @@ class Transcriber(DikteTest):
worker.failed.connect(failures.append)
worker.progress.connect(progress.append)
def to_wav(path, workdir):
def to_wav(path, workdir, aborter=None):
return make_wav(self.path("converted.wav"), tone(1.0))
with mock.patch.object(ft, "_to_wav", side_effect=to_wav), \
@@ -225,6 +226,40 @@ class Transcriber(DikteTest):
_, _, _, cleanup_call = self.run_chain(cleanup=True, transcript="")
cleanup_call.assert_not_called()
def test_a_stopped_run_is_not_a_failure(self):
def stopped(*args, **kwargs):
raise api.Aborted
done, failures, progress, _ = self.run_chain(fail=stopped)
self.assertEqual(failures, [])
self.assertEqual(done, [])
self.assertEqual(progress[-1], "Stopped.")
def test_the_request_is_handed_the_stop_to_watch(self):
worker = ft.FileTranscriber(self.conf)
with mock.patch.object(ft, "_to_wav", side_effect=lambda *a: self.source), \
mock.patch.object(ft.shutil, "which", return_value="/usr/bin/ffmpeg"), \
mock.patch.object(api, "transcribe", return_value="text") as call:
worker._work(self.source, False, False)
self.assertIs(call.call_args.kwargs["aborter"], worker._abort)
def test_stopping_a_local_run_stops_the_model_with_it(self):
"""Closing the socket is nothing to a process of ours: it would grind on
to the end of the chunk with nobody left to hand the answer to."""
worker = ft.FileTranscriber(self.conf)
worker._local = mock.Mock()
worker.stop()
self.assertTrue(worker._abort.aborted)
for _ in range(100):
if worker._local.stop.called:
break
time.sleep(0.01)
worker._local.stop.assert_called_once_with()
def test_a_run_that_is_over_leaves_the_model_alone(self):
worker = ft.FileTranscriber(self.conf)
worker.stop()
self.assertTrue(worker._abort.aborted)
def test_a_second_start_while_one_is_running_is_ignored(self):
worker = ft.FileTranscriber(self.conf)
worker._thread = mock.Mock(is_alive=lambda: True)