Skip to content

Commit 3d7b233

Browse files
authored
fix(资源更新): 修复启动器更新弹窗卡死与重复弹出 (#2715)
## 为什么改 启动器启动时若 GitHub 网络慢,弹窗构造在主线程同步请求启动器版本信息(pygit2 list_heads),UI 卡死无响应;且弹窗处理完毕后待更新标记未清理,导致同一会话内反复弹窗。 ## 改动要点 - 修复:UpdateService 增加启动器版本信息缓存,检查线程查询后写入,UI 构造下载项只读缓存,主线程不再发起网络请求 - 修复:资源更新检查每次启动只执行一次,弹窗处理完毕后清除待更新标记,不再重复弹窗 - 修复:OCR 下载等待期间抑制弹窗,避免任务已在队列时二次弹出 ## 关联 承接 #2714(兼容修复已合入本分支)
1 parent 426fdc6 commit 3d7b233

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

src/one_dragon/envs/update_service.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ def __init__(
3737
self.project_config: ProjectConfig = project_config
3838
self.env_config: EnvConfig = env_config
3939
self.git_service: GitService = git_service
40+
# 版本信息缓存:检查线程查询后填入,UI 构造下载项只读缓存,避免主线程网络请求
41+
self._launcher_version_cache: dict[str, tuple[str, str, str]] = {}
4042

4143
@staticmethod
4244
def get_launcher_exe_name(launcher_type: LauncherType) -> str:
@@ -54,15 +56,20 @@ def _get_launcher_zip_suffix(launcher_type: LauncherType) -> str:
5456
return RUNTIME_LAUNCHER_ZIP_SUFFIX if launcher_type == 'runtime' else LAUNCHER_ZIP_SUFFIX
5557

5658
def get_launcher_version_info(self, launcher_type: LauncherType) -> tuple[str, str, str]:
57-
"""获取当前启动器版本、最新稳定版和最新测试版。"""
59+
"""获取当前启动器版本、最新稳定版和最新测试版(带缓存,重复调用不重新请求网络)。"""
60+
cached = self._launcher_version_cache.get(launcher_type)
61+
if cached is not None:
62+
return cached
5863
exe_path = Path(os_utils.get_work_dir()) / self.get_launcher_exe_name(launcher_type)
5964
current_version = app_utils.get_exe_version(str(exe_path)) if exe_path.exists() else ''
6065
try:
6166
latest_stable, latest_beta = self.git_service.get_latest_tag()
6267
except Exception:
6368
log.error('获取最新启动器版本失败', exc_info=True)
6469
latest_stable, latest_beta = '', ''
65-
return current_version, latest_stable, latest_beta
70+
result = (current_version, latest_stable, latest_beta)
71+
self._launcher_version_cache[launcher_type] = result
72+
return result
6673

6774
def is_launcher_update_available(self) -> bool:
6875
"""检查当前启动器通道是否存在可用更新。"""

src/one_dragon_qt/services/resource_update_coordinator.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def __init__(
8989
self._suppressed_update_keys: set[str] = set()
9090
self._update_dialog_scheduled: bool = False
9191
self._update_dialog_open: bool = False
92+
self._ocr_waiting: bool = False
9293
self._last_check_time: float = 0
9394
self._check_interval: float = 300
9495
self._checks_started: bool = False
@@ -120,7 +121,9 @@ def _register_check(self, resource_check: _ResourceCheck) -> None:
120121
self._check_runners[resource_check.check_id] = runner
121122

122123
def check_updates(self, force: bool = False) -> None:
123-
"""按冷却时间并行启动各资源提供器的检查。"""
124+
"""每次启动只检查一次;启动检查完成后,后续非强制调用不再检查。"""
125+
if self._checks_started and not force:
126+
return
124127
current_time = time.time()
125128
if not force and current_time - self._last_check_time <= self._check_interval:
126129
return
@@ -168,6 +171,7 @@ def _schedule_update_dialog(self) -> None:
168171
or not self._checks_started
169172
or not all(self._checks_complete.values())
170173
or not (has_pending_update or self._pending_ocr_request is not None)
174+
or self._ocr_waiting
171175
or self._update_dialog_scheduled
172176
or self._update_dialog_open
173177
):
@@ -185,6 +189,7 @@ def _show_update_dialog(self) -> None:
185189
specs = self._build_pending_specs(included_ocr_request)
186190
if not specs:
187191
self._update_dialog_open = False
192+
self._reset_pending_updates()
188193
return
189194

190195
self._suppressed_update_keys.update(
@@ -214,7 +219,7 @@ def _show_update_dialog(self) -> None:
214219
False,
215220
)
216221
self._update_dialog_open = False
217-
self._schedule_update_dialog()
222+
self._reset_pending_updates()
218223
return
219224
selected_specs = dialog.selected_specs()
220225
remember_choice = dialog.remember_choice
@@ -225,6 +230,7 @@ def _show_update_dialog(self) -> None:
225230
remember_choice,
226231
)
227232
self._update_dialog_open = False
233+
self._reset_pending_updates()
228234
self._schedule_update_dialog()
229235

230236
def _build_pending_specs(
@@ -314,6 +320,7 @@ def _wait_for_ocr_task(
314320
ResourceDownloadTaskState.FAILED,
315321
ResourceDownloadTaskState.CANCELLED,
316322
)
323+
self._ocr_waiting = True
317324
if task.state in terminal_states:
318325
self._respond_ocr_request(
319326
request,
@@ -347,6 +354,11 @@ def _disconnect() -> None:
347354
self.queue.task_updated.connect(_on_task_updated)
348355
self.queue.task_removed.connect(_on_task_removed)
349356

357+
def _reset_pending_updates(self) -> None:
358+
"""弹窗已展示并处理完毕后清除本轮待更新标记,避免立即重复弹窗。"""
359+
for check_id in self._pending_updates:
360+
self._pending_updates[check_id] = False
361+
350362
def _respond_ocr_request(
351363
self,
352364
request: ContextDownloadRequestEvent,
@@ -356,6 +368,7 @@ def _respond_ocr_request(
356368
"""结束指定 OCR 下载确认请求,不影响后来到达的新请求。"""
357369
if self._pending_ocr_request is request:
358370
self._pending_ocr_request = None
371+
self._ocr_waiting = False
359372
request.respond(confirmed=confirmed, remember=remember)
360373

361374
def _build_launcher_specs(self) -> list[ResourceDownloadSpec]:

0 commit comments

Comments
 (0)