Skip to content

Refactor command queue handling to prevent duplicate execution on Folia. Introduced atomic flag to track command check progress and updated comments for clarity.#126

Open
sluhtie wants to merge 1 commit intotebexio:2.3.0-devfrom
sluhtie:2.3.0-dev
Open

Refactor command queue handling to prevent duplicate execution on Folia. Introduced atomic flag to track command check progress and updated comments for clarity.#126
sluhtie wants to merge 1 commit intotebexio:2.3.0-devfrom
sluhtie:2.3.0-dev

Conversation

@sluhtie
Copy link

@sluhtie sluhtie commented Feb 3, 2026

Summary

This PR fixes an issue on Folia where purchase commands could be executed twice when the player is online. The root cause was a redundant call to checkCommandQueue(true) during Folia plugin enable, combined with missing protection against overlapping command-queue checks.

In favour of #125

Changes

1) Folia: remove redundant command queue check on startup

File: folia/src/main/java/io/tebex/plugin/TebexFoliaPlugin.java

  • Removed the platform.checkCommandQueue(true) call at the end of onEnable().
  • The initial queue check is now triggered only from initStore() after getServerInformation() succeeds, matching the existing Bukkit behavior (where the onEnable() call is commented out).
  • Added a code comment explaining why checkCommandQueue should not be invoked from onEnable() on Folia.

Why:
On Folia, onEnable() could initiate a queue check concurrently with the store initialization flow, resulting in duplicate processing and command execution.


2) SDK: guard against concurrent command queue checks

File: sdk/src/main/java/io/tebex/sdk/platform/BasePluginPlatform.java

  • Introduced AtomicBoolean commandCheckInProgress to prevent parallel executions of checkCommandQueue().

  • At the beginning of checkCommandQueue():

    • If a run is already active (compareAndSet(false, true) fails), the check is skipped.
    • If appropriate, the next check is still scheduled in 60 seconds.
  • In the whenComplete callback of getDuePlayers():

    • Wrapped the entire callback logic in a try/finally.
    • In finally, commandCheckInProgress.set(false) ensures the next run is allowed.

Why:
Even with the Folia startup fix, overlapping checks can still occur (e.g., scheduler timings, network delays, async completions). This guard ensures command processing remains idempotent with respect to scheduling and avoids double execution due to concurrency.

Result

  • Commands are no longer executed twice on Folia when the player is online.
  • checkCommandQueue() is protected from overlapping runs across all platforms.

Testing

  • Verified on Folia 1.21.11 that:

    • Purchases made while the player is online execute commands once.
    • Purchases made while the player is offline execute commands once.
  • Verified both purchase flows:

    1. Tebex store purchase
    2. Manual payment creation

…ia. Introduced atomic flag to track command check progress and updated comments for clarity.
@sluhtie sluhtie marked this pull request as draft February 3, 2026 23:42
@sluhtie sluhtie marked this pull request as ready for review February 3, 2026 23:42
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.

2 participants