从数据库初始化全局 Token 池 Args: provider: 提供商名称(当前仅使用 zai) failure_threshold: 失败阈值 recovery_timeout: 恢复超时时间(秒) Returns: TokenPool 实例(即使没有 Token 也会创建空池)
(
provider: str = "zai",
failure_threshold: int = 3,
recovery_timeout: int = 1800
)
| 579 | |
| 580 | |
| 581 | async def initialize_token_pool_from_db( |
| 582 | provider: str = "zai", |
| 583 | failure_threshold: int = 3, |
| 584 | recovery_timeout: int = 1800 |
| 585 | ) -> Optional[TokenPool]: |
| 586 | """ |
| 587 | 从数据库初始化全局 Token 池 |
| 588 | |
| 589 | Args: |
| 590 | provider: 提供商名称(当前仅使用 zai) |
| 591 | failure_threshold: 失败阈值 |
| 592 | recovery_timeout: 恢复超时时间(秒) |
| 593 | |
| 594 | Returns: |
| 595 | TokenPool 实例(即使没有 Token 也会创建空池) |
| 596 | """ |
| 597 | global _token_pool |
| 598 | |
| 599 | from app.services.token_dao import get_token_dao |
| 600 | |
| 601 | dao = get_token_dao() |
| 602 | |
| 603 | # 从数据库加载 Token(只加载启用的认证用户 Token) |
| 604 | token_records = await dao.get_tokens_by_provider(provider, enabled_only=True) |
| 605 | |
| 606 | # 转换为 TokenPool 所需格式 |
| 607 | tokens = [] |
| 608 | if token_records: |
| 609 | tokens = [ |
| 610 | (record["id"], record["token"], record.get("token_type", "unknown")) |
| 611 | for record in token_records |
| 612 | ] |
| 613 | |
| 614 | # 过滤掉 guest token(不应该在数据库中,但防御性检查) |
| 615 | user_tokens = [ |
| 616 | (tid, tval, ttype) for tid, tval, ttype in tokens |
| 617 | if ttype != "guest" |
| 618 | ] |
| 619 | |
| 620 | if len(user_tokens) < len(tokens): |
| 621 | guest_count = len(tokens) - len(user_tokens) |
| 622 | logger.warning(f"⚠️ 过滤了 {guest_count} 个匿名用户 Token") |
| 623 | |
| 624 | tokens = user_tokens |
| 625 | |
| 626 | # 始终创建 Token 池实例(即使为空) |
| 627 | with _pool_lock: |
| 628 | _token_pool = TokenPool(tokens, failure_threshold, recovery_timeout) |
| 629 | |
| 630 | if not tokens: |
| 631 | logger.warning(f"⚠️ {provider} 没有有效的认证用户 Token,已创建空 Token 池") |
| 632 | else: |
| 633 | logger.info(f"🔧 从数据库初始化 Token 池({provider}),共 {len(tokens)} 个 Token") |
| 634 | |
| 635 | return _token_pool |
| 636 | |
| 637 | |
| 638 | async def sync_token_stats_to_db(): |
no test coverage detected