123123213weqw opened a new pull request, #5761: URL: https://github.com/apache/rocketmq-dashboard/pull/5761
## What\n\n`AiRunService.stop` reads the run row once at the top. When the registry then reports the run unowned, it writes the terminal state (`STOPPED/USER_STOP`) through `runExecutor.terminate` — the branch meant for a row the orphan sweep would otherwise have to reap.\n\n## Why it is a bug\n\nThe registry lookup coming back empty cannot distinguish an orphaned row from a worker that finalised **between the top-of-method read and the lookup**: finalisation unregisters the run right after writing its terminal state. On that stale read the stop then\n\n- writes a **second** `run_status` event into the timeline (two terminal rows for one run), and\n- overwrites the row to `STOPPED` for a run that had just completed — the user pressed stop a moment too late and watched the answer finish, yet the transcript says stopped.\n\nSame corruption class as the executor-side race (`decide()` vs a late abort), reached through the service's stop path.\n\n## The fix\n\nRe-read the row insid e the unowned branch before writing anything: an already-terminal row makes the stop the documented 200 no-op; only a genuinely active, unowned row gets the direct terminal write. The final `findById` re-read also now returns the freshest row.\n\n## Test\n\nRed-first: `AiRunServiceTest.aStopThatLosesTheFinalisationRaceMustNotWriteASecondTerminalTest` stubs `findById` to return RUNNING first (the admission read) and COMPLETED after (the re-read), with an empty registry. Asserts the stop returns COMPLETED with no row update and no persisted event — previously a `STOPPED/USER_STOP` row was written over it. The class (23 tests) stays green. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
