Conversation
…r-actor-type supervision Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
✅ Deploy Preview for hyprnote canceled.
|
✅ Deploy Preview for hyprnote-storybook canceled.
|
…, move restart counter after successful spawn Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
…y, propagate DegradedError, add Debug to SessionMsg Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
…er in meltdown, fallback stop reason Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
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.
Replace ractor_supervisor with custom SessionActor supervision
Summary
Replaces the
ractor_supervisor::Supervisor(RestForOne strategy) with a customSessionActorthat implementsractor::Actordirectly, enabling per-actor-type supervision. This is the core fix for the bug where recording stops when STT (transcription) fails.Key behavioral change: When
ListenerActordies (STT failure), the session enters "degraded mode" — recording and audio capture continue uninterrupted. Previously, RestForOne would killRecorderActortoo.What changed:
session/mod.rs: ReplacedSupervisor+ChildSpecpattern withSessionActorimplementingActortrait.handle_supervisor_evtroutes events by child type: Listener death → degraded mode; Source/Recorder death → restart with limits (3 in 15s), then meltdown. Graceful shutdown is handled viaSessionMsg::Shutdownwhich stops children in order (Recorder first, with wait for WAV finalization, then Source/Listener) and setsshutting_downflag to suppress supervision restarts during teardown.events.rs:SessionLifecycleEvent::Activenow carries an optionalDegradedErrorto notify the frontend of degraded state.root.rs: UpdatedActiveevent emission to passerror: None.stop_session_implnow sendsSessionMsg::Shutdownto theSessionActorinstead of directly stopping children by name.ActorTerminatedhandler now parsesDegradedErrorfrom the session stop reason and propagates it toemit_session_ended.Cargo.toml: Removedractor-supervisordependency.Updates since last revision
Addressed review findings:
record_restart()to beforeActor::spawn_linked()intry_restart_sourceandtry_restart_recorder. Previously the actor was spawned first, and if the limit was exceeded the new actor was already running but never stored — an orphaned actor leak.tokio::time::sleep(50ms)before eachspawn_linkedin the restart paths. Without this, rapid respawns hit name collisions in ractor's actor registry (the old supervisor had a 500ms backoff).root.rsActorTerminatedhandler now parsesDegradedErrorJSON from the session actor's stop reason and passes it toemit_session_ended, instead of always passingNone.#[derive(Debug)]onSessionMsg: Added missing derive required by ractor'sMessagetrait.Review & Testing Checklist for Human
50ms backoff may be insufficient: The old code used 500ms. Verify 50ms is enough for ractor's registry to deregister actor names, especially under load. If restarts still fail with name collisions, increase the delay.
identify_childuses cell-ID matching: When a child terminates, its cell is cleared from state, then restart is attempted. If the new actor dies quickly and the old cell's termination event arrives late,identify_childwon't match it (returnsNone→ silently ignored). Name-based identification would be more robust but is lower priority.ActorRef<SessionMsg>cast fromActorCell: Instop_session_impl,let session_ref: ActorRef<SessionMsg> = supervisor.clone().into()performs an unchecked type cast. This relies onstate.supervisoralways being theSessionActorcell. Confirm ractor'sinto()behavior — if the cell is somehow not aSessionActor, thecast(Shutdown)would silently fail or panic.Test manually: Start a recording session, then simulate STT failure (e.g., disconnect network, use invalid API key). Verify:
Activeevent witherrorfield populatedNotes
listener_degradedfield inSessionStateis set but never read — it's placeholder state for future use.stop_actor_by_name_and_waitinlifecycle.rsis now unused (compiler warning). Can be removed in a follow-up.cargo check -p tauri-plugin-listenerpasses.Link to Devin run: https://app.devin.ai/sessions/ab6b741af4114e40ba11334c08eaf56f
Requested by: @yujonglee