promotional bannermobile promotional banner

AceCommQueue

An addon library that adds queuing to the AceComm framework

AceCommQueue-1.0 - Transparent Send-Queue for AceComm-3.0

Are your addon's large AceComm messages arriving garbled with CRC errors? Does your guild communication addon silently drop or corrupt multi-chunk messages under load? AceCommQueue-1.0 is the solution.

AceCommQueue-1.0 is a lightweight, transparent queuing library that sits between your addon and AceComm-3.0, ensuring that only one message per channel is ever in-flight through ChatThrottleLib at a time — eliminating the chunk-interleaving bug that causes CRC failures on receivers.

The Problem

AceComm-3.0 splits large messages into FIRST/NEXT/LAST chunks and hands them all to ChatThrottleLib (CTL) at once. CTL maintains separate priority rings — ALERT, NORMAL, BULK — and drains ALERT before NORMAL before BULK.

If a second message is submitted on the same prefix immediately after a large first message, and the two use different CTL priorities, CTL can drain the second message's chunks ahead of remaining chunks from the first message. The receiver's AceComm spool is keyed on prefix + sender. When a new FIRST frame arrives mid-stream, the partial spool is overwritten — the assembled payload is garbage and the CRC check fails.

BULK  message: FIRST ─── NEXT ─── NEXT ─── LAST
NORMAL message:            FIRST ─ LAST
                                ↑
                      receiver spool corrupted here

This bug is silent. No error is printed. The message simply never arrives. It hits any addon that sends multiple large messages in rapid succession using different CTL priorities.

The Solution

AceCommQueue-1.0 maintains an app-level queue per (prefix, distribution, target). Only one message is ever active in CTL at a time for that combination. The next queued message is not submitted until CTL's callback confirms the previous message's final chunk was handed off.

Between messages, higher-priority items drain first (ALERT > NORMAL > BULK), so an urgent message pushed onto the queue still goes out before pending lower-priority traffic — matching CTL's own intent.

Core Features

Fully Transparent Integration

  • Zero Call-Site Changes: Embed once in OnInitialize — all existing self:SendCommMessage(...) calls are automatically queued
  • Wrapper-Safe: Captures whatever SendCommMessage is present at embed time — compatible with your existing wrappers
  • LibStub-Versioned: Standard LibStub upgrade semantics — multiple addons can embed the library without conflicts
  • Queue State Preserved: Internal queues survive LibStub upgrades across repeated /reload cycles

Priority-Aware Draining

  • ALERT drains before NORMAL before BULK — mirrors CTL's own priority ordering
  • Urgent messages (ALERT) are never held behind lower-priority backlog
  • Per-channel queues: separate queues per (prefix, distribution, target) so unrelated channels never block each other

Suppression Compatible

  • Works with send-suppression wrappers (e.g. in-raid guards) — suppressing wrappers just call the callback with (arg, 0, 0, nil) to unblock the queue cleanly
  • Never stalls: the 0 >= 0 condition satisfies last-chunk detection regardless of real send

Predictable Callbacks

  • Every message you hand to the queue ends in exactly one callback — whether it was sent, suppressed by one of your wrappers, rejected for a bad argument, or failed outright
  • So a send chained on the previous message's callback can never be stranded by one bad message
  • A send that raises is still reported to the error handler, exactly as it would be without the queue in the way — the queue keeps running, but nothing is swallowed

Debug & Diagnostics

  • Optional runtime debug output via AceCommQueue:SetDebug(true)
  • Optional slash command registration: ACQ:RegisterSlashCommand("/acq") — pick any command name you like
  • Slash command lets you toggle debug output and inspect live queue state without a reload

How It Works

Integration (Three Steps)

  1. Load the library in your .toc before your own files:
    Libs\LibStub\LibStub.lua
    Libs\AceCommQueue-1.0\AceCommQueue-1.0.lua
  2. Embed after AceComm in OnInitialize:
    AceComm must be embedded first, then any custom wrappers, then AceCommQueue last so it wraps the complete chain.
  3. Done. Use self:SendCommMessage(...) as normal — queueing is fully transparent.

