ForcePilot/backend/package/yuxi/channel/extensions/xmpp/rate_limiter.py
Kris 5946478772 feat(channel): 添加小红书、XMPP、元宝和 Zalo 渠道扩展
新增小红书、XMPP、元宝、Zalo 四个渠道扩展。

小红书渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, dedupe, media, status, window

XMPP 渠道扩展主要模块:plugin, config, gateway, outbound, streaming, pairing, security, dedupe, accounts, commands, muc, rate_limiter, stanza_utils, status, monitor

元宝渠道扩展主要模块:plugin, client, config_schema, gateway, outbound(chunk/queue/transport), inbound(dispatcher), streaming, pairing, security, accounts, actions, commands, codec(biz/conn), session, shared, utils

Zalo 渠道扩展主要模块:api, config, gateway, webhook, outbound, pairing, security, session, polling, monitor, status
2026-05-21 12:04:05 +08:00

37 lines
1.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import asyncio
import time
import logging
logger = logging.getLogger("yuxi.channel.xmpp.rate_limiter")
class XmppRateLimiter:
"""Token Bucket 限流器,默认 5 msg/s突发 10 条"""
def __init__(self, max_rate: float = 5.0, burst: int = 10):
self._rate = max_rate
self._burst = burst
self._tokens = float(burst)
self._last_refill = time.monotonic()
self._lock = asyncio.Lock()
async def acquire(self) -> None:
async with self._lock:
now = time.monotonic()
elapsed = now - self._last_refill
self._tokens = min(self._burst, self._tokens + elapsed * self._rate)
self._last_refill = now
if self._tokens < 1.0:
wait_time = (1.0 - self._tokens) / self._rate
logger.debug("XMPP rate limit: waiting %.2fs", wait_time)
await asyncio.sleep(wait_time)
self._tokens = 0.0
else:
self._tokens -= 1.0
xmpp_rate_limiter = XmppRateLimiter(max_rate=5.0, burst=10)