@@ -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;
@@ -865,11 +875,13 @@ class UpdateMachine {
865
875
}
866
876
867
877
void poll () async {
868
- BackoffMachine ? backoffMachine ;
878
+ assert ( ! _disposed) ;
869
879
880
+ BackoffMachine ? backoffMachine;
870
881
while (true ) {
871
882
if (_debugLoopSignal != null ) {
872
883
await _debugLoopSignal! .future;
884
+ if (_disposed) return ;
873
885
assert (() {
874
886
_debugLoopSignal = Completer ();
875
887
return true ;
@@ -880,7 +892,10 @@ class UpdateMachine {
880
892
try {
881
893
result = await getEvents (store.connection,
882
894
queueId: queueId, lastEventId: lastEventId);
895
+ if (_disposed) return ;
883
896
} catch (e) {
897
+ if (_disposed) return ;
898
+
884
899
store.isLoading = true ;
885
900
switch (e) {
886
901
case ZulipApiException (code: 'BAD_EVENT_QUEUE_ID' ):
@@ -929,6 +944,7 @@ class UpdateMachine {
929
944
final events = result.events;
930
945
for (final event in events) {
931
946
await store.handleEvent (event);
947
+ if (_disposed) return ;
932
948
}
933
949
if (events.isNotEmpty) {
934
950
lastEventId = events.last.id;
@@ -944,6 +960,7 @@ class UpdateMachine {
944
960
// TODO(#322) save acked token, to dedupe updating it on the server
945
961
// TODO(#323) track the addFcmToken/etc request, warn if not succeeding
946
962
Future <void > registerNotificationToken () async {
963
+ assert (! _disposed);
947
964
if (! debugEnableRegisterNotificationToken) {
948
965
return ;
949
966
}
@@ -957,12 +974,14 @@ class UpdateMachine {
957
974
await NotificationService .registerToken (store.connection, token: token);
958
975
}
959
976
960
- /// Cleans up resources.
977
+ /// Cleans up resources and tells the instance not to make new API requests .
961
978
///
962
979
/// After this is called, the instance is not in a usable state
963
980
/// and should be abandoned.
964
981
void dispose () { // TODO abort long-poll and close ApiConnection
982
+ assert (! _disposed);
965
983
NotificationService .instance.token.removeListener (_registerNotificationToken);
984
+ _disposed = true ;
966
985
}
967
986
968
987
/// In debug mode, controls whether [fetchEmojiData] should
0 commit comments