zjncs opened a new pull request, #4592:
URL: https://github.com/apache/rocketmq-dashboard/pull/4592

   ### Which Issue(s) This PR Fixes
   
   - Fixes #<issue-id>
   
   ### Brief Description
   
   `scanDeadLetters` abandons a DLQ queue mid-scan in two places without 
incrementing `failedQueueCount`:
   
   1. a pull whose `nextBeginOffset` does not advance (a stall that would 
otherwise loop forever), and
   2. more than `MAX_CONSECUTIVE_OFFSET_ILLEGAL` consecutive `OFFSET_ILLEGAL` 
responses (giving up on the corrected offsets).
   
   Only the exception path and the null pull result counted. Because 
`scanIncomplete()` is `failedQueueCount > 0 || truncated`, a scan where every 
*other* queue succeeded stayed "complete": the resend was classified as 
`SUCCESS` with `scanIncomplete=false, scanFailedQueues=0`, even though part of 
the dead-letter queue was never read. The operator gets a "complete" resend 
whose `matched` count silently excludes the unscanned messages — for dead 
letters that is the worst kind of success, because the unresent messages look 
handled.
   
   This PR adds `failedQueueCount++` before both abandonments, so:
   
   - mixed case (one queue abandoned, others scanned): outcome becomes 
`PARTIAL` with `scanIncomplete=true` and `scanFailedQueues=1`, matching the 
existing semantics of the exception path 
(`resendMessagesMarksAResultPartialWhenOneDlqQueueCannotBeScanned`);
   - all-queues-abandoned case: the scan now fails with the same 502 `Failed to 
scan DLQ topic ...` as the all-queues-threw case, instead of returning an empty 
success.
   
   The DLQ **list** path (`listMessages`) shares `scanDeadLetters` and already 
maps `failedQueueCount` into its VO, so it picks up the corrected 
incompleteness signal for free.
   
   ### How Did You Test This Change?
   
   Two new tests plus one updated test in `RocketMQDLQProviderTest`:
   
   - `resendMessagesMarksAResultPartialWhenOneDlqQueueStalls` (new): two queues 
— one stalls (`nextBeginOffset == requestedOffset`), one yields an in-window 
dead letter that is resent. Expects `matched=1, resent=1, outcome=PARTIAL, 
scanIncomplete=true, failedQueueCount=1` and the `scanFailedQueues=1`/`PARTIAL` 
audit record.
   - `resendMessagesCountsAQueueAbandonedAfterPersistentOffsetIllegal` (new): 
every pull returns `OFFSET_ILLEGAL` with a corrected offset that is itself 
illegal again until the cap is hit. Expects the 502 `Failed to scan DLQ topic` 
(the queue is the only one, so the whole scan fails) and no producer invocation.
   - `resendMessagesStopsWhenPullOffsetDoesNotAdvance` (updated): the single 
stalled queue now fails the whole scan instead of returning an empty success; 
the test's original guarantees (exactly one pull, no producer, bounded time) 
are kept.
   
   Fail-before (fix stashed, tests on master's code): the three tests above 
fail — the two-queue case returns 
`SUCCESS/scanIncomplete=false/failedQueueCount=0`, the give-up case returns 
instead of throwing. Pass-after:
   
   ```
   $ mvn -B -ntp test 
-Dtest='RocketMQDLQProviderTest,DLQServiceTest,DLQControllerTest' 
-Dspotbugs.skip=true
    Tests run: 41 ... in RocketMQDLQProviderTest      (0 failures)
    Tests run: 24 ... in DLQControllerTest            (0 failures)
    Tests run: 17 ... in DLQServiceTest               (0 failures)
    BUILD SUCCESS
   ```
   
   The existing `resendMessagesRetriesFromCorrectedOffsetAfterOffsetIllegal` 
(single illegal, then FOUND → `SUCCESS`) is unchanged and green, confirming the 
retry-from-corrected-offset behaviour is untouched.
   
   ### Checklist
   
   - [x] One coherent change; unrelated modifications are not bundled in
   - [x] Commit subject follows Conventional Commits (`feat:` / `fix:` / 
`refactor:` / `chore:` / `docs:` / `perf:`)
   - [x] Tests added or updated for non-trivial changes, test methods named 
`...Test`
   - [x] New UI text has both Chinese and English entries under `web/src/i18n/` 
(no UI change)
   - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit 
checks)
   - [x] New source files carry the ASF license header (no new files)
   - [x] Documentation touched where behaviour changed (error/signal semantics 
only, no user-facing docs exist for scan internals)


-- 
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]

Reply via email to