mirror of
https://github.com/debpalash/VoiceStudio.git
synced 2026-10-02 01:26:35 +08:00
fix(media): update fallback process exit status after wait (#2473)
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
This commit is contained in:
@@ -86,6 +86,8 @@ metadata and the backend fallback mirror it.
|
||||
- The Twilio guide and integration directory describe the guided setup and in-app integration pages (#2304)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Media subprocess fallback reports the completed exit status after waiting (#2473) — thanks @rudycelekli!
|
||||
- Dub assembly, cached segments and audio tools can read generated WAV files when TorchCodec is missing or cannot load (#2379) — thanks @tokutei58301-boop!
|
||||
- Remote API-key and share-PIN clients can record and read export history while native filesystem operations stay local (#2383, #2384) — thanks @sedatdagg!
|
||||
- Concurrent job events receive unique sequence numbers (#2384) — thanks @sedatdagg!
|
||||
|
||||
@@ -432,7 +432,9 @@ async def _spawn_thread_fallback(cmd, **kwargs):
|
||||
return out, err
|
||||
|
||||
async def wait(self):
|
||||
return await loop.run_in_executor(None, self._popen.wait)
|
||||
code = await loop.run_in_executor(None, self._popen.wait)
|
||||
self.returncode = code
|
||||
return code
|
||||
|
||||
def kill(self):
|
||||
self._popen.kill()
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Update fallback process exit status after wait
|
||||
|
||||
The Windows-compatible subprocess wrapper exposes the completed child exit code after `wait()`, matching its public asyncio process contract.
|
||||
|
||||
## Contract
|
||||
|
||||
Store the completed Popen wait result in the wrapper returncode before returning it.
|
||||
|
||||
The unsupported transport condition is reproduced with a selector loop on macOS; native Windows execution and the full application smoke matrix await hosted CI. No ffmpeg binary or model was needed for the process protocol regression.
|
||||
|
||||
## Regression coverage
|
||||
|
||||
The public helper regression is in `tests/test_voice_fallback_exit.py`.
|
||||
Run it with `python -m pytest -q tests/test_voice_fallback_exit.py` from the repository root.
|
||||
It uses local text, files or child processes; no model generation is required.
|
||||
@@ -0,0 +1,31 @@
|
||||
"""Real children on the unsupported-subprocess loop retain asyncio exit status."""
|
||||
import asyncio
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
class UnsupportedSubprocessLoop(asyncio.SelectorEventLoop):
|
||||
async def _make_subprocess_transport(self, *args, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
@pytest.mark.parametrize("code", [0, 23])
|
||||
def test_public_spawn_wait_updates_returncode_on_fallback(code):
|
||||
from services.ffmpeg_utils import spawn_subprocess
|
||||
async def run():
|
||||
proc = await spawn_subprocess(sys.executable, "-c", f"raise SystemExit({code})")
|
||||
assert proc.uses_sync_pipes
|
||||
assert await asyncio.wait_for(proc.wait(), 5) == code
|
||||
assert proc.returncode == code
|
||||
assert await proc.wait() == code
|
||||
with asyncio.Runner(loop_factory=UnsupportedSubprocessLoop) as runner:
|
||||
runner.run(run())
|
||||
|
||||
def test_fallback_communicate_keeps_exit_code_and_real_output():
|
||||
from services.ffmpeg_utils import spawn_subprocess
|
||||
async def run():
|
||||
proc = await spawn_subprocess(sys.executable, "-c", "import sys; sys.stdout.buffer.write(b'media child\\n'); raise SystemExit(7)", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||
out, err = await asyncio.wait_for(proc.communicate(), 5)
|
||||
assert out == b"media child\n"
|
||||
assert err == b""
|
||||
assert proc.returncode == 7
|
||||
with asyncio.Runner(loop_factory=UnsupportedSubprocessLoop) as runner:
|
||||
runner.run(run())
|
||||
Reference in New Issue
Block a user