Skip to content

fix: only decrease the notification red dot cache once per notification - #1644

Merged
LinkinStars merged 1 commit into
apache:devfrom
lhk0504:fix/notification-read-idempotent
Oct 15, 2026
Merged

LinkinStars merged 1 commit into
apache:devfrom
lhk0504:fix/notification-read-idempotent

Conversation

@lhk0504

@lhk0504 lhk0504 commented Oct 15, 2026

Copy link
Copy Markdown

Fixes #1643

As suggested in the issue, marking a notification as read is now conditional and atomic, and the red dot cache is only decreased when the notification really changed from unread to read.

Proposed Changes

  • ClearIDUnRead in the notification repository adds an is_read = unread predicate to the update and returns the number of changed rows, which xorm already provided but was discarded.
  • NotificationService.ClearIDUnRead only calls DecreaseRedDot when exactly one row was changed, so duplicate sequential requests and concurrent duplicate requests for the same notification cannot decrease the cached counter more than once. The badge award alert cache cleanup stays independent, since it is already idempotent.
  • Tests: the repository test asserts one changed row for the first request and zero for a duplicate request and for a request from another user, plus a concurrent duplicate request test; a service test asserts that the cached red dot counter decreases exactly once.

ClearUnRead (mark all as read) is intentionally not touched: as noted in the issue, the red dot cache is not designed as an exact mirror of the unread rows, so the fix is scoped to making the single-notification read endpoint idempotent.

Marking a notification as read is a no-op in the database when it is already
read, but ClearIDUnRead decreased the cached red dot count unconditionally.
Duplicate sequential requests therefore decreased the counter twice: the
first request changed the notification from unread to read, while the second
skipped the meaningful database transition but still decreased the cache.
Two concurrent requests could do the same, because the update had no
"is_read = unread" predicate and the changed row count was discarded.

Make the update conditional and atomic (WHERE user_id = ? AND id = ?
AND is_read = unread) and only decrease the cache counter when exactly one
row was changed. The badge award alert cache cleanup stays independent,
since it is already idempotent.

Close apache#1643
Copilot AI balanced review requested due to automatic review settings October 15, 2026 03:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@LinkinStars
LinkinStars self-requested a review October 15, 2026 03:44
@LinkinStars LinkinStars self-assigned this Oct 15, 2026
@LinkinStars LinkinStars added this to the v2.0.4 milestone Oct 15, 2026

@LinkinStars LinkinStars left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LinkinStars
LinkinStars merged commit 3dc1df1 into apache:dev Oct 15, 2026
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.

3 participants