refactor: 修复预热编排器竞态条件添加 runToken 机制

This commit is contained in:
zl-q
2026-03-30 09:06:38 +08:00
parent 41f35d6e22
commit bd7ac6285c
3 changed files with 44 additions and 6 deletions
@@ -37,6 +37,7 @@ class AppPrewarmOrchestrator extends ChangeNotifier {
String? _userId;
Future<void>? _running;
int _runToken = 0;
bool get isBootBlocking => _status == AppPrewarmStatus.running;
@@ -51,6 +52,7 @@ class AppPrewarmOrchestrator extends ChangeNotifier {
}
_userId = userId;
final runToken = ++_runToken;
_status = AppPrewarmStatus.running;
notifyListeners();
@@ -60,7 +62,7 @@ class AppPrewarmOrchestrator extends ChangeNotifier {
_runPrewarmUnreadInbox(),
]);
final running = _runWithBudget(tasks);
final running = _runWithBudget(tasks, userId: userId, runToken: runToken);
_running = running;
return running.whenComplete(() {
if (identical(_running, running)) {
@@ -93,15 +95,30 @@ class AppPrewarmOrchestrator extends ChangeNotifier {
return _inboxRepository.getMessages(isRead: false);
}
Future<void> _runWithBudget(Future<void> tasks) async {
Future<void> _runWithBudget(
Future<void> tasks, {
required String userId,
required int runToken,
}) async {
bool isLatestRun() => _runToken == runToken && _userId == userId;
try {
await tasks.timeout(bootBudget);
if (!isLatestRun()) {
return;
}
_status = AppPrewarmStatus.completed;
notifyListeners();
} on TimeoutException {
if (!isLatestRun()) {
return;
}
_status = AppPrewarmStatus.timedOut;
notifyListeners();
} catch (_) {
if (!isLatestRun()) {
return;
}
_status = AppPrewarmStatus.failed;
notifyListeners();
}
@@ -110,6 +127,7 @@ class AppPrewarmOrchestrator extends ChangeNotifier {
void reset() {
_userId = null;
_running = null;
_runToken += 1;
if (_status != AppPrewarmStatus.idle) {
_status = AppPrewarmStatus.idle;
notifyListeners();