fix: stale call checker leaks memory

This commit is contained in:
Nicolas Werner 2023-11-03 23:32:48 +01:00
parent e0b6529525
commit 37582a3a8e
No known key found for this signature in database
3 changed files with 24 additions and 33 deletions

View File

@ -1741,6 +1741,8 @@ class Client extends MatrixApi {
await processToDeviceQueue(); await processToDeviceQueue();
} catch (_) {} // we want to dispose any errors this throws } catch (_) {} // we want to dispose any errors this throws
await singleShotStaleCallChecker();
_retryDelay = Future.value(); _retryDelay = Future.value();
onSyncStatus.add(SyncStatusUpdate(SyncStatus.finished)); onSyncStatus.add(SyncStatusUpdate(SyncStatus.finished));
} on MatrixException catch (e, s) { } on MatrixException catch (e, s) {
@ -2148,6 +2150,9 @@ class Client extends MatrixApi {
} }
} }
/// stores when we last checked for stale calls
DateTime lastStaleCallRun = DateTime(0);
Future<Room> _updateRoomsByRoomUpdate( Future<Room> _updateRoomsByRoomUpdate(
String roomId, SyncRoomUpdate chatUpdate) async { String roomId, SyncRoomUpdate chatUpdate) async {
// Update the chat list item. // Update the chat list item.
@ -2188,9 +2193,6 @@ class Client extends MatrixApi {
} }
// If the membership is "leave" then remove the item and stop here // If the membership is "leave" then remove the item and stop here
else if (found && membership == Membership.leave) { else if (found && membership == Membership.leave) {
// stop stale group call checker for left room.
room.stopStaleCallsChecker(room.id);
rooms.removeAt(roomIndex); rooms.removeAt(roomIndex);
// in order to keep the archive in sync, add left room to archive // in order to keep the archive in sync, add left room to archive

View File

@ -90,9 +90,6 @@ class Room {
/// Key-Value store for private account data only visible for this user. /// Key-Value store for private account data only visible for this user.
Map<String, BasicRoomEvent> roomAccountData = {}; Map<String, BasicRoomEvent> roomAccountData = {};
/// stores stale group call checking timers for rooms.
Map<String, Timer> staleGroupCallsTimer = {};
final _sendingQueue = <Completer>[]; final _sendingQueue = <Completer>[];
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
@ -137,9 +134,6 @@ class Room {
setState(state); setState(state);
} }
} }
if (!isArchived) {
startStaleCallsChecker(id);
}
partial = false; partial = false;
} }

View File

@ -43,17 +43,6 @@ extension GroupCallUtils on Room {
return []; return [];
} }
/// stops the stale call checker timer
void stopStaleCallsChecker(String roomId) {
if (staleGroupCallsTimer.tryGet(roomId) != null) {
staleGroupCallsTimer[roomId]!.cancel();
staleGroupCallsTimer.remove(roomId);
Logs().d('[VOIP] stopped stale group calls checker for room $id');
} else {
Logs().d('[VOIP] no stale call checker for room found');
}
}
static const staleCallCheckerDuration = Duration(seconds: 30); static const staleCallCheckerDuration = Duration(seconds: 30);
bool callMemberStateIsExpired( bool callMemberStateIsExpired(
@ -89,23 +78,16 @@ extension GroupCallUtils on Room {
} }
/// checks for stale calls in a room and sends `m.terminated` if all the /// checks for stale calls in a room and sends `m.terminated` if all the
/// expires_ts are expired. Call when opening a room /// expires_ts are expired. Called regularly on sync.
void startStaleCallsChecker(String roomId) async {
stopStaleCallsChecker(roomId);
await singleShotStaleCallCheckerOnRoom();
staleGroupCallsTimer[roomId] = Timer.periodic(
staleCallCheckerDuration,
(timer) async => await singleShotStaleCallCheckerOnRoom(),
);
}
Future<void> singleShotStaleCallCheckerOnRoom() async { Future<void> singleShotStaleCallCheckerOnRoom() async {
Logs().d('[VOIP] checking for stale group calls in room $id'); if (partial) return;
// make sure we have all the to-device messages we are supposed to have
await client.oneShotSync();
final copyGroupCallIds = final copyGroupCallIds =
states.tryGetMap<String, Event>(EventTypes.GroupCallPrefix); states.tryGetMap<String, Event>(EventTypes.GroupCallPrefix);
if (copyGroupCallIds == null) return; if (copyGroupCallIds == null) return;
Logs().d('[VOIP] checking for stale group calls in room $id');
for (final groupCall in copyGroupCallIds.entries) { for (final groupCall in copyGroupCallIds.entries) {
final groupCallId = groupCall.key; final groupCallId = groupCall.key;
final groupCallEvent = groupCall.value; final groupCallEvent = groupCall.value;
@ -165,3 +147,16 @@ extension GroupCallUtils on Room {
} }
} }
} }
extension GroupCallClientUtils on Client {
// call after sync
Future<void> singleShotStaleCallChecker() async {
if (lastStaleCallRun
.add(GroupCallUtils.staleCallCheckerDuration)
.isBefore(DateTime.now())) {
await Future.wait(rooms
.where((r) => r.membership == Membership.join)
.map((r) => r.singleShotStaleCallCheckerOnRoom()));
}
}
}