Three issues identified by code review:
1. Per-league queue: replace single global queue with a Map keyed by leagueId
so concurrent drafts in different leagues don't block each other.
2. Deadlock fix: wrap drainer body in try/finally so drainingLeagues is always
cleaned up even if a task throws unexpectedly, preventing the queue from
being permanently stuck.
3. Wait cap fix: move Math.min to wrap the full backoff expression
(retryAfter * (attempt+1)) so the 10s ceiling applies to the product, not
just the base — settings actions were previously blockable for up to 30s.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>