refactor(apps): 重构数据层目录结构并新增启动预热编排器
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../../features/calendar/data/repositories/calendar_repository.dart';
|
||||
import '../../features/messages/data/repositories/inbox_repository.dart';
|
||||
import '../../features/chat/data/repositories/chat_history_repository.dart';
|
||||
|
||||
enum AppPrewarmStatus { idle, running, completed, timedOut, failed }
|
||||
|
||||
class AppPrewarmOrchestrator extends ChangeNotifier {
|
||||
AppPrewarmOrchestrator({
|
||||
required CalendarRepository calendarRepository,
|
||||
required InboxRepository inboxRepository,
|
||||
required ChatHistoryRepository chatHistoryRepository,
|
||||
this.bootBudget = const Duration(milliseconds: 1200),
|
||||
Future<void> Function()? prewarmChatHistory,
|
||||
Future<void> Function()? prewarmCalendarToday,
|
||||
Future<void> Function()? prewarmUnreadInbox,
|
||||
}) : _calendarRepository = calendarRepository,
|
||||
_inboxRepository = inboxRepository,
|
||||
_chatHistoryRepository = chatHistoryRepository,
|
||||
_prewarmChatHistory = prewarmChatHistory,
|
||||
_prewarmCalendarToday = prewarmCalendarToday,
|
||||
_prewarmUnreadInbox = prewarmUnreadInbox;
|
||||
|
||||
final CalendarRepository _calendarRepository;
|
||||
final InboxRepository _inboxRepository;
|
||||
final ChatHistoryRepository _chatHistoryRepository;
|
||||
final Duration bootBudget;
|
||||
final Future<void> Function()? _prewarmChatHistory;
|
||||
final Future<void> Function()? _prewarmCalendarToday;
|
||||
final Future<void> Function()? _prewarmUnreadInbox;
|
||||
|
||||
AppPrewarmStatus _status = AppPrewarmStatus.idle;
|
||||
AppPrewarmStatus get status => _status;
|
||||
|
||||
String? _userId;
|
||||
Future<void>? _running;
|
||||
|
||||
bool get isBootBlocking => _status == AppPrewarmStatus.running;
|
||||
|
||||
Future<void> ensureStartedFor(String userId) {
|
||||
if (_userId == userId &&
|
||||
(_status == AppPrewarmStatus.completed ||
|
||||
_status == AppPrewarmStatus.timedOut)) {
|
||||
return Future<void>.value();
|
||||
}
|
||||
if (_userId == userId && _running != null) {
|
||||
return _running!;
|
||||
}
|
||||
|
||||
_userId = userId;
|
||||
_status = AppPrewarmStatus.running;
|
||||
notifyListeners();
|
||||
|
||||
final tasks = Future.wait<void>([
|
||||
_runPrewarmChatHistory(),
|
||||
_runPrewarmCalendarToday(),
|
||||
_runPrewarmUnreadInbox(),
|
||||
]);
|
||||
|
||||
final running = _runWithBudget(tasks);
|
||||
_running = running;
|
||||
return running.whenComplete(() {
|
||||
if (identical(_running, running)) {
|
||||
_running = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _runPrewarmChatHistory() {
|
||||
final override = _prewarmChatHistory;
|
||||
if (override != null) {
|
||||
return override();
|
||||
}
|
||||
return _chatHistoryRepository.loadHistory();
|
||||
}
|
||||
|
||||
Future<void> _runPrewarmCalendarToday() {
|
||||
final override = _prewarmCalendarToday;
|
||||
if (override != null) {
|
||||
return override();
|
||||
}
|
||||
return _calendarRepository.getDayEvents(DateTime.now());
|
||||
}
|
||||
|
||||
Future<void> _runPrewarmUnreadInbox() {
|
||||
final override = _prewarmUnreadInbox;
|
||||
if (override != null) {
|
||||
return override();
|
||||
}
|
||||
return _inboxRepository.getMessages(isRead: false);
|
||||
}
|
||||
|
||||
Future<void> _runWithBudget(Future<void> tasks) async {
|
||||
try {
|
||||
await tasks.timeout(bootBudget);
|
||||
_status = AppPrewarmStatus.completed;
|
||||
notifyListeners();
|
||||
} on TimeoutException {
|
||||
_status = AppPrewarmStatus.timedOut;
|
||||
notifyListeners();
|
||||
} catch (_) {
|
||||
_status = AppPrewarmStatus.failed;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_userId = null;
|
||||
_running = null;
|
||||
if (_status != AppPrewarmStatus.idle) {
|
||||
_status = AppPrewarmStatus.idle;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user