Skip to content

Commit d4649fa

Browse files
committed
fix: 防止同步把主控打爆
1 parent 2ca7db5 commit d4649fa

File tree

5 files changed

+40
-16
lines changed

5 files changed

+40
-16
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0
1+
3.0.1

core/__init__.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ async def main():
5151
)
5252
])
5353

54-
def read_version():
55-
with open("VERSION", "r") as f:
56-
return f.read().strip()
57-
5854
def init():
5955
atexit.register(main_exit)
6056
try:
@@ -66,6 +62,4 @@ def init():
6662
logger.tsuccess("main.success.service_exit")
6763

6864
def main_exit():
69-
_WAITLOCK.release()
70-
71-
VERSION = read_version()
65+
_WAITLOCK.release()

core/cluster.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import asyncio
33
from collections import defaultdict, deque
44
from dataclasses import asdict, dataclass
5+
import datetime
56
import hashlib
67
import hmac
78
import io
@@ -36,6 +37,17 @@ class File:
3637
def __hash__(self) -> int:
3738
return hash((self.hash, self.size, self.mtime))
3839

40+
@dataclass
41+
class FailedFile:
42+
file: File
43+
failed_times: int
44+
first_time: datetime.datetime
45+
last_failed_time: float
46+
47+
def __hash__(self) -> int:
48+
return hash(self.file)
49+
50+
3951
class StorageManager:
4052
def __init__(self, clusters: 'ClusterManager'):
4153
self.clusters = clusters
@@ -278,7 +290,7 @@ def __init__(self, clusters: 'ClusterManager'):
278290
self.cluster_last_modified: defaultdict['Cluster', int] = defaultdict(lambda: 0)
279291
self.sync_sem: utils.SemaphoreLock = utils.SemaphoreLock(256)
280292
self.download_statistics = DownloadStatistics()
281-
self.failed_hashs: asyncio.Queue[File] = asyncio.Queue()
293+
self.failed_hashs: asyncio.Queue[FailedFile] = asyncio.Queue()
282294
self.failed_hash_urls: defaultdict[str, FileDownloadInfo] = defaultdict(lambda: FileDownloadInfo(set()))
283295
self.task = None
284296

@@ -383,10 +395,18 @@ async def download(self, filelist: set[File]):
383395
await session.close()
384396

385397
async def _download(self, session: aiohttp.ClientSession, file_queues: asyncio.Queue[File], pbar: DownloadStatistics):
386-
while not file_queues.empty():
398+
while not file_queues.empty() or not self.failed_hashs.empty():
387399
recved = 0
388400
try:
389-
file = await file_queues.get()
401+
failed_file = None
402+
if file_queues.empty():
403+
failed_file = await self.failed_hashs.get()
404+
file = failed_file.file
405+
t = max(0, min(failed_file.failed_times * 30, 600) * 1e9 - (time.monotonic_ns() - failed_file.last_failed_time))
406+
logger.tdebug("cluster.debug.retry_download", start_date=failed_file.first_time, file_path=file.path, file_hash=file.hash, file_size=units.format_bytes(file.size), time=units.format_count_time(t), count=failed_file.failed_times)
407+
await asyncio.sleep(t)
408+
else:
409+
file = await file_queues.get()
390410
content = io.BytesIO()
391411
async with self.sync_sem:
392412
async with session.get(
@@ -409,7 +429,10 @@ async def _download(self, session: aiohttp.ClientSession, file_queues: asyncio.Q
409429
break
410430
except Exception as e:
411431
pbar.update(-recved)
412-
await file_queues.put(file)
432+
if failed_file is None:
433+
failed_file = FailedFile(file, 0, datetime.datetime.now(), time.monotonic_ns())
434+
failed_file.failed_times += 1
435+
await self.failed_hashs.put(failed_file)
413436
pbar.update_failed()
414437
r = None
415438
if "resp" in locals():
@@ -933,7 +956,7 @@ def __init__(self, hash: str, size: int, mtime: float, data: bytes) -> None:
933956
ROOT = Path(__file__).parent.parent
934957

935958
API_VERSION = "1.12.1"
936-
USER_AGENT = f"openbmclapi/{API_VERSION} python-openbmclapi/3.0"
959+
USER_AGENT = f"openbmclapi/{API_VERSION} python-openbmclapi/{config.VERSION}"
937960
CHECK_FILE_CONTENT = "Python OpenBMCLAPI"
938961
CHECK_FILE_MD5 = hashlib.md5(CHECK_FILE_CONTENT.encode("utf-8")).hexdigest()
939962
CHECK_FILE = File(
@@ -957,7 +980,7 @@ def convert_file_to_storage_file(file: File) -> SFile:
957980
)
958981

959982
async def init():
960-
logger.tinfo("cluster.info.init", openbmclapi_version=API_VERSION, version=core.VERSION)
983+
logger.tinfo("cluster.info.init", openbmclapi_version=API_VERSION, version=config.VERSION)
961984
# read clusters from config
962985
config_clusters = config.Config.get("clusters")
963986
for ccluster in config_clusters:

core/config.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,10 @@ def auto_sync_assets(self):
153153
def github_token(self):
154154
return Config.get("advanced.github_token", None) or None
155155

156-
const = Const()
156+
const = Const()
157+
158+
def read_version():
159+
with open("VERSION", "r") as f:
160+
return f.read().strip()
161+
162+
VERSION = read_version()

i18n/zh_cn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@
4242
"cluster.error.download.report": "上报 [${file_path} ${file_hash}(${file_size})] 错误次数 [${failed}] 地址是:${urls}",
4343
"cluster.info.request_certing": "节点 [${cluster}] 正在请求证书……",
4444
"cluster.info.init": "当前 OpenBMCLAPI 版本为 [${openbmclapi_version}] Python OpenBMCLAPI 版本为 [${version}]",
45-
"cluster.success.no_missing_files": "当前暂无更新的文件"
45+
"cluster.success.no_missing_files": "当前暂无更新的文件",
46+
"cluster.debug.retry_download": "文件 [${file_path} ${file_hash}(${file_size})] 第 ${count} 次下载失败,将在 ${time} 重试"
4647
}

0 commit comments

Comments
 (0)