Skip to content

Let the window close, answer stray handshake frames, reply where asked - #41

Merged
krotname merged 1 commit into
mainfrom
fix/obvious-bugs
Aug 16, 2026
Merged

Let the window close, answer stray handshake frames, reply where asked#41
krotname merged 1 commit into
mainfrom
fix/obvious-bugs

Conversation

@krotname

Copy link
Copy Markdown
Owner

Summary

  • The GUI client could not exit. requestConnectionSettings blocks on a CountDownLatch until Connect or Cancel completes the request. Closing the window only called controller.disconnect(), so the waiting thread stayed parked and the JVM never terminated. windowClosing now completes the pending request exactly like Cancel, which makes ClientGuiController.run dispose and return.
  • A stray handshake frame killed the connection. Every misplaced client frame gets a soft Unsupported client frame error, except NAME_REQUEST and USER_NAME, which fell through to default -> throw new IOException(...). Both are now handled with the same soft error, and the switch covers the enum.
  • The bot answered in the wrong place. BotChatClient always replied with sendTextMessage, i.e. plain text in the general room: a private command got a public answer, and a command asked inside a room was answered somewhere else. Replies now go back to the room the command came from, or privately to the sender of a private command.
  • ci.yml asked setup-gradle for Gradle 8.10.2 while the build runs ./gradlew (wrapper 9.7), so that distribution was downloaded and never used; codeql.yml already omits the pin.

Not changed (needs a decision)

  • Rooms restored from the history file at startup are created empty and are only reclaimed once a member leaves, so they occupy maxRooms slots permanently. Whether restored rooms should be pre-created at all, or reclaimed lazily, is a product decision.
  • ChatHistoryStore rewrites and fsyncs the whole file per message under a global lock — a durability/throughput trade-off, not an accident.
  • The frame rate limiter still parses and answers rejected frames.

Test plan

  • ./gradlew spotlessApply check — BUILD SUCCESSFUL (spotless, checkstyle, spotbugs, unit/integration/ui tests, -Werror).
  • New tests: BotChatClientTest.answersPrivateCommandsPrivately, answersRoomCommandsInTheSameRoom.

🤖 Generated with Claude Code

- Closing the chat window while the connection dialog is open left the
  thread inside requestConnectionSettings blocked on its latch forever, so
  the JVM never exited. windowClosing now completes the pending request the
  same way Cancel does.
- NAME_REQUEST and USER_NAME were the only frame types left to the default
  branch of the server loop, so a stray handshake frame dropped the
  connection with an IOException while every other misplaced frame got a
  soft "Unsupported client frame" error.
- The bot answered every command with a plain text message to the general
  room: a private question got a public answer, and a question asked in a
  room was answered elsewhere. It now replies in the room it was asked in,
  or privately to the sender of a private command.
- ci.yml pinned gradle-version 8.10.2 for setup-gradle although the build
  runs through the 9.7 wrapper, so that download was dead weight (codeql.yml
  already omits it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@krotname
krotname merged commit 38ab4db into main Aug 16, 2026
11 checks passed
@krotname
krotname deleted the fix/obvious-bugs branch August 16, 2026 09:17
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