Automatically recover deleted Discord leaderboard messages - #1542
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf364e6dae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| topVoterMessageIds.put(top, 0L); | ||
| plugin.getServerData().setTopVoterMessageId(top, 0L); | ||
| channel.sendMessageEmbeds(eb.build()).queue(msg -> { |
There was a problem hiding this comment.
Serialize replacement creation for stale message IDs
When two leaderboard refreshes have outstanding edits for the same deleted message—for example, a background refresh overlaps the hourly task—both asynchronous failure callbacks unconditionally clear the ID and post a replacement. This creates duplicate leaderboard messages, and whichever send callback finishes last becomes the persisted ID. Atomically mark recovery as in progress, or only clear and replace when the currently stored ID still equals existingId.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61c90c5ea9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| synchronized (recoveringTopVoters) { | ||
| if (recoveringTopVoters.contains(top)) { |
There was a problem hiding this comment.
Read the message ID inside the recovery critical section
When a scheduled or manual refresh races with successful recovery, it can read the temporary 0 ID immediately before this block; the recovery callback can then publish the replacement ID and remove top from recoveringTopVoters, after which the refresh enters this block, sees no recovery, and uses its stale 0 to post a duplicate message. The fresh evidence in this revision is that the message-ID read remains outside the newly added guard and recovery completion also clears the guard separately; read the ID and publish the replacement ID/clear the recovery marker under the same lock.
Useful? React with 👍 / 👎.
What changed
DiscordSRV.TopVoter.AutoRecoverMessageOnFailure, enabled by default.UNKNOWN_MESSAGEresponse when updating a stored top-voter message.Why
A deleted leaderboard message or a channel change can leave VotingPlugin retrying the same invalid message ID indefinitely. This makes the Discord integration recover automatically while preserving the existing manual/configurable behavior.
Validation
git diff --checkpassed.The separate
LoadCommandAliasesissue is intentionally not included: Bukkit registers every command declared inplugin.ymlbefore VotingPlugin code executes and needs a separate dynamic-registration design.