refactor: 修复预热编排器竞态条件添加 runToken 机制
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user