Home

dev / openkara

publicthedavidweng/OpenKara· sync paused
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

feat(separation): cancel single-song runs and surface cache hits (#180, #181) (#183)

2 months ago

f6b4e73
Authored
Davy7/25/2026, 2:52:10 AM
#180 — cancel a running single-song separation:
- Thread `cancel: &AtomicBool` into `inference::separate_streaming`, checked at
  the top of each chunk iteration; on cancel it returns
  `SeparationError::Cancelled` without finalizing writers, so no partial stem
  set or cache entry is promoted (aborted runs restart from chunk 0).
- Add a per-song cancel registry (song_hash -> Arc<AtomicBool>) to
  SeparationState; jobs register on start and remove on exit on both paths.
- New `cancel_separation(song_id)` command — a no-op success when the song is
  not currently separating.
- Batch cancel now flags the in-flight song via `batch_current_song` so it
  stops mid-song instead of after the current track.
- Cancelled jobs emit a `separation-cancelled` event and reset the row to idle
  — never `separation-error`, and no error toast.
- UI: an x affordance beside the inline spinner on the running SongListItem
  row and on the single-song global progress bar.

#181 — surface cache hits: `cache_hit` was already populated end-to-end but
never shown. On a `separation-complete` event with cache_hit=true, show a
lightweight "Using cached separation" toast. Downgrade sets cache_hit=false so
the explicit downgrade action does not raise the cue.

i18n: add library.cancelSeparation and library.usingCachedSeparation to en and
zh-CN.

Tests: inference-level cancellation (pre-set flag and mid-run), cancel-registry
unit tests, and frontend tests for the cancel affordance, the cancelled event
reducer, and the cache-hit toast.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Parent037a6e6

26 files changed
  • src-tauri/src/commands/batch_separation.rs+7−0
  • src-tauri/src/commands/error.rs+9−0
  • src-tauri/src/commands/separation.rs+11−3
  • src-tauri/src/lib.rs+1−0
  • src-tauri/src/separator/error.rs+14−0
  • src-tauri/src/separator/inference.rs+16−1
  • src-tauri/src/separator/job.rs+4−1
  • src-tauri/src/services/separation.rs+152
−8
  • src-tauri/src/smoke.rs+1−0
  • src-tauri/src/state/separation.rs+9−0
  • src-tauri/tests/phase3_inference.rs+160−0
  • src-tauri/tests/phase3_job.rs+2−0
  • src-tauri/tests/phase5_flow.rs+1−0
  • src/components/Layout/GlobalProgressBar.test.tsx+38−1
  • src/components/Layout/GlobalProgressBar.tsx+2−0
  • src/components/Library/SongListItem.test.tsx+59−1
  • src/components/Library/SongListItem.tsx+15−1
  • src/hooks/use-playback-runtime.test.tsx+72−7
  • src/hooks/use-playback-runtime.ts+27−2
  • src/lib/tauri/separation.ts+4−0
  • src/lib/tauri/tauri-wrappers.test.ts+8−0
  • src/locales/en.json+3−1
  • src/locales/zh-CN.json+3−1
  • src/runtime/event-reducers.test.ts+9−0
  • src/runtime/event-reducers.ts+19−0
  • src/types/ipc.ts+4−0