fix(auth): 登录目录就绪幂等化与并发控制
- employee/settings/user_session_metrics 的 ensure_*_ready 改为按 bind 缓存 + 锁, 避免每次登录重复建表与并发场景下的竞态 - auth 登录链路先查员工再降级触发目录就绪,并吞掉查询期 SQLAlchemy 异常 - 默认管理员账号由 superadmin 迁移为 admin,兼容历史账号回填 - 补充登录降级与设置持久化相关测试
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from collections import Counter
|
||||
from datetime import UTC, date, datetime
|
||||
import threading
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy import select
|
||||
@@ -81,11 +82,31 @@ def prepare_employee_directory() -> None:
|
||||
|
||||
|
||||
class EmployeeService:
|
||||
_directory_ready_lock = threading.Lock()
|
||||
_directory_ready_keys: set[tuple[str, int]] = set()
|
||||
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
self.repository = EmployeeRepository(db)
|
||||
|
||||
@staticmethod
|
||||
def _bind_cache_key(db: Session) -> tuple[str, int]:
|
||||
bind = db.get_bind()
|
||||
return (bind.url.render_as_string(hide_password=True), id(bind.pool))
|
||||
|
||||
def ensure_directory_ready(self) -> None:
|
||||
cache_key = self._bind_cache_key(self.db)
|
||||
if cache_key in self._directory_ready_keys:
|
||||
return
|
||||
|
||||
with self._directory_ready_lock:
|
||||
if cache_key in self._directory_ready_keys:
|
||||
return
|
||||
|
||||
self._ensure_directory_ready_uncached()
|
||||
self._directory_ready_keys.add(cache_key)
|
||||
|
||||
def _ensure_directory_ready_uncached(self) -> None:
|
||||
try:
|
||||
Base.metadata.create_all(bind=self.db.get_bind())
|
||||
ensure_employee_schema(self.db)
|
||||
|
||||
Reference in New Issue
Block a user