fix: a background job's exit notification crashed the fiber - #52
Merged
Conversation
Starting any background command took down the fiber that reports its
exit with an OverflowError:
Unhandled exception in spawn: Arithmetic overflow (OverflowError)
from time/span.cr:272:21 in '+'
from channel/select/timeout_action.cr:39:7 in 'wait'
`job.wait(Time::Span::MAX)` reads like "wait indefinitely", but the
event loop arms a timer at `now + span`, and that overflows. A deadline
that cannot be represented is not a deadline, so the no-argument `wait`
arms no timer at all.
A second fault at the same spot: `@done` carried a single value, and a
single value releases a single waiter. The tool call waiting out its
timeout and the on_exit fiber are both waiting, so one of them was left
hanging whichever way the race fell. Closing the channel broadcasts.
Both are covered: on_exit has to fire, and it has to fire even after
another fiber already waited on the same job.
Co-Authored-By: Claude Opus 5 <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.
Fällt beim Testen von #29 auf, ist aber unabhängig davon — der Fehler steckt seit
61780c7(background bash jobs) aufmain.Jedes gestartete Background-Kommando riss den Fiber ab, der seinen Exit meldet:
Ursache
bash_jobs.cr:159wartete mitjob.wait(Time::Span::MAX). Das liest sich wie „unbegrenzt warten", ist es aber nicht: der Event-Loop legt den Timer aufnow + span, und das läuft über. Isoliert reproduzierbar:Eine Frist, die sich nicht darstellen lässt, ist keine Frist — das parameterlose
waitlegt deshalb gar keinen Timer an.Zweiter Fehler an derselben Stelle
@donetrug einen einzelnen Wert, und ein einzelner Wert weckt einen einzelnen Wartenden. Es warten aber regelmäßig zwei: der Tool-Call, der sein Timeout aussitzt, und der Fiber, deron_exitfeuert. Je nachdem, wie das Rennen ausging, blieb einer von beiden hängen. Das Schließen des Channels weckt alle.Aufgefallen ist das bisher nicht, weil der Overflow ohnehin zuerst zuschlug.
Tests
Drei neue Beispiele in
bash_jobs_spec.cr:on_exitmuss feuern; es muss auch dann feuern, wenn schon ein anderer Fiber auf denselben Job gewartet hat; und ein fristloseswaitauf einen bereits beendeten Job muss zurückkehren statt zu blockieren.Gegen den ungefixten Stand läuft die Suite nicht mehr durch (sie hängt), mit dem Fix in 2 s.
crystal spec: 555 Beispiele, 0 Fehler. Format sauber.🤖 Generated with Claude Code