Throttle Manager
Per-actor throttling of the despawn pipeline.
The global io.fairyfox.papermc.despawneditems.config.PerformanceSettings budget answers "how much relocation work may the server do this tick". This answers the different question the owner asked for: "how much of that budget may this player take" — so a single player dumping a double chest of junk cannot consume the whole pipeline while everyone else's items quietly expire.
Three composable strategies, selected by throttle.strategy:
| Strategy | What it bounds | Owner's phrasing |
|---|---|---|
| ThrottleStrategy.RATE | relocations per actor per time window (token bucket) | "max per chunk of time" |
| ThrottleStrategy.CONCURRENT | relocations in flight per actor at once | "max per each one" |
| ThrottleStrategy.FAIR_SHARE | drain order across actors, weighted | "some users get more than others" |
| ThrottleStrategy.COMBINED | all three at once | — |
State is per-actor and lazily created; purgeIdle evicts actors whose budgets are full and who have nothing in flight, so a long-running server does not accumulate a map entry per player who ever dropped an item.
Parameters
read fresh each call so /despi reload takes effect immediately.
injected player lookup — tests pass a stub and need no server.
injected time source in milliseconds — tests drive it deterministically.