diff --git a/app/chain/torrents.py b/app/chain/torrents.py index 6877dead..2e994074 100644 --- a/app/chain/torrents.py +++ b/app/chain/torrents.py @@ -179,7 +179,7 @@ class TorrentsChain(ChainBase): # 按pubdate降序排列 torrents.sort(key=lambda x: x.pubdate or '', reverse=True) # 取前N条 - torrents = torrents[:settings.CACHE_CONF["refresh"]] + torrents = torrents[:settings.CONF["refresh"]] if torrents: # 过滤出没有处理过的种子 - 优化:使用集合查找,避免重复创建字符串列表 cached_signatures = {f'{t.torrent_info.title}{t.torrent_info.description}' @@ -219,8 +219,8 @@ class TorrentsChain(ChainBase): else: torrents_cache[domain].append(context) # 如果超过了限制条数则移除掉前面的 - if len(torrents_cache[domain]) > settings.CACHE_CONF["torrents"]: - torrents_cache[domain] = torrents_cache[domain][-settings.CACHE_CONF["torrents"]:] + if len(torrents_cache[domain]) > settings.CONF["torrents"]: + torrents_cache[domain] = torrents_cache[domain][-settings.CONF["torrents"]:] else: logger.info(f'{indexer.get("name")} 没有获取到种子') diff --git a/app/core/config.py b/app/core/config.py index fa241c62..ce30e9d1 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -522,7 +522,7 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): return self.CONFIG_PATH / "cookies" @property - def CACHE_CONF(self): + def CONF(self): """ { "torrents": "缓存种子数量", @@ -531,7 +531,9 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): "douban": "豆瓣请求缓存数量", "fanart": "Fanart请求缓存数量", "meta": "元数据缓存过期时间(秒)", - "memory": "最大占用内存(MB)" + "memory": "最大占用内存(MB)", + "scheduler": "调度器缓存数量" + "threadpool": "线程池数量" } """ if self.BIG_MEMORY_MODE: @@ -543,7 +545,9 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): "bangumi": 512, "fanart": 512, "meta": (self.META_CACHE_EXPIRE or 24) * 3600, - "memory": 2 * 1024 + "memory": 2 * 1024, + "scheduler": 50, + "threadpool": 50 } return { "torrents": 100, @@ -553,7 +557,9 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel): "bangumi": 256, "fanart": 128, "meta": (self.META_CACHE_EXPIRE or 2) * 3600, - "memory": 1024 + "memory": 1024, + "scheduler": 20, + "threadpool": 20 } @property diff --git a/app/helper/thread.py b/app/helper/thread.py index c96eb7d2..1fa09fc4 100644 --- a/app/helper/thread.py +++ b/app/helper/thread.py @@ -2,14 +2,15 @@ from concurrent.futures import ThreadPoolExecutor from typing import Optional from app.utils.singleton import Singleton +from core.config import settings class ThreadHelper(metaclass=Singleton): """ 线程池管理 """ - def __init__(self, max_workers: Optional[int] = 50): - self.pool = ThreadPoolExecutor(max_workers=max_workers) + def __init__(self): + self.pool = ThreadPoolExecutor(max_workers=settings.CONF['threadpool']) def submit(self, func, *args, **kwargs): """ diff --git a/app/modules/bangumi/bangumi.py b/app/modules/bangumi/bangumi.py index 423e2240..6fa095b8 100644 --- a/app/modules/bangumi/bangumi.py +++ b/app/modules/bangumi/bangumi.py @@ -30,7 +30,7 @@ class BangumiApi(object): self._session = requests.Session() self._req = RequestUtils(session=self._session) - @cached(maxsize=settings.CACHE_CONF["bangumi"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["bangumi"], ttl=settings.CONF["meta"]) def __invoke(self, url, key: Optional[str] = None, **kwargs): req_url = self._base_url + url params = {} diff --git a/app/modules/douban/apiv2.py b/app/modules/douban/apiv2.py index 5af0a431..ff75fa66 100644 --- a/app/modules/douban/apiv2.py +++ b/app/modules/douban/apiv2.py @@ -171,14 +171,14 @@ class DoubanApi(metaclass=Singleton): ).digest() ).decode() - @cached(maxsize=settings.CACHE_CONF["douban"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["douban"], ttl=settings.CONF["meta"]) def __invoke_recommend(self, url: str, **kwargs) -> dict: """ 推荐/发现类API """ return self.__invoke(url, **kwargs) - @cached(maxsize=settings.CACHE_CONF["douban"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["douban"], ttl=settings.CONF["meta"]) def __invoke_search(self, url: str, **kwargs) -> dict: """ 搜索类API @@ -213,7 +213,7 @@ class DoubanApi(metaclass=Singleton): return resp.json() return resp.json() if resp else {} - @cached(maxsize=settings.CACHE_CONF["douban"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["douban"], ttl=settings.CONF["meta"]) def __post(self, url: str, **kwargs) -> dict: """ POST请求 diff --git a/app/modules/douban/douban_cache.py b/app/modules/douban/douban_cache.py index 0ce9666a..2baa8c71 100644 --- a/app/modules/douban/douban_cache.py +++ b/app/modules/douban/douban_cache.py @@ -16,7 +16,7 @@ from app.schemas.types import MediaType lock = RLock() CACHE_EXPIRE_TIMESTAMP_STR = "cache_expire_timestamp" -EXPIRE_TIMESTAMP = settings.CACHE_CONF["meta"] +EXPIRE_TIMESTAMP = settings.CONF["meta"] class DoubanCache(metaclass=Singleton): diff --git a/app/modules/fanart/__init__.py b/app/modules/fanart/__init__.py index c20b55c9..4957b760 100644 --- a/app/modules/fanart/__init__.py +++ b/app/modules/fanart/__init__.py @@ -420,7 +420,7 @@ class FanartModule(_ModuleBase): return result @classmethod - @cached(maxsize=settings.CACHE_CONF["fanart"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["fanart"], ttl=settings.CONF["meta"]) def __request_fanart(cls, media_type: MediaType, queryid: Union[str, int]) -> Optional[dict]: if media_type == MediaType.MOVIE: image_url = cls._movie_url % queryid diff --git a/app/modules/themoviedb/tmdb_cache.py b/app/modules/themoviedb/tmdb_cache.py index 7f3908f1..fdd6312b 100644 --- a/app/modules/themoviedb/tmdb_cache.py +++ b/app/modules/themoviedb/tmdb_cache.py @@ -15,7 +15,7 @@ from app.schemas.types import MediaType lock = RLock() CACHE_EXPIRE_TIMESTAMP_STR = "cache_expire_timestamp" -EXPIRE_TIMESTAMP = settings.CACHE_CONF["meta"] +EXPIRE_TIMESTAMP = settings.CONF["meta"] class TmdbCache(metaclass=Singleton): diff --git a/app/modules/themoviedb/tmdbapi.py b/app/modules/themoviedb/tmdbapi.py index a8a1515e..0380d91c 100644 --- a/app/modules/themoviedb/tmdbapi.py +++ b/app/modules/themoviedb/tmdbapi.py @@ -500,7 +500,7 @@ class TmdbApi: return ret_info - @cached(maxsize=settings.CACHE_CONF["tmdb"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["tmdb"], ttl=settings.CONF["meta"]) @rate_limit_exponential(source="match_tmdb_web", base_wait=5, max_wait=1800, enable_logging=True) def match_web(self, name: str, mtype: MediaType) -> Optional[dict]: """ diff --git a/app/modules/themoviedb/tmdbv3api/tmdb.py b/app/modules/themoviedb/tmdbv3api/tmdb.py index 27cf77bd..1bf1ae75 100644 --- a/app/modules/themoviedb/tmdbv3api/tmdb.py +++ b/app/modules/themoviedb/tmdbv3api/tmdb.py @@ -124,7 +124,7 @@ class TMDb(object): def cache(self, cache): self._cache_enabled = bool(cache) - @cached(maxsize=settings.CACHE_CONF["tmdb"], ttl=settings.CACHE_CONF["meta"]) + @cached(maxsize=settings.CONF["tmdb"], ttl=settings.CONF["meta"]) def cached_request(self, method, url, data, json, _ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ diff --git a/app/scheduler.py b/app/scheduler.py index 66b53ae4..8790caf0 100644 --- a/app/scheduler.py +++ b/app/scheduler.py @@ -166,7 +166,7 @@ class Scheduler(metaclass=Singleton): # 创建定时服务 self._scheduler = BackgroundScheduler(timezone=settings.TZ, executors={ - 'default': ThreadPoolExecutor(20) + 'default': ThreadPoolExecutor(settings.CONF['scheduler']) }) # CookieCloud定时同步 @@ -323,7 +323,7 @@ class Scheduler(metaclass=Singleton): "interval", id="clear_cache", name="缓存清理", - hours=settings.CACHE_CONF["meta"] / 3600, + hours=settings.CONF["meta"] / 3600, kwargs={ 'job_id': 'clear_cache' } diff --git a/app/startup/memory_initializer.py b/app/startup/memory_initializer.py index 01571e33..a66acba3 100644 --- a/app/startup/memory_initializer.py +++ b/app/startup/memory_initializer.py @@ -8,7 +8,7 @@ def init_memory_manager(): """ memory_manager = MemoryHelper() # 设置内存阈值和启动监控 - memory_manager.set_threshold(settings.CACHE_CONF['memory']) + memory_manager.set_threshold(settings.CONF['memory']) memory_manager.start_monitoring() diff --git a/config/app.env b/config/app.env index 0fd2e9de..c57ea4a7 100644 --- a/config/app.env +++ b/config/app.env @@ -27,3 +27,5 @@ DB_MAX_OVERFLOW=500 DB_TIMEOUT=60 # 是否开发调试模式,仅开发人员使用,打开后将停止后台服务 DEV=false +API_TOKEN='jYImOhUt6p4acOeMpNgDhA' +ANIME_GENREIDS='[16]'