Make sure to handle 429:s (rate limiting) on message redactions and final room leave!

This commit is contained in:
N-Pex 2023-02-08 11:22:12 +01:00
parent 06d023dc7f
commit 434c0fb48c
3 changed files with 65 additions and 27 deletions

View file

@ -89,8 +89,8 @@
"members": "no members | 1 member | {count} members",
"leave": "Leave",
"purge_set_room_state": "Setting room state",
"purge_redacting_events": "Redacting events",
"purge_removing_members": "Removing members",
"purge_redacting_events": "Redacting events ({count} of {total})",
"purge_removing_members": "Removing members ({count} of {total})",
"purge_failed": "Failed to purge room!",
"room_list_invites": "Invites",
"room_list_rooms": "Rooms",

View file

@ -1287,6 +1287,10 @@ export default {
restartRRTimer() {
this.stopRRTimer();
if (this.$matrix.currentRoomBeingPurged) {
return;
}
let eventIdFirst = null;
let eventIdLast = null;
if (!this.useAudioLayout) {

View file

@ -37,6 +37,7 @@ export default {
userDisplayName: null,
userAvatar: null,
currentRoom: null,
currentRoomBeingPurged: false,
notificationCount: 0,
};
},
@ -558,6 +559,28 @@ export default {
* @param roomId
*/
purgeRoom(roomId, statusCallback) {
this.currentRoomBeingPurged = true;
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
const withRetry = (codeBlock) => {
return codeBlock().catch((error) => {
if (error && error.errcode == "M_LIMIT_EXCEEDED") {
var retry = 1000;
if (error.data) {
const retryIn = error.data.retry_after_ms;
retry = Math.max(retry, retryIn ? retryIn : 0);
}
console.log("Rate limited, retry in", retry);
return sleep(retry).then(() => withRetry(codeBlock));
} else {
return Promise.resolve();
}
});
};
const oldGlobalErrorSetting = this.matrixClient.getGlobalErrorOnUnknownDevices();
return new Promise((resolve, reject) => {
const room = this.getRoom(roomId);
@ -613,14 +636,32 @@ export default {
statusCallback(this.$t("room.purge_redacting_events"));
// First ignore unknown device errors
this.matrixClient.setGlobalErrorOnUnknownDevices(false);
var redactionPromises = [];
timelineWindow.getEvents().forEach((event) => {
if (!event.isRedacted() && !event.isRedaction() && !event.isState()) {
// Redact!
redactionPromises.push(this.matrixClient.redactEvent(event.getRoomId(), event.getId()));
}
const allEvents = timelineWindow.getEvents().filter((event) => {
return (
!event.isRedacted() &&
!event.isRedaction() &&
!event.isState() &&
(!room.currentState || room.currentState.maySendRedactionForEvent(event, this.currentUserId))
);
});
return Promise.all(redactionPromises);
const redactFirstEvent = (events) => {
statusCallback(
this.$t("room.purge_redacting_events", {
count: allEvents.length - events.length + 1,
total: allEvents.length,
})
);
if (events.length == 0) {
return Promise.resolve(true);
}
const event = events[0];
return withRetry(() => this.matrixClient.redactEvent(event.getRoomId(), event.getId())).then(() =>
redactFirstEvent(events.slice(1))
);
};
return redactFirstEvent(allEvents);
})
.then(() => {
//console.log("Purge: kick members");
@ -628,13 +669,15 @@ export default {
var joined = room.getMembersWithMembership("join");
var invited = room.getMembersWithMembership("invite");
var allMembers = joined.concat(invited);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const kickFirstMember = (members) => {
//console.log(`Kicking ${members.length} members`);
statusCallback(
this.$t("room.purge_removing_members", {
count: allMembers.length - members.length + 1,
total: allMembers.length,
})
);
if (members.length == 0) {
return Promise.resolve(true);
}
@ -644,19 +687,8 @@ export default {
} else {
// Slight pause to avoid rate limiting.
return sleep(0.1)
.then(() => this.matrixClient.kick(roomId, member.userId, "Room Deleted"))
.catch((error) => {
if (error && error.errcode == "M_LIMIT_EXCEEDED") {
var retry = 1000;
if (error.data) {
const retryIn = error.data.retry_after_ms;
retry = Math.max(retry, retryIn ? retryIn : 0);
}
//console.log("Rate limited, retry in", retry);
return sleep(retry).then(() => kickFirstMember(members));
}
})
.finally(() => kickFirstMember(members.slice(1)))
.then(() => withRetry(() => this.matrixClient.kick(roomId, member.userId, "Room Deleted")))
.then(() => kickFirstMember(members.slice(1)));
}
};
@ -665,13 +697,15 @@ export default {
.then(() => {
statusCallback(null);
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
return this.leaveRoom(roomId);
return withRetry(() => this.leaveRoom(roomId));
})
.then(() => {
this.currentRoomBeingPurged = false;
resolve(true); // Done!
})
.catch((err) => {
console.error("Error purging room", err);
this.currentRoomBeingPurged = false;
this.matrixClient.setGlobalErrorOnUnknownDevices(oldGlobalErrorSetting);
reject(err);
});