Suppression Wrappers

If your addon has a wrapper that sometimes suppresses sends (e.g. an in-raid guard), install it before calling ACQ:Embed(self), and have it call callbackFn(callbackArg, 0, 0, nil) when suppressing. This satisfies last-chunk detection and unblocks the queue so it never stalls permanently.

Why Use AceCommQueue-1.0?

Correctness

  • Eliminates the silent CRC-corruption bug that affects any addon sending large multi-chunk messages in rapid succession
  • No lost messages, no garbage payloads, no confusing intermittent failures under guild channel load
  • Backlogs of any size drain safely — a burst of tens of thousands of queued messages is delivered in full, in order
  • Verified by an offline test suite that runs the real Ace3 and ChatThrottleLib code and reproduces the corruption end to end, so the fix is demonstrated rather than asserted

Zero Overhead

  • Single Lua file, no external dependencies beyond LibStub and AceComm-3.0
  • No polling, no frame update hooks — purely callback-driven
  • Queue drain happens in the same CTL callback that already fires per chunk

Drop-In

  • No refactoring of call sites required
  • Compatible with every current WoW client — Classic Era, Anniversary realms, Burning Crusade, Wrath, Cataclysm, Mists, and Retail
  • Ships as a standalone addon or embedded in your own Libs folder

Slash Commands

Register with LibStub("AceCommQueue-1.0"):RegisterSlashCommand("/acq"). Available commands:

  • /acq on — Enable debug output
  • /acq off — Disable debug output
  • /acq status — Print current queue state for all active channels
  • /acq unstick — Get a blocked channel moving again immediately, without waiting for the automatic recovery. Anything that was stuck is re-sent. Channels the game is still working through are left alone
  • /acq — Toggle debug output

Requirements

  • LibStub
  • AceComm-3.0 (part of Ace3)

Recent Updates

v1.0.6 (Latest Release)

  • Fixed: a perfectly healthy message could be reported as a fault in your addon. When the game rate-limits a whisper, it keeps retrying that message several times a second and says nothing at all while it does — which looked exactly like a message that had been lost. The library reported it as a bug in the sending addon and named a cause it had no way to check, sending authors to search codebases that were not at fault. It now asks the game's own send queue first, and stays quiet for as long as the message is genuinely still on its way. Whisper rate-limiting on a busy realm triggered the old check routinely
  • Fixed: that same check assumed every addon sends messages the same way. It looked for the message in one specific place — the place the most common comms library happens to file it. An addon that organises its outgoing messages differently would have had a perfectly healthy message reported as lost and then sent a second time. The check now looks everywhere the message could be and identifies it by its own destination details, so it no longer depends on how the sending addon is built. This library is published for anyone to use, so that assumption was not safe to ship
  • A blocked channel now recovers itself instead of staying blocked. Previously a channel whose message never reported back was stuck for the rest of the session, with everything behind it waiting forever. Now, once the library has confirmed the message really is gone, it clears the channel and re-sends the message — keeping its place at the front of the queue — so a lost notification costs a delay rather than a message
  • Added /acq unstick and a matching Unstick call, for getting a channel moving right now instead of waiting out the timer. It applies the same safety check, so it will never cut in front of a message the game is still sending
  • The wait before a channel is considered blocked is now five minutes rather than one. Reporting late costs nothing; reporting wrongly costs someone an afternoon
  • Repeat problems on the same channel are now counted rather than repeated. The first one is reported normally; the running total appears in /acq status, so a persistent fault stays visible without burying the chat frame
  • Your send callback can now report a further outcome — the message's fate is unknown and its retries are used up — so an addon tracking delivery can tell it apart from one it deliberately chose not to send

