perf: use keyed create locks for ban/group and add tuple support

This commit is contained in:
HibiKier
2025-12-23 17:22:41 +08:00
parent a8251165fa
commit af75d7fc5a
3 changed files with 21 additions and 5 deletions
+4
View File
@@ -44,6 +44,10 @@ class BanConsole(Model):
"""缓存键字段""" """缓存键字段"""
enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT] enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT]
"""开启锁""" """开启锁"""
lock_fields: ClassVar[dict[DbLockType, tuple[str, str]]] = {
DbLockType.CREATE: ("user_id", "group_id"),
DbLockType.UPSERT: ("user_id", "group_id"),
}
@classmethod @classmethod
async def _get_data(cls, user_id: str | None, group_id: str | None) -> Self | None: async def _get_data(cls, user_id: str | None, group_id: str | None) -> Self | None:
+4
View File
@@ -98,6 +98,10 @@ class GroupConsole(Model):
"""缓存键字段""" """缓存键字段"""
enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT] enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT]
"""开启锁""" """开启锁"""
lock_fields: ClassVar[dict[DbLockType, tuple[str, str]]] = {
DbLockType.CREATE: ("group_id", "channel_id"),
DbLockType.UPSERT: ("group_id", "channel_id"),
}
@classmethod @classmethod
async def _get_task_modules(cls, *, default_status: bool) -> list[str]: async def _get_task_modules(cls, *, default_status: bool) -> list[str]:
+11 -3
View File
@@ -87,7 +87,7 @@ class Model(TortoiseModel):
cls_sem = cls.sem_data.setdefault(cls.__name__, {}) cls_sem = cls.sem_data.setdefault(cls.__name__, {})
# 是否配置了按字段的锁 # 是否配置了按字段的锁
lock_fields: dict[DbLockType, str] = getattr(cls, "lock_fields", {}) or {} lock_fields: dict[DbLockType, Any] = getattr(cls, "lock_fields", {}) or {}
if lock_type in lock_fields and lock_key is not None: if lock_type in lock_fields and lock_key is not None:
keyed = cls_sem.setdefault(lock_type, {}) keyed = cls_sem.setdefault(lock_type, {})
if not isinstance(keyed, dict): if not isinstance(keyed, dict):
@@ -131,9 +131,13 @@ class Model(TortoiseModel):
cls, using_db: BaseDBAsyncClient | None = None, **kwargs: Any cls, using_db: BaseDBAsyncClient | None = None, **kwargs: Any
) -> Self: ) -> Self:
"""创建数据(使用CREATE锁)""" """创建数据(使用CREATE锁)"""
lock_fields: dict[DbLockType, str] = getattr(cls, "lock_fields", {}) or {} lock_fields: dict[DbLockType, Any] = getattr(cls, "lock_fields", {}) or {}
lock_key = None lock_key = None
if field := lock_fields.get(DbLockType.CREATE): if field := lock_fields.get(DbLockType.CREATE):
if isinstance(field, tuple):
key_tuple = tuple(kwargs.get(f) for f in field)
lock_key = key_tuple if any(v is not None for v in key_tuple) else None
else:
lock_key = kwargs.get(field) lock_key = kwargs.get(field)
async with cls._lock_context(DbLockType.CREATE, lock_key): async with cls._lock_context(DbLockType.CREATE, lock_key):
@@ -166,9 +170,13 @@ class Model(TortoiseModel):
**kwargs: Any, **kwargs: Any,
) -> tuple[Self, bool]: ) -> tuple[Self, bool]:
"""更新或创建数据(使用UPSERT锁)""" """更新或创建数据(使用UPSERT锁)"""
lock_fields: dict[DbLockType, str] = getattr(cls, "lock_fields", {}) or {} lock_fields: dict[DbLockType, Any] = getattr(cls, "lock_fields", {}) or {}
lock_key = None lock_key = None
if field := lock_fields.get(DbLockType.UPSERT): if field := lock_fields.get(DbLockType.UPSERT):
if isinstance(field, tuple):
key_tuple = tuple(kwargs.get(f) for f in field)
lock_key = key_tuple if any(v is not None for v in key_tuple) else None
else:
lock_key = kwargs.get(field) lock_key = kwargs.get(field)
async with cls._lock_context(DbLockType.UPSERT, lock_key): async with cls._lock_context(DbLockType.UPSERT, lock_key):