fix: queue TTL + per-member send rate limit + size cap + no-recipient reject + ack.error
Broker (all need redeploy): - sweepOrphanMessages: DELETE undelivered message_queue rows older than 7 days; hourly sweep. Stops unbounded growth when a sender typos a name (queued forever, never claimed). - Per-member send rate limit: TokenBucket(60/min, burst 10) keyed on memberId so reconnecting can't bypass. Surfaces as queued=false, error='rate_limit: ...'. - Pre-flight size cap: reject at handleSend if nonce+ciphertext+ targetSpec exceeds env.MAX_MESSAGE_BYTES with a clear error instead of silent WSS frame-level kill. - No-recipient reject: for direct sends, check any matching peer is connected BEFORE queueing. Kills the self-send silent drop (sending to your own pubkey when you only have one session connected) and typo-to-offline-peer silent drops. - WSAckMessage.error field added for structured failure reasons. CLI: - ws-client ack handler reads msg.queued and msg.error; surfaces rate_limit / too_large / no_recipient to callers instead of returning ok:true with a dummy messageId. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1618,10 +1618,13 @@ export class BrokerClient {
|
||||
if (msg.type === "ack") {
|
||||
const pending = this.pendingSends.get(String(msg.id ?? ""));
|
||||
if (pending) {
|
||||
pending.resolve({
|
||||
ok: true,
|
||||
messageId: String(msg.messageId ?? ""),
|
||||
});
|
||||
const queued = msg.queued !== false;
|
||||
const errStr = typeof msg.error === "string" ? msg.error : undefined;
|
||||
pending.resolve(
|
||||
queued
|
||||
? { ok: true, messageId: String(msg.messageId ?? "") }
|
||||
: { ok: false, error: errStr ?? "broker rejected send" },
|
||||
);
|
||||
this.pendingSends.delete(pending.id);
|
||||
}
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user