fix(avatar): keep BOXIM status ready during long polls

This commit is contained in:
stefanfeng
2026-08-20 15:58:07 +08:00
parent 89f52963b7
commit 64b7680ec4
2 changed files with 27 additions and 2 deletions
@@ -12,6 +12,7 @@ from routers.authorizations import _require_authorization
from routers.avatars import _require_owned_avatar from routers.avatars import _require_owned_avatar
router = APIRouter(tags=["分身接管"]) router = APIRouter(tags=["分身接管"])
BOXIM_STATUS_FRESH_SECONDS = 60
@router.get("/avatar/{avatar_id}/takeover/status") @router.get("/avatar/{avatar_id}/takeover/status")
@@ -44,7 +45,9 @@ def get_takeover_status(
cursor cursor
and cursor.initialized and cursor.initialized
and cursor.last_polled_at and cursor.last_polled_at
and cursor.last_polled_at >= datetime.utcnow() - timedelta(seconds=15) # BOXIM offline-message reads can long-poll for about 20 seconds.
and cursor.last_polled_at
>= datetime.utcnow() - timedelta(seconds=BOXIM_STATUS_FRESH_SECONDS)
): ):
status, message = "ready", "BOXIM 已连接,收到私聊消息 3 秒后自动回复" status, message = "ready", "BOXIM 已连接,收到私聊消息 3 秒后自动回复"
else: else:
@@ -1,6 +1,6 @@
"""Tests for takeover configuration and BOXIM connection status.""" """Tests for takeover configuration and BOXIM connection status."""
from datetime import datetime from datetime import datetime, timedelta
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
@@ -192,6 +192,28 @@ def test_takeover_status_reports_ready_pending_count_and_errors(authorization_co
assert ready["pendingCount"] == 1 assert ready["pendingCount"] == 1
assert ready["lastPolledAt"] assert ready["lastPolledAt"]
db = SessionLocal()
try:
cursor = db.query(TakeoverCursor).filter(TakeoverCursor.avatar_id == avatar_id).one()
cursor.last_polled_at = datetime.utcnow() - timedelta(seconds=30)
db.commit()
finally:
db.close()
long_polling = client.get(endpoint, headers=context["owner_headers"]).json()["data"]
assert long_polling["status"] == "ready"
db = SessionLocal()
try:
cursor = db.query(TakeoverCursor).filter(TakeoverCursor.avatar_id == avatar_id).one()
cursor.last_polled_at = datetime.utcnow() - timedelta(seconds=61)
db.commit()
finally:
db.close()
stale = client.get(endpoint, headers=context["owner_headers"]).json()["data"]
assert stale["status"] == "connecting"
db = SessionLocal() db = SessionLocal()
try: try:
cursor = db.query(TakeoverCursor).filter(TakeoverCursor.avatar_id == avatar_id).one() cursor = db.query(TakeoverCursor).filter(TakeoverCursor.avatar_id == avatar_id).one()