Repository navigation
fix(vn): close translation streams after cancellation - #183
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Cancelling VN/Host speech translation while the synchronous SDK is creating a stream can discard an unread response without closing it. Repeated cancellations consume the cached client's connection slots and can prevent both speech and subtitle translation from completing.
The bridge now owns stream creation, iteration and closure in one async iterator. It shields the current worker result, closes the stream off the audio loop, and transfers cleanup to a completion callback if cancellation happens during create/next. Cleanup waits for an active synchronous read to finish before closing the same stream. Explicit async-generator closure also covers cancellation or failure while feeding a translated piece into the TTS queue.
This is an existing lifecycle defect, independently verified against unmodified upstream
6147acbc36e2b16faa5d8192a873d40a7feb5965on 2026-10-11. It is a follow-up to #181, not a regression introduced by #180 or #181. Client-factory consolidation remains a separate performance task.Change class
Owning layer: VN bridge's synchronous translation-stream lifecycle.
User-visible effect: cancelled speech translation releases its connection so subsequent subtitle and speech requests can continue.
Compatibility or migration impact: none. Provider settings, retry policy, prompts and public contracts are unchanged. Cancellation cannot forcibly interrupt synchronous work already running; cleanup runs when that operation returns or fails.
Evidence
Environment: Windows x64, CPython 3.12.10, OpenAI 2.38.0, HTTPX 0.28.1, HTTPCore 1.0.9. All inputs and credentials are synthetic; the integration test uses only a loopback HTTP server.
httpcore.PoolTimeout/openai.APITimeoutErrorafter cancelling an unread stream in a one-connection pool. Fixed code completes three cancellation/subtitle-request cycles successfully using that pool.python -X utf8 -m pytest -q tests/test_vn_translation_stream_lifecycle.py tests/test_vn_translation_clients.py tests/test_release_tooling.py— 29 passed, including late read failure cleanup, both provider configurations, cold/warm client sharing, incremental delivery and source-release checks.python -m ruff check .,python tools/architecture/generate_views.py --check,python tools/architecture/generate_readme_overview.py --check, andgit diff --check— passed.python -X utf8 tools/run_tests.py --shard-count 3 --shard-index Nfor N = 0, 1, 2, withAMADEUS_E2E_NO_TTS=1,TTS_DEVICE=cpuandWORK_WORKTREE_ISOLATION=0— all 441 suite files completed successfully; 5,539 passed, 23 skipped, all three processes exited 0. Remote CI is still running; this PR remains draft until those checks finish.Final check