feat: Fix loop uses sinceState instead of newSinceState, causing infinite loops.

This commit is contained in:
dab246
2026-02-04 09:48:50 +07:00
committed by Dat H. Pham
parent 4fea45d062
commit 41817091c1
9 changed files with 23 additions and 16 deletions
@@ -31,16 +31,16 @@ mixin BatchGetLabelProcessingMixin on HandleSetErrorMixin, SessionMixin {
} }
final maxObjects = getMaxObjectsInGetMethod(session, accountId); final maxObjects = getMaxObjectsInGetMethod(session, accountId);
final totalEmails = labelIds.length; final totalLabels = labelIds.length;
final batchSize = max(1, min(totalEmails, maxObjects)); final batchSize = max(1, min(totalLabels, maxObjects));
final List<Label> allLabels = []; final List<Label> allLabels = [];
final List<Id> allNotFoundIds = []; final List<Id> allNotFoundIds = [];
State? latestState; State? latestState;
for (int start = 0; start < totalEmails; start += batchSize) { for (int start = 0; start < totalLabels; start += batchSize) {
int end = int end =
(start + batchSize < totalEmails) ? start + batchSize : totalEmails; (start + batchSize < totalLabels) ? start + batchSize : totalLabels;
final currentListIds = labelIds.sublist(start, end); final currentListIds = labelIds.sublist(start, end);
log('BatchGetLabelProcessingMixin::$debugLabel: processing batch ${start + 1} to $end'); log('BatchGetLabelProcessingMixin::$debugLabel: processing batch ${start + 1} to $end');
+2 -2
View File
@@ -92,10 +92,10 @@ mixin MailAPIMixin on HandleSetErrorMixin, SessionMixin {
); );
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? []; final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
final mapErrors = handleSetResponse([setEmailResponse]); final batchErrors = handleSetResponse([setEmailResponse]);
updatedEmailIds.addAll(listEmailIds); updatedEmailIds.addAll(listEmailIds);
mapErrors.addAll(mapErrors); mapErrors.addAll(batchErrors);
} }
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors); return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
+1 -1
View File
@@ -22,7 +22,7 @@ mixin SessionMixin {
maxObjectsInSetMethod, maxObjectsInSetMethod,
CapabilityIdentifierExtension.defaultMaxObjectsInSet, CapabilityIdentifierExtension.defaultMaxObjectsInSet,
); );
log('$runtimeType::_getMaxObjectsInSetMethod:minOfMaxObjectsInSetMethod = $minOfMaxObjectsInSetMethod'); log('$runtimeType::getMaxObjectsInSetMethod:minOfMaxObjectsInSetMethod = $minOfMaxObjectsInSetMethod');
return minOfMaxObjectsInSetMethod; return minOfMaxObjectsInSetMethod;
} }
@@ -19,6 +19,8 @@ import 'package:uuid/uuid.dart';
class LabelApi class LabelApi
with HandleSetErrorMixin, SessionMixin, BatchGetLabelProcessingMixin { with HandleSetErrorMixin, SessionMixin, BatchGetLabelProcessingMixin {
static const int _defaultMaxChanges = 128;
final HttpClient _httpClient; final HttpClient _httpClient;
final Uuid _uuid; final Uuid _uuid;
@@ -179,7 +181,7 @@ class LabelApi
final changesLabelMethod = ChangesLabelMethod( final changesLabelMethod = ChangesLabelMethod(
accountId, accountId,
sinceState, sinceState,
maxChanges: UnsignedInt(128), maxChanges: UnsignedInt(_defaultMaxChanges),
); );
final changesLabelInvocation = final changesLabelInvocation =
jmapRequestBuilder.invocation(changesLabelMethod); jmapRequestBuilder.invocation(changesLabelMethod);
@@ -50,7 +50,7 @@ class LabelRepositoryImpl extends LabelRepository {
final changesResponse = await _labelDatasource.getLabelChanges( final changesResponse = await _labelDatasource.getLabelChanges(
session, session,
accountId, accountId,
sinceState, newSinceState,
); );
hasMoreChanges = changesResponse.hasMoreChanges; hasMoreChanges = changesResponse.hasMoreChanges;
@@ -36,8 +36,10 @@ extension HandleLabelWebsocketExtension on LabelController {
if (refreshState is GetLabelChangesSuccess) { if (refreshState is GetLabelChangesSuccess) {
await _handleGetLabelChangesSuccess(refreshState); await _handleGetLabelChangesSuccess(refreshState);
} else { } else if (refreshState != null) {
onDataFailureViewState(refreshState); onDataFailureViewState(refreshState);
} else {
logWarning('HandleLabelWebsocketExtension::handleWebSocketMessage: refreshState is null');
} }
} catch (e, stackTrace) { } catch (e, stackTrace) {
logWarning( logWarning(
@@ -244,6 +244,10 @@ class LabelUtils {
} }
} }
/// Applies label changes to [currentLabels] **in place**.
///
/// Removes labels matching [destroyedIds], [created], and [updated] IDs,
/// then appends [created] and [updated] labels.
static void applyLabelChanges({ static void applyLabelChanges({
required List<Label> currentLabels, required List<Label> currentLabels,
required List<Label> created, required List<Label> created,
@@ -78,7 +78,7 @@ abstract class PushBaseController {
.nonNulls .nonNulls
.toList(); .toList();
log('PushBaseController::mappingTypeStateToAction():listMailboxActions: $listEmailActions'); log('PushBaseController::mappingTypeStateToAction():listMailboxActions: $listMailboxActions');
if (listMailboxActions.isNotEmpty) { if (listMailboxActions.isNotEmpty) {
mailboxChangeListener.dispatchActions(listMailboxActions); mailboxChangeListener.dispatchActions(listMailboxActions);
@@ -11,11 +11,10 @@ class LabelChangeListener extends ChangeListener {
LabelController? _labelController; LabelController? _labelController;
LabelChangeListener._internal() { LabelChangeListener._internal() {
try { _labelController = getBinding<LabelController>();
_labelController = getBinding<LabelController>(); if (_labelController == null) {
} catch (e) { logWarning(
logError( 'LabelChangeListener::_internal(): LabelController IS NOT REGISTERED');
'LabelChangeListener::_internal(): IS NOT REGISTERED: ${e.toString()}');
} }
} }