List chat channels in config order rather than query completion order - #10
Conversation
/listchatchannels built and sent each channel's line from inside that channel's own listeners.thenAccept callback, so a line was sent whenever its own asynchronous query happened to finish. Completion order is not iteration order, so the list arrived shuffled. The per-channel line building moves into a private function, and the command now starts every listeners query up front and awaits them together with CompletableFuture.allOf before sending. The queries still run concurrently; only the send is ordered, and it follows RPKChatChannelService.chatChannels, which is built from the config key order. rpk-chat-bukkit had no test dependencies, so the Kotest and MockK block is copied from rpk-players-bukkit to let the regression test live in the module it covers. Closes #9 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
41feb55 to
81dff39
Compare
|
Self-review rubric (scored against the diff and CI output, not recollection):
Two observations from outside the diff, folded in here rather than posted inline:
This review comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). |
|
Merge note — do-not-auto-merge path check, disclosed rather than skipped. Two entries on the loop's do-not-auto-merge list are matched by this diff:
The regression gate is satisfied empirically rather than by reasoning: the CI revert ladder recorded in the self-review shows the two ordering tests failing without the fix and passing with it. This pull request has been merged under an explicit merge pre-authorization given by the operator for this session, which is what satisfies the hold on the two matched paths. Both matches are stated above so the override is on the record rather than implicit. The branch has deliberately not been deleted. Contributing this fix to This comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). |
Summary
/listchatchannelsbuilt and sent each channel's line from inside that channel's ownlisteners.thenAcceptcallback, so each line was sent whenever its own asynchronous query happened to finish. Completion order is not iteration order, so the list arrived shuffled.chatChannelComponentsfunction, and the command now starts everylistenersquery up front and awaits them together withCompletableFuture.allOfbefore sending. The queries are still fired off concurrently; only the send is ordered.RPKChatChannelService.chatChannels, whichRPKChatChannelServiceImpl.kt:43builds from thechat-channelsconfig section's key order — so the listed order is the config order, as the upstream report asked for.git diff -wconfirms.bukkit/rpk-chat-bukkit/build.gradlehad notestImplementationblock, so the Kotest + MockK dependencies andtest { useJUnitPlatform() }have been copied verbatim frombukkit/rpk-players-bukkit/build.gradleto let the regression test live in the module it covers.Test plan
ListChatChannelsCommandTests— three channels are listed in service order even though their listener futures are completed in reverse order, and nothing is sent before the last future completes.ListChatChannelsCommandTests— each channel is paired with its own listeners when the queries complete out of order (alphaoffers Mute,betaoffers Unmute), guarding the index-based pairing introduced here.ListChatChannelsCommandTests— a service with no chat channels sends no lines, covering the emptyCompletableFuture.allOf()path../gradlew compileKotlinand./gradlew teston JDK 17.Anchor verdict
UNVERIFIED locally, CI-anchored. No JDK 17 is available in the session this branch was prepared in, and Gradle 7.6 cannot run on the JDKs that are, so
./gradlew testwas not run locally. Thebuildworkflow on this pull request's head is the anchor; its result is recorded in the self-review comment. CI's scope is the whole build rather than a narrowed subset, so it does cover both files changed here.Closes #9
Upstream: RP-Kit#650
No other issue was open on this fork's tracker at triage time, so no skip reasons apply this cycle.
This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).