mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-09-29 00:32:06 +08:00
bugfix:修复sqlite部分场景下锁竞争问题;新增插件恶意触发配置文件 (#2144)
* bugfix:修复sqlite部分场景下锁竞争问题;新增插件恶意触发配置文件 * 文件没同步完
This commit is contained in:
@@ -5,12 +5,10 @@ from typing_extensions import Self
|
||||
from tortoise import fields
|
||||
from tortoise.expressions import Q
|
||||
|
||||
from zhenxun.services.cache import CacheException, CacheRegistry, CacheRoot
|
||||
from zhenxun.services.cache.runtime_cache import BanMemoryCache
|
||||
from zhenxun.services.data_access import DataAccess
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import CacheType, DbLockType
|
||||
from zhenxun.utils.enum import DbLockType
|
||||
from zhenxun.utils.exception import UserAndGroupIsNone
|
||||
|
||||
|
||||
@@ -38,28 +36,8 @@ class BanConsole(Model):
|
||||
unique_together = ("user_id", "group_id")
|
||||
indexes = [("user_id",), ("group_id",)] # noqa: RUF012
|
||||
|
||||
cache_type = CacheType.BAN
|
||||
"""缓存类型"""
|
||||
cache_key_field = ("user_id", "group_id")
|
||||
"""缓存键字段"""
|
||||
enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT]
|
||||
"""开启锁"""
|
||||
_cache_checked: ClassVar[bool] = False
|
||||
|
||||
@classmethod
|
||||
def _ensure_cache_registered(cls):
|
||||
"""兜底注册 BAN 缓存,避免启动时序导致的未注册问题。"""
|
||||
if cls._cache_checked:
|
||||
return
|
||||
try:
|
||||
CacheRoot.get_model(CacheType.BAN)
|
||||
except CacheException:
|
||||
CacheRegistry.register(
|
||||
CacheType.BAN,
|
||||
cls,
|
||||
key_format="{user_id}_{group_id}",
|
||||
)
|
||||
cls._cache_checked = True
|
||||
|
||||
@classmethod
|
||||
async def create(cls, *args, **kwargs) -> Self:
|
||||
@@ -87,15 +65,13 @@ class BanConsole(Model):
|
||||
返回:
|
||||
Self | None: Self
|
||||
"""
|
||||
cls._ensure_cache_registered()
|
||||
if not user_id and not group_id:
|
||||
raise UserAndGroupIsNone()
|
||||
if user_id:
|
||||
dao = DataAccess(cls)
|
||||
return (
|
||||
await dao.safe_get_or_none(user_id=user_id, group_id=group_id)
|
||||
await cls.safe_get_or_none(user_id=user_id, group_id=group_id)
|
||||
if group_id
|
||||
else await dao.safe_get_or_none(user_id=user_id, group_id__isnull=True)
|
||||
else await cls.safe_get_or_none(user_id=user_id, group_id__isnull=True)
|
||||
)
|
||||
else:
|
||||
return await cls.safe_get_or_none(
|
||||
@@ -177,7 +153,6 @@ class BanConsole(Model):
|
||||
)
|
||||
if not user_id and not group_id:
|
||||
raise UserAndGroupIsNone()
|
||||
cls._ensure_cache_registered()
|
||||
target, _ = await cls.update_or_create(
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
|
||||
@@ -9,10 +9,9 @@ from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.models.task_info import TaskInfo
|
||||
from zhenxun.services.cache import CacheRoot
|
||||
from zhenxun.services.cache.runtime_cache import GroupMemoryCache
|
||||
from zhenxun.services.data_access import DataAccess
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.services.db_context.schema_ops import AlterColumnType, CreateIndex
|
||||
from zhenxun.utils.enum import CacheType, DbLockType, PluginType
|
||||
from zhenxun.utils.enum import DbLockType, PluginType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from zhenxun.services.cache.runtime_cache import GroupSnapshot
|
||||
@@ -98,10 +97,6 @@ class GroupConsole(Model):
|
||||
("group_id",)
|
||||
]
|
||||
|
||||
cache_type = CacheType.GROUPS
|
||||
"""缓存类型"""
|
||||
cache_key_field = ("group_id", "channel_id")
|
||||
"""缓存键字段"""
|
||||
enable_lock: ClassVar[list[DbLockType]] = [DbLockType.CREATE, DbLockType.UPSERT]
|
||||
"""开启锁"""
|
||||
_root_group_locks: ClassVar[dict[str, asyncio.Lock]] = {}
|
||||
@@ -331,9 +326,11 @@ class GroupConsole(Model):
|
||||
if update_fields:
|
||||
await keep.save(update_fields=update_fields)
|
||||
|
||||
for group in groups:
|
||||
if group.id != keep.id:
|
||||
await group.delete()
|
||||
duplicate_ids = [
|
||||
group.id for group in groups if group.id and group.id != keep.id
|
||||
]
|
||||
if duplicate_ids:
|
||||
await cls.filter(id__in=duplicate_ids).delete()
|
||||
await GroupMemoryCache.upsert_from_model(keep)
|
||||
return keep
|
||||
|
||||
@@ -417,14 +414,13 @@ class GroupConsole(Model):
|
||||
clean_duplicates: bool = True,
|
||||
) -> Self | None:
|
||||
"""获取群组(数据库)"""
|
||||
dao = DataAccess(cls)
|
||||
if channel_id:
|
||||
return await dao.safe_get_or_none(
|
||||
return await cls.safe_get_or_none(
|
||||
group_id=group_id,
|
||||
channel_id=channel_id,
|
||||
clean_duplicates=clean_duplicates,
|
||||
)
|
||||
return await dao.safe_get_or_none(
|
||||
return await cls.safe_get_or_none(
|
||||
group_id=group_id,
|
||||
channel_id__isnull=True,
|
||||
clean_duplicates=clean_duplicates,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.utils.enum import CacheType
|
||||
|
||||
|
||||
class GroupPluginSetting(Model):
|
||||
@@ -18,11 +17,6 @@ class GroupPluginSetting(Model):
|
||||
updated_at = fields.DatetimeField(auto_now=True, description="最后更新时间")
|
||||
"""最后更新时间"""
|
||||
|
||||
cache_type = CacheType.GROUP_PLUGIN_SETTINGS
|
||||
"""缓存类型"""
|
||||
cache_key_field = ("group_id", "plugin_name")
|
||||
"""缓存键字段"""
|
||||
|
||||
class Meta: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||
table = "group_plugin_settings"
|
||||
table_description = "插件分群通用配置表"
|
||||
|
||||
Reference in New Issue
Block a user