Annotation Interface UsageLimit


@Target({METHOD,TYPE}) @Retention(RUNTIME) public @interface UsageLimit
Marks a @CmdMapping method as subject to a concurrency lock, enforced by UsageLockValidator.

UsageLimit.LimitType.SENDER serialises invocations per sender: while one invocation from a given sender is in flight, a second invocation of the SAME mapping from the SAME sender is rejected; a different sender is unaffected. UsageLimit.LimitType.ALL serialises invocations server-wide: while any one invocation is in flight, every OTHER sender's invocation of the same mapping is rejected, regardless of who is invoking it.

Acquisition is the gate (GEN-09 / D-02, acquire-as-you-validate): the lock is taken inside validation itself, so a failed acquisition is an ordinary validation rejection -- the mapped method is never invoked. An ALL-scope lock is released only by the sender that acquired it; no other sender's completion can free it (Pitfall 5 / T-05-03).

ContainConsole() defaults to true as of 6.3.0 -- a console sender is subject to this limit unless a mapping opts out explicitly.

Re-entry (as of 6.3.0). A command body runs at dispatch on the server thread, so a body that dispatches its own command -- performCommand or Bukkit.dispatchCommand -- runs the nested dispatch while its own lock is still held. The nested dispatch is refused with the ordinary lock message (SENDER: from the same sender; ALL: from any sender); acquisition never waits, so nothing blocks and nothing deadlocks. The outer body's lock is released when the outer body returns, normally or by throwing. A body that must run its own command again should schedule it with runTask instead.

A mapping -- or the executor class itself -- carrying this annotation with UsageLimit.LimitType.SENDER or UsageLimit.LimitType.ALL whose chain omits UsageLockValidator is refused at plugin load, naming the offending class and, when known, the offending mapping method (SILENT-11 / D-01, D-04); UsageLimit.LimitType.NONE is exempt since it declares no limit to enforce. No opt-out exists for this refusal: Phase 3 D-08's module-granularity isolation is the accepted escape hatch -- the offending module alone fails to load, every other module still starts.

As of 6.3.0 this annotation may also be applied at the class level, and it is enforced there: UsageLockValidator resolves the annotation per @CmdMapping method as the method's own annotation, then the concrete executor class's, then the class that declared the mapping in source -- also when the executor is an AOP proxy. A class-level placement therefore locks every mapping of that class that carries no @UsageLimit of its own; a method-level annotation governs its own mapping instead.

See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static enum 
     
  • Required Element Summary

    Required Elements
    Modifier and Type
    Required Element
    Description
     
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    boolean
    Whether a console sender is subject to this limit, the same as a player sender.
  • Element Details

    • value

      Returns:
      the concurrency scope this limit enforces -- see UsageLimit.LimitType
    • ContainConsole

      boolean ContainConsole
      Whether a console sender is subject to this limit, the same as a player sender. Defaults to true as of 6.3.0 -- a console sender is included unless a mapping opts out explicitly.
      Returns:
      whether to contain console
      Default:
      true