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
Debug & Diagnostics
- Optional runtime debug output via
AceCommQueue:SetDebug(true)
- Optional slash command registration:
ACQ:RegisterSlashCommand("/acq")
- Slash command lets you toggle debug output and inspect live queue state without a reload
How It Works
Integration (Three Steps)
- Load the library in your
.toc before your own files:
Libs\LibStub\LibStub.lua
Libs\AceCommQueue-1.0\AceCommQueue-1.0.lua
- Embed after AceComm in
OnInitialize:
AceComm must be embedded first, then any custom wrappers, then AceCommQueue last so it wraps the complete chain.
- 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
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 all WoW Classic versions (Era, BCC, Wrath)
- 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 debug on|off — Enable or disable debug output
- /acq queues — Print current queue state for all active channels
Requirements
- LibStub
- AceComm-3.0 (part of Ace3)
Recent Updates
v1.0.0 (Latest Release)
- 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?
If you have any questions, comments or anything else, please feel free to reach out on Discord!
Credits
Developed by:
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.