v1.0.5

  • Fixed: a message could be reported to your addon as delivered when the client had actually refused part of it. If one piece of a large multi-part message was rejected, the remaining pieces still went out and your addon was told the send succeeded — while the receiving end reassembled a corrupted payload. The delivery result now covers the whole message, so a refused piece means you are told it failed
  • Added automatic retry: a send the client refuses is retried three times with an increasing delay before being reported as failed. The channel keeps its place in the queue while it waits, so message order is never disturbed by a retry. Tune or disable it with SetRetryPolicy
  • A refused message sent without a callback is now reported through the standard error handler, so it can no longer disappear without a trace
  • Your send callback now receives a fifth value naming the outcome — delivered, refused, suppressed by your own code, rejected, or errored — so an addon counting failures can tell a message it deliberately chose not to send from one that was genuinely lost. Existing callbacks are unaffected
  • Added stall detection: if a send's completion callback never arrives, that channel used to block silently for the rest of the session. After a minute of no progress it is now reported, naming the channel and how many messages are waiting behind it. Nothing is dropped or re-sent — the queue is left exactly as it was, and recovers on its own if the callback turns up
  • New documentation section spelling out the delivery contract: what the callback's fourth argument means, and the two traps that catch otherwise-careful code — the result describes the whole message rather than the last piece, and it is a true/false value rather than one of the game's send-result codes

v1.0.4

  • Fixed a crash when sending to a numbered channel — the send died on the way into the queue instead of going out
  • Fixed silent message loss when a very large backlog drained all at once: past roughly twenty thousand queued messages, a few were dropped with no error at all. Backlogs of any size now drain in full, in order
  • A message the queue refuses (bad prefix, missing text, unknown priority) now reports back to your callback instead of ending in silence, so a send chained on the previous message's callback is never stranded
  • A send that fails is now reported to the error handler as well, rather than only appearing with debug output turned on
  • Added an offline test suite that runs the real Ace3 and ChatThrottleLib code outside the game and reproduces the message corruption this library prevents — the three fixes above were found by it. Development-only; it is not part of the download

v1.0.3

  • Updated for the current Classic Era client so the library is no longer flagged out of date; every other supported version (Anniversary realms, Burning Crusade, Wrath, Cataclysm, Mists, and Retail) is unchanged
  • Fixed the packaging rules so the documentation folder and the development-only scripts are correctly left out of the released download — the published zip is now just the library file, the TOC, and the license
  • Internal library revision bumped so this copy takes precedence over an older embedded copy when several addons ship the library side by side
  • No behavioural change — queueing, priority ordering, and the embed contract are identical to v1.0.2

v1.0.2

  • Ace3 is now declared as a proper required dependency for the standalone addon, so it is resolved automatically on install instead of a duplicate copy of LibStub being bundled into the download
  • No change for authors who embed the library — you continue to supply your own LibStub and AceComm-3.0

v1.0.1

  • Added a full changelog, published with each release
  • Expanded the documentation with the background on why chunk interleaving corrupts messages, a step-by-step integration walkthrough, the suppression-wrapper contract, and the slash command reference

v1.0.0

  • Initial public release — transparent per-(prefix, distribution, target) send queue on top of AceComm-3.0; prevents ChatThrottleLib priority-bucket reordering from interleaving chunks across messages; queue drains via CTL callback on last chunk; priority ordering preserved (ALERT > NORMAL > BULK); fully transparent to existing call sites; includes optional /acq slash commands for debug output and live queue inspection

Bug Reports & Feature Requests

Found a bug or have a suggestion?

  • CurseForge page: TBD

If you have any questions, comments or anything else, please feel free to reach out on Discord!

Credits

Developed by:

  • Pimptasty - Author

Special Thanks:

  • The Old Gods guild community for real-world testing
  • Ace3 library maintainers for the excellent framework
  • WoW Classic community for feedback and support

License

AceCommQueue-1.0 is open-source software. See LICENSE file for details.

The AceCommQueue Team

Forgeborn tier frameprofile avatar
  • 2
    Followers
  • 27
    Projects
  • 414.1K
    Downloads
Donate

More from PmptastyView all