@@ -454,17 +454,23 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
454
454
autocompleteViewManager.reassemble ();
455
455
}
456
456
457
+ bool _disposed = false ;
458
+
457
459
@override
458
460
void dispose () {
461
+ assert (! _disposed);
459
462
recentDmConversationsView.dispose ();
460
463
unreads.dispose ();
461
464
_messages.dispose ();
462
465
typingStatus.dispose ();
463
466
updateMachine? .dispose ();
467
+ _disposed = true ;
464
468
super .dispose ();
465
469
}
466
470
467
471
Future <void > handleEvent (Event event) async {
472
+ assert (! _disposed);
473
+
468
474
switch (event) {
469
475
case HeartbeatEvent ():
470
476
assert (debugLog ("server event: heartbeat" ));
@@ -606,6 +612,8 @@ class PerAccountStore extends ChangeNotifier with EmojiStore, ChannelStore, Mess
606
612
}
607
613
608
614
Future <void > sendMessage ({required MessageDestination destination, required String content}) {
615
+ assert (! _disposed);
616
+
609
617
// TODO implement outbox; see design at
610
618
// https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M3881.20Sending.20outbox.20messages.20is.20fraught.20with.20issues/near/1405739
611
619
return _apiSendMessage (connection,
@@ -790,6 +798,8 @@ class UpdateMachine {
790
798
final String queueId;
791
799
int lastEventId;
792
800
801
+ bool _disposed = false ;
802
+
793
803
static Future <InitialSnapshot > _registerQueueWithRetry (
794
804
ApiConnection connection) async {
795
805
BackoffMachine ? backoffMachine;
@@ -868,8 +878,11 @@ class UpdateMachine {
868
878
BackoffMachine ? backoffMachine;
869
879
870
880
while (true ) {
881
+ if (_disposed) return ;
882
+
871
883
if (_debugLoopSignal != null ) {
872
884
await _debugLoopSignal! .future;
885
+ if (_disposed) return ;
873
886
assert (() {
874
887
_debugLoopSignal = Completer ();
875
888
return true ;
@@ -880,7 +893,10 @@ class UpdateMachine {
880
893
try {
881
894
result = await getEvents (store.connection,
882
895
queueId: queueId, lastEventId: lastEventId);
896
+ if (_disposed) return ;
883
897
} catch (e) {
898
+ if (_disposed) return ;
899
+
884
900
store.isLoading = true ;
885
901
switch (e) {
886
902
case ZulipApiException (code: 'BAD_EVENT_QUEUE_ID' ):
@@ -929,6 +945,7 @@ class UpdateMachine {
929
945
final events = result.events;
930
946
for (final event in events) {
931
947
await store.handleEvent (event);
948
+ if (_disposed) return ;
932
949
}
933
950
if (events.isNotEmpty) {
934
951
lastEventId = events.last.id;
@@ -944,6 +961,7 @@ class UpdateMachine {
944
961
// TODO(#322) save acked token, to dedupe updating it on the server
945
962
// TODO(#323) track the addFcmToken/etc request, warn if not succeeding
946
963
Future <void > registerNotificationToken () async {
964
+ assert (! _disposed);
947
965
if (! debugEnableRegisterNotificationToken) {
948
966
return ;
949
967
}
@@ -957,12 +975,14 @@ class UpdateMachine {
957
975
await NotificationService .registerToken (store.connection, token: token);
958
976
}
959
977
960
- /// Cleans up resources.
978
+ /// Cleans up resources and tells the instance not to make new API requests .
961
979
///
962
980
/// After this is called, the instance is not in a usable state
963
981
/// and should be abandoned.
964
982
void dispose () { // TODO abort long-poll and close ApiConnection
983
+ assert (! _disposed);
965
984
NotificationService .instance.token.removeListener (_registerNotificationToken);
985
+ _disposed = true ;
966
986
}
967
987
968
988
/// In debug mode, controls whether [fetchEmojiData] should
0 commit comments