fix(cnb): skip local email cache and add safe email/state cache clearing

(cherry picked from commit 0e7f589df58240badc1d2340e9856882aa075b63)
This commit is contained in:
dab246
2025-12-02 11:52:48 +07:00
committed by Dat H. Pham
parent 9d4f6e73d2
commit b3e5ab0df4
21 changed files with 141 additions and 294 deletions
@@ -77,5 +77,5 @@ abstract class ThreadDataSource {
Future<PresentationEmail> getEmailById(Session session, AccountId accountId, EmailId emailId, {Properties? properties});
Future<void> clearEmailCacheAndStateCache(AccountId accountId, Session session);
Future<void> clearEmailCacheAndStateCache();
}
@@ -133,12 +133,9 @@ class LocalThreadDataSourceImpl extends ThreadDataSource {
}
@override
Future<void> clearEmailCacheAndStateCache(AccountId accountId, Session session) {
Future<void> clearEmailCacheAndStateCache() {
return Future.sync(() async {
return await _cachingManager.clearAllEmailAndStateCache(
accountId: accountId,
userName: session.username,
);
return await _cachingManager.clearAllEmailAndStateCache();
}).catchError(_exceptionThrower.throwException);
}
}
@@ -142,7 +142,7 @@ class ThreadDataSourceImpl extends ThreadDataSource {
}
@override
Future<void> clearEmailCacheAndStateCache(AccountId accountId, Session session) {
Future<void> clearEmailCacheAndStateCache() {
throw UnimplementedError();
}
}
@@ -148,37 +148,8 @@ class ThreadRepositoryImpl extends ThreadRepository {
EmailFilter? emailFilter,
Properties? propertiesCreated,
}) async* {
final localDataSource = mapDataSource[DataSourceType.local];
final networkDataSource = mapDataSource[DataSourceType.network];
if (localDataSource == null || networkDataSource == null) {
logError(
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
'Missing required data sources (local or network).',
);
return;
}
List<Email> cachedList = const [];
jmap.State? cachedState;
// Load cached emails
try {
cachedList = await localDataSource.getAllEmailCache(
accountId,
session.username,
inMailboxId: emailFilter?.mailboxId,
sort: sort,
limit: limit,
filterOption: emailFilter?.filterOption,
);
} catch (_) {
logError(
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
'Failed to load cached emails',
);
}
// Load cached state
try {
cachedState = await stateDataSource.getState(
@@ -187,29 +158,19 @@ class ThreadRepositoryImpl extends ThreadRepository {
StateType.email,
);
} catch (_) {
logError(
logWarning(
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
'Failed to load cached email state',
);
}
final localResponse = EmailsResponse(
emailList: cachedList,
state: cachedState,
);
log(
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
'Local cache count = ${cachedList.length}; '
'State = ${cachedState?.value}',
'State cache = ${cachedState?.value}',
);
if (localResponse.hasEmails()) {
yield localResponse;
}
// Query fresh emails from server
final serverResponse = await networkDataSource.getAllEmail(
final serverResponse = await mapDataSource[DataSourceType.network]!.getAllEmail(
session,
accountId,
limit: limit,
@@ -588,13 +549,8 @@ class ThreadRepositoryImpl extends ThreadRepository {
}
@override
Future<void> clearEmailCacheAndStateCache(
AccountId accountId,
Session session,
) => mapDataSource[DataSourceType.local]!.clearEmailCacheAndStateCache(
accountId,
session,
);
Future<void> clearEmailCacheAndStateCache() =>
mapDataSource[DataSourceType.local]!.clearEmailCacheAndStateCache();
@override
Stream<EmailsResponse> loadAllEmailInFolderWithoutCache({