按最小忙碌度获取一个可用匿名会话。
(
self,
exclude_user_ids: Optional[Set[str]] = None,
)
| 487 | await self._close_http_client() |
| 488 | |
| 489 | async def acquire( |
| 490 | self, |
| 491 | exclude_user_ids: Optional[Set[str]] = None, |
| 492 | ) -> GuestSession: |
| 493 | """按最小忙碌度获取一个可用匿名会话。""" |
| 494 | excluded = exclude_user_ids or set() |
| 495 | attempts_left = self._get_fill_attempt_budget(len(excluded) + 1) |
| 496 | |
| 497 | while attempts_left > 0: |
| 498 | candidates = self._list_valid_sessions(exclude_user_ids=excluded) |
| 499 | if candidates: |
| 500 | session = min( |
| 501 | candidates, |
| 502 | key=lambda item: (item.active_requests, item.created_at), |
| 503 | ) |
| 504 | with self._lock: |
| 505 | current = self._sessions.get(session.user_id) |
| 506 | if ( |
| 507 | current |
| 508 | and self._is_session_usable(current) |
| 509 | and current.user_id not in excluded |
| 510 | ): |
| 511 | current.active_requests += 1 |
| 512 | return current |
| 513 | |
| 514 | new_session = await self._create_session() |
| 515 | attempts_left -= 1 |
| 516 | if new_session.user_id in excluded: |
| 517 | logger.warning( |
| 518 | "⚠️ 获取匿名会话时命中排除 user_id,已忽略: " |
| 519 | f"{new_session.user_id}" |
| 520 | ) |
| 521 | continue |
| 522 | |
| 523 | if not self._store_session(new_session): |
| 524 | logger.warning( |
| 525 | "⚠️ 获取匿名会话时命中重复 user_id,已重试: " |
| 526 | f"{new_session.user_id}" |
| 527 | ) |
| 528 | continue |
| 529 | |
| 530 | with self._lock: |
| 531 | current = self._sessions.get(new_session.user_id) |
| 532 | if current and self._is_session_usable(current): |
| 533 | current.active_requests += 1 |
| 534 | return current |
| 535 | |
| 536 | raise RuntimeError("匿名会话池获取失败: 未能创建唯一匿名会话") |
| 537 | |
| 538 | def release(self, user_id: str): |
| 539 | """释放一个匿名会话占用。""" |