fix(scan): prevent scan tasks from being lost after transaction commit - #752
fix(scan): prevent scan tasks from being lost after transaction commit#752bbdu3 wants to merge 4 commits into
Conversation
|
bbdu3 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
Reviewed against #749. The transactional-outbox approach is the right fix: writing
None of these block the core fix for the strand-in-SCANNING bug; (1) is the one I'd most want addressed since it's part of the issue's stated expected behavior. |
Signed-off-by: bbdu3 <bbdu3@iflytek.com>
Signed-off-by: bbdu3 <bbdu3@iflytek.com>
Signed-off-by: bbdu3 <bbdu3@iflytek.com>
Signed-off-by: bbdu3 <ergouyang854@gmail.com>
|
Thanks for the detailed review. I’ve addressed all five points:
Verification:
|
FenjuFu
left a comment
There was a problem hiding this comment.
The five requested changes are present, but the new taskId lock introduces a message-loss race with the existing pending-message reclaimer.\n\nIn ScanTaskConsumer.processBusiness, a failed processingLock.tryLock() calls skipCleanup() and returns normally. AbstractStreamConsumer.handleMessageInScope treats every normal return as success: it calls markCompleted(payload) and then �cknowledge(messageId).\n\nThat is unsafe for the exact duplicate-delivery scenario this lock targets:\n\n1. Consumer A is still scanning after the default 2-minute reclaim idle threshold and holds the taskId lock.\n2. Redis auto-claims the same pending entry to consumer B.\n3. B cannot acquire the lock, returns normally, and XACKs the shared stream entry.\n4. If A crashes or is killed after B's acknowledgement, there is no pending entry left to reclaim and no retry message. The version can remain in SCANNING, recreating the strand this PR is meant to eliminate.\n\nskipCleanup protects the temp path but does not protect delivery state. Please make lock contention preserve eventual processing—for example, wait for the watchdog lock and re-check isTaskAlreadyProcessed after acquisition, or add an explicit consumer outcome that leaves a contended message pending without acknowledging it. Add a test that drives the auto-claim/lock-contention path and proves the entry is not acknowledged before the active scan reaches a terminal result.\n\nI independently inspected the max-attempt terminal transition, SKIP LOCKED query, soft-delete cleanup, and metadata migration; those address the earlier points. Remote CI/DCO/CLA are green. My local targeted Maven run was blocked only because the available JDK does not support the project's Java 21 --release flag.
|
Thanks for addressing all five review points. I rechecked the latest head (1556665) against #749:
DCO, CLA, unit tests, RISC-V builds, and the real-services E2E check are all green. The implementation now satisfies the issue's expected recovery and explicit-failure behavior. I am leaving this as a comment only, not an approval. |
Summary
This closes #749 .Fix the issue where scan tasks can be lost after the database transaction commits but before they are written to the Redis Stream.
Changes
scan_task_outboxtable, domain model, and repository implementation.taskId-based consumer idempotency checks to prevent duplicate scans.SkillVersionis deleted.Verification
SecurityScanServiceTest: 10 passedScanTaskOutboxTest: 2 passedSecurityScanOutboxTest: 1 passedskillhub-infracompilation passedgit diff --checkpassed