Fix TTS streamer hang that freezes crab stop indefinitely#2
Open
TheDiscordian wants to merge 1 commit into
Open
Fix TTS streamer hang that freezes crab stop indefinitely#2TheDiscordian wants to merge 1 commit into
TheDiscordian wants to merge 1 commit into
Conversation
The TTS streamer tails the stream-json debug log and only exits when it
reads a {"type":"result"} event. Two paths left it looping forever, with
the parent crab stop blocked on `wait` for it:
1. If claude crashed, was killed, or got rate-limited mid-stream it may
never emit a result event.
2. A streamer still running from an overlapping request gets its read
cursor stranded past EOF when the next session truncates the shared
log, so it never reaches the result event.
Fixes:
- Append a synthetic {"type":"result"} terminator after the claude call
so the streamer always gets a stop signal (extract-response ignores a
result line with no "result" field, so it's harmless on success).
- Kill any prior streamer before truncating the shared log, so an
overlapping streamer can't be stranded.
- Exit the streamer if its launching crab process dies (ppid changes),
covering the orphaned-parent case under a systemd user subreaper.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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.
Problem
Holding SUPER+A occasionally leaves Beatrice/Crab stuck — the spoken response never comes and the interaction silently dies. Diagnosed from a live hung process: a
crab stopblocked indo_waitfor 5+ minutes on atts-streamerchild whose read cursor was 2407 bytes past EOF of a truncated log.Root cause
lib/tts-streamertails the stream-json debug log and its only non-signal exit is reading a{"type":"result"}event. Two paths make it loop forever, with the parentcrab stopblocked onwait "$_TTS_STREAMER_PID":claudecrashed, was killed, or got rate-limited mid-stream, it may never emit aresultline.DEBUGLOG(: > "$DEBUGLOG"), so it never reaches the result event.This is independent of the recent sliding-window summarization PR — that only touched
common.shconversation handling, not the start/stop or streamer path.Fix
{"type":"result"}terminator after theclaudecall so the streamer always gets a stop signal.extract-responseignores a result line with noresultfield, so it's harmless on the success path.crabprocess dies (ppid changes) — covers the orphaned-parent case, including under a systemd user subreaper where orphans don't reparent to PID 1.Testing
bash -n/py_compileclean.pkill -foverlap pattern kills a prior streamer before truncation. ✅extract-responsereturns the real result. ✅