fix(ext,bot): 통신 아키텍처 감사 — writeRegistration 이중쓰기 + ApprovalView fallback + scanner 최적화

- step-probe.ts: writeRegistration WS 후 return 추가 (파일 이중쓰기 방지)
- bot.py: ApprovalView approve/reject/choice — send_response_to_pending_owner 반환값 확인 + file bridge fallback (5곳)
- bot.py: scanner 주기 3s/5s → 30s (Hub 모드 불필요 I/O 감소)
This commit is contained in:
Variet Worker
2026-03-17 21:30:05 +09:00
parent 47cc838d9d
commit 0fae7e32aa
4 changed files with 32 additions and 16 deletions

29
bot.py
View File

@@ -98,12 +98,13 @@ class ApprovalView(discord.ui.View):
"project_name": getattr(self.request, 'project_name', ''),
}
# Hub WS route (primary — reaches remote Extensions)
delivered = False
if self.hub:
await self.hub.send_response_to_pending_owner(self.request.request_id, {
delivered = await self.hub.send_response_to_pending_owner(self.request.request_id, {
"type": "response", "data": response_data,
})
else:
# File bridge (fallback — only when Hub is unavailable)
if not delivered:
# File bridge fallback (Hub unavailable OR owner disconnected)
self.bridge.write_response(UserResponse(**response_data))
embed = interaction.message.embeds[0] if interaction.message.embeds else None
if embed:
@@ -130,11 +131,12 @@ class ApprovalView(discord.ui.View):
"step_type": getattr(self.request, 'step_type', ''),
"project_name": getattr(self.request, 'project_name', ''),
}
delivered = False
if self.hub:
await self.hub.send_response_to_pending_owner(self.request.request_id, {
delivered = await self.hub.send_response_to_pending_owner(self.request.request_id, {
"type": "response", "data": response_data,
})
else:
if not delivered:
self.bridge.write_response(UserResponse(**response_data))
embed = interaction.message.embeds[0] if interaction.message.embeds else None
if embed:
@@ -156,11 +158,12 @@ class ApprovalView(discord.ui.View):
"step_type": getattr(self.request, 'step_type', ''),
"project_name": getattr(self.request, 'project_name', ''),
}
delivered = False
if self.hub:
await self.hub.send_response_to_pending_owner(self.request.request_id, {
delivered = await self.hub.send_response_to_pending_owner(self.request.request_id, {
"type": "response", "data": response_data,
})
else:
if not delivered:
self.bridge.write_response(UserResponse(**response_data))
embed = interaction.message.embeds[0] if interaction.message.embeds else None
if embed:
@@ -608,7 +611,7 @@ class GravityBot(commands.Bot):
# ─── Approval Scanner ────────────────────────────────────────────
@tasks.loop(seconds=3)
@tasks.loop(seconds=30) # Hub mode: WS is primary, file scan is fallback only
async def pending_approval_scanner(self):
"""Scan bridge/pending/ for new approval requests + reload registrations.
@@ -1081,8 +1084,9 @@ class GravityBot(commands.Bot):
"""Auto-approve a pending request via Hub."""
self._sent_approval_ids.add(request.request_id)
delivered = False
if self.hub:
await self.hub.send_response_to_pending_owner(request.request_id, {
delivered = await self.hub.send_response_to_pending_owner(request.request_id, {
"type": "response",
"data": {
"request_id": request.request_id,
@@ -1092,9 +1096,8 @@ class GravityBot(commands.Bot):
"project_name": request.project_name,
},
})
# Hub delivered — skip file bridge to prevent dual delivery
else:
# File bridge fallback (only when Hub is unavailable)
if not delivered:
# File bridge fallback (Hub unavailable OR owner disconnected)
self.bridge.write_response(UserResponse(
request_id=request.request_id, approved=True,
step_type=request.step_type,
@@ -1230,7 +1233,7 @@ class GravityBot(commands.Bot):
# ─── Chat Snapshot Scanner ─────────────────────────────────────────
@tasks.loop(seconds=5)
@tasks.loop(seconds=30) # Hub mode: WS is primary, file scan is fallback only
async def chat_snapshot_scanner(self):
"""Scan bridge/chat_snapshots/ for AI response dumps."""
try: