fix(bridge): 429 Rate Limit 무한 루프 방지 — 지수 백오프 + Collector 폴링 보호 + rate limit 완화

This commit is contained in:
Variet Worker
2026-03-12 00:49:37 +09:00
parent feb8c05a73
commit 52c9526fdb
6 changed files with 75 additions and 9 deletions

View File

@@ -94,6 +94,11 @@ class CollectorBridge:
"""
while self._running:
try:
# Skip cycle if rate-limited
if self.remote.is_rate_limited:
await asyncio.sleep(self._poll_interval)
continue
current_files = set()
for fname in self.local.list_json_files("pending"):
rid = fname.replace(".json", "")
@@ -148,12 +153,21 @@ class CollectorBridge:
"""Poll Gateway for responses and write them locally for Extension."""
while self._running:
try:
# Skip cycle if rate-limited
if self.remote.is_rate_limited:
await asyncio.sleep(self._poll_interval)
continue
# Check each forwarded pending for a response
for rid in list(self._forwarded_pending):
if rid in self._startup_pending:
continue # Don't poll responses for pre-startup files
# Rate-limit guard: stop polling if we got rate-limited mid-cycle
if self.remote.is_rate_limited:
break
data = await self.remote.aread_json("response", f"{rid}.json")
if data is None or data.get("waiting"):
await asyncio.sleep(0.2) # Throttle between individual response polls
continue
# Write response locally for Extension to pick up
@@ -175,12 +189,14 @@ class CollectorBridge:
"""Poll Gateway for commands and write them locally for Extension."""
while self._running:
try:
commands = await self.remote.apoll_commands(self.project_name)
for cmd in commands:
cmd_id = cmd.get("id", str(int(time.time() * 1000)))
fname = f"{cmd_id}.json"
self.local.write_json("commands", fname, cmd)
logger.info(f"[COLLECTOR] ← Gateway: command {cmd.get('text', '?')[:30]}")
# Skip cycle if rate-limited
if not self.remote.is_rate_limited:
commands = await self.remote.apoll_commands(self.project_name)
for cmd in commands:
cmd_id = cmd.get("id", str(int(time.time() * 1000)))
fname = f"{cmd_id}.json"
self.local.write_json("commands", fname, cmd)
logger.info(f"[COLLECTOR] ← Gateway: command {cmd.get('text', '?')[:30]}")
except Exception as e:
logger.error(f"[COLLECTOR] poll_commands error: {e}")