Skip to content

Automatically recover deleted Discord leaderboard messages - #1542

Merged
BenCodez merged 7 commits into
masterfrom
agent/discord-message-recovery
Aug 8, 2026
Merged

Automatically recover deleted Discord leaderboard messages#1542
BenCodez merged 7 commits into
masterfrom
agent/discord-message-recovery

Conversation

@BenCodez

@BenCodez BenCodez commented Aug 8, 2026

Copy link
Copy Markdown
Owner

What changed

  • Add DiscordSRV.TopVoter.AutoRecoverMessageOnFailure, enabled by default.
  • Detect Discord's UNKNOWN_MESSAGE response when updating a stored top-voter message.
  • Clear the stale in-memory and persisted message IDs.
  • Automatically post and persist a replacement leaderboard 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 --check passed.
  • Maven compile could not run because Maven is not installed in the execution environment.

The separate LoadCommandAliases issue is intentionally not included: Bukkit registers every command declared in plugin.yml before VotingPlugin code executes and needs a separate dynamic-registration design.

@BenCodez
BenCodez marked this pull request as ready for review August 8, 2026 22:49

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 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".

Comment on lines +224 to +226
topVoterMessageIds.put(top, 0L);
plugin.getServerData().setTopVoterMessageId(top, 0L);
channel.sendMessageEmbeds(eb.build()).queue(msg -> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 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".

Comment on lines +197 to +198
synchronized (recoveringTopVoters) {
if (recoveringTopVoters.contains(top)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@BenCodez
BenCodez merged commit 803e9e2 into master Aug 8, 2026
4 checks passed
@BenCodez
BenCodez deleted the agent/discord-message-recovery branch August 8, 2026 23:18
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.

1 participant