fix(awooop): use shared redis for approval gates
Some checks failed
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / tests (push) Successful in 1m0s
CD Pipeline / build-and-deploy (push) Failing after 4m6s
CD Pipeline / post-deploy-checks (push) Has been skipped

This commit is contained in:
OG T
2026-05-06 13:18:43 +08:00
parent 56b4d8165b
commit 2c2bf9d665
6 changed files with 266 additions and 19 deletions

View File

@@ -44,7 +44,7 @@ from typing import Any
from uuid import UUID
import structlog
from sqlalchemy import select, text
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.awooop_models import (
@@ -54,6 +54,7 @@ from src.db.awooop_models import (
AwoooPMcpToolRegistry,
AwoooPProject,
)
from src.core.redis_client import get_redis
from src.plugins.mcp.interfaces import MCPToolResult
from src.plugins.mcp.registry import get_provider_registry
@@ -359,14 +360,9 @@ class McpGateway:
raise GateApprovalError("write/admin 操作需要 run_idapproval 追蹤用)")
try:
import aioredis
from src.core.config import settings
redis = aioredis.from_url(settings.REDIS_URL)
redis = get_redis()
approval_key = f"mcp_approval:{ctx.project_id}:{ctx.agent_id}:{ctx.tool_name}:{ctx.run_id}"
approved = await redis.get(approval_key)
await redis.aclose()
except Exception as exc:
logger.warning(
"mcp_gate5_redis_error",

View File

@@ -46,6 +46,8 @@ from typing import Any
import structlog
from src.core.redis_client import get_redis
logger = structlog.get_logger(__name__)
# ─────────────────────────────────────────────────────────────────────────────
@@ -219,29 +221,23 @@ async def record_approval(
exp = payload["exp"]
try:
import aioredis
from src.core.config import settings
redis = aioredis.from_url(settings.REDIS_URL)
redis = get_redis()
# jti NX
jti_key = f"{_JTI_KEY_PREFIX}{jti}"
ttl_remaining = max(exp - int(time.time()), 1)
ok = await redis.set(jti_key, "1", nx=True, ex=ttl_remaining)
if not ok:
await redis.aclose()
raise TokenReplayError(f"jti={jti!r} 已使用")
# SADD approver
sig_key = f"{_SIG_SET_PREFIX}{project_id}:{run_id}:{tool_name}"
added = await redis.sadd(sig_key, approver_id)
if added == 0:
await redis.aclose()
raise DuplicateApproverError(f"approver '{approver_id}' 已簽核")
await redis.expire(sig_key, _SIG_TTL_SECONDS)
count = int(await redis.scard(sig_key))
await redis.aclose()
logger.info(
"awooop_approval_recorded",
@@ -271,13 +267,9 @@ async def check_approval_quorum(
檢查 quorum。Raises QuorumNotMetError if 不足。
"""
try:
import aioredis
from src.core.config import settings
redis = aioredis.from_url(settings.REDIS_URL)
redis = get_redis()
sig_key = f"{_SIG_SET_PREFIX}{project_id}:{run_id}:{tool_name}"
count = int(await redis.scard(sig_key))
await redis.aclose()
if count < required_count:
raise QuorumNotMetError(f"簽核數不足({count}/{required_count}")