Skip to content

fix: resolve critical deadlocks and infinite loops#117

Open
renich wants to merge 1 commit into
elbywan:masterfrom
renich:fix/core-stability
Open

fix: resolve critical deadlocks and infinite loops#117
renich wants to merge 1 commit into
elbywan:masterfrom
renich:fix/core-stability

Conversation

@renich
Copy link
Copy Markdown

@renich renich commented Apr 28, 2026

Description

This PR addresses several fundamental stability issues that caused the Crystalline server to hang indefinitely or become unresponsive to SIGINT (Ctrl+C). These fixes are critical for the reliability of the server, especially in single-threaded environments or when used with diverse LSP clients.

Key Changes

1. Infinite Loop in Workspace Completion

  • Problem: In Workspace#completion, the lexer loop was comparing token.type (an Enum) to a symbol (:EOF). This comparison always returned false, causing the server to spin indefinitely when lexing comments.
  • Fix: Updated the comparison to use the idiomatic Crystal enum predicate methods (.eof? and .comment?).

2. Deadlock in Single-Threaded Mode (-Dpreview_mt absent)

  • Problem: Analysis.spawn_dedicated enqueued a fiber on the current thread and then immediately blocked the main fiber on a channel. In single-threaded mode, the scheduler never had a chance to switch to the compilation fiber, leading to a permanent deadlock.
  • Fix: Refactored spawn_dedicated to execute the compilation block immediately (synchronously) when multithreading is disabled, ensuring the channel is populated before the main fiber waits.

3. Progress Report Hang

  • Problem: Progress#report assumed all clients would respond to a workDoneProgress/create request. If a client (or a test mock) didn't support progress or didn't send a response, the server would hang waiting for an on_response callback.
  • Fix: Added a capability check for work_done_progress. If unsupported, the report executes the block immediately rather than waiting for a client handshake.

4. Buffered Sync Channel

  • Problem: The compilation synchronization channel was unbuffered, which could lead to blocking during synchronous execution paths.
  • Fix: Introduced a buffer of 1 to the sync_channel to ensure non-blocking completion of the compilation block.

Verification

  • New Spec: Added spec/reproduction_76_spec.cr which empirically reproduces the comment-completion hang and verifies the fix.
  • Cross-Platform: Verified that the test suite passes with 100% success in both Single-Threaded and Multi-Threaded (-Dpreview_mt) modes.
  • Responsiveness: Confirmed that the server now correctly handles SIGINT even during heavy compilation tasks.

Maintainer Note

These stability fixes are prerequisites for running the full test suite reliably. Without them, specific edge cases in comment lexing or single-threaded execution can cause the test runner itself to hang.

Assisted-by: Gemini gemini@google.com

@renich
Copy link
Copy Markdown
Author

renich commented Apr 28, 2026

This PR addresses and fixes issues #76 and #20. (Foundational stability fixes for hangs and infinite loops).

@renich renich force-pushed the fix/core-stability branch from 553b417 to 41571b9 Compare April 28, 2026 00:38
Assisted-by: Gemini <gemini@google.com>
@renich renich force-pushed the fix/core-stability branch from 41571b9 to cb7a460 Compare April 28, 2026 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant