mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-18 18:40:58 +01:00
fix: promises in groups.leave
speed up user.delete
user.delete calls `groups.leaveAllGroups` which calls rejectMembership with 500+ groups. This function then tries to remove the user from `group:<group>:pending` and `group:<group>:invited` sets so a total for 1k sets. You can't be invited or request membership to privilege groups so filter the groups before sending to rejectMembership
clearGroupTitleIfSet function tries to remove the group title from the user. It was only skipping privilege groups and registered-users, but unverified-users & verified users weren't added to the check
Messaging.leaveRooms, make a single call to isUserInRoom and passing an array of roomIds
In user.delete, check utils.isNumber(uid) once.
Call deleteVotes/deleteChats/revokeAllSessions in Promise.all
If user is local dont call activitypub.actors.remove(), this saves a db call to `await db.isSortedSetMember('usersRemote:lastCrawled', id);`
This commit is contained in:
@@ -43,20 +43,20 @@ module.exports = function (Groups) {
|
||||
|
||||
const promises = [];
|
||||
if (emptyPrivilegeGroups.length) {
|
||||
promises.push(Groups.destroy, emptyPrivilegeGroups);
|
||||
promises.push(Groups.destroy(emptyPrivilegeGroups));
|
||||
}
|
||||
if (visibleGroups.length) {
|
||||
promises.push(
|
||||
db.sortedSetAdd,
|
||||
'groups:visible:memberCount',
|
||||
visibleGroups.map(groupData => groupData.memberCount),
|
||||
visibleGroups.map(groupData => groupData.name)
|
||||
db.sortedSetAdd(
|
||||
'groups:visible:memberCount',
|
||||
visibleGroups.map(groupData => groupData.memberCount),
|
||||
visibleGroups.map(groupData => groupData.name)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
await Promise.all([
|
||||
...promises,
|
||||
clearGroupTitleIfSet(groupsToLeave, uid),
|
||||
leavePublicRooms(groupsToLeave, uid),
|
||||
]);
|
||||
@@ -82,7 +82,12 @@ module.exports = function (Groups) {
|
||||
}
|
||||
|
||||
async function clearGroupTitleIfSet(groupNames, uid) {
|
||||
groupNames = groupNames.filter(groupName => groupName !== 'registered-users' && !Groups.isPrivilegeGroup(groupName));
|
||||
groupNames = groupNames.filter(
|
||||
groupName => groupName !== 'registered-users' &&
|
||||
groupName !== 'unverified-users' &&
|
||||
groupName !== 'verified-users' &&
|
||||
!Groups.isPrivilegeGroup(groupName)
|
||||
);
|
||||
if (!groupNames.length) {
|
||||
return;
|
||||
}
|
||||
@@ -103,7 +108,9 @@ module.exports = function (Groups) {
|
||||
const groups = await db.getSortedSetRange('groups:createtime', 0, -1);
|
||||
await Promise.all([
|
||||
Groups.leave(groups, uid),
|
||||
Groups.rejectMembership(groups, uid),
|
||||
Groups.rejectMembership(
|
||||
groups.filter(g => !Groups.isPrivilegeGroup(g)), uid
|
||||
),
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
@@ -361,9 +361,11 @@ module.exports = function (Messaging) {
|
||||
};
|
||||
|
||||
Messaging.leaveRooms = async (uid, roomIds) => {
|
||||
const isInRoom = await Promise.all(roomIds.map(roomId => Messaging.isUserInRoom(uid, roomId)));
|
||||
const isInRoom = await Messaging.isUserInRoom(uid, roomIds);
|
||||
roomIds = roomIds.filter((roomId, index) => isInRoom[index]);
|
||||
|
||||
if (!roomIds.length) {
|
||||
return;
|
||||
}
|
||||
const roomKeys = [
|
||||
...roomIds.map(roomId => `chat:room:${roomId}:uids`),
|
||||
...roomIds.map(roomId => `chat:room:${roomId}:owners`),
|
||||
|
||||
@@ -33,10 +33,15 @@ module.exports = function (User) {
|
||||
throw new Error('[[error:already-deleting]]');
|
||||
}
|
||||
deletesInProgress[uid] = 'user.delete';
|
||||
await deletePosts(callerUid, uid);
|
||||
await deleteTopics(callerUid, uid);
|
||||
await deleteUploads(callerUid, uid);
|
||||
await deleteQueued(uid);
|
||||
async function deletePostsTopics() {
|
||||
await deletePosts(callerUid, uid);
|
||||
await deleteTopics(callerUid, uid);
|
||||
}
|
||||
await Promise.all([
|
||||
deletePostsTopics(),
|
||||
deleteUploads(callerUid, uid),
|
||||
deleteQueued(uid),
|
||||
]);
|
||||
delete deletesInProgress[uid];
|
||||
};
|
||||
|
||||
@@ -90,9 +95,9 @@ module.exports = function (User) {
|
||||
throw new Error('[[error:already-deleting]]');
|
||||
}
|
||||
deletesInProgress[uid] = 'user.deleteAccount';
|
||||
|
||||
const isLocal = utils.isNumber(uid);
|
||||
await removeFromSortedSets(uid);
|
||||
const userData = await db.getObject(utils.isNumber(uid) ? `user:${uid}` : `userRemote:${uid}`);
|
||||
const userData = await db.getObject(isLocal ? `user:${uid}` : `userRemote:${uid}`);
|
||||
|
||||
if (!userData || !userData.username) {
|
||||
delete deletesInProgress[uid];
|
||||
@@ -100,9 +105,11 @@ module.exports = function (User) {
|
||||
}
|
||||
|
||||
await plugins.hooks.fire('static:user.delete', { uid: uid, userData: userData });
|
||||
await deleteVotes(uid);
|
||||
await deleteChats(uid);
|
||||
await User.auth.revokeAllSessions(uid);
|
||||
await Promise.all([
|
||||
deleteVotes(uid),
|
||||
deleteChats(uid),
|
||||
User.auth.revokeAllSessions(uid),
|
||||
]);
|
||||
|
||||
const keys = [
|
||||
`uid:${uid}:notifications:read`,
|
||||
@@ -143,7 +150,7 @@ module.exports = function (User) {
|
||||
|
||||
await Promise.all([
|
||||
db.sortedSetRemoveBulk(bulkRemove),
|
||||
utils.isNumber(uid) ? db.decrObjectField('global', 'userCount') : null,
|
||||
isLocal ? db.decrObjectField('global', 'userCount') : null,
|
||||
db.deleteAll(keys),
|
||||
db.setRemove('invitation:uids', uid),
|
||||
deleteUserIps(uid),
|
||||
@@ -156,13 +163,13 @@ module.exports = function (User) {
|
||||
flags.resolveFlag('user', uid, uid),
|
||||
User.reset.cleanByUid(uid),
|
||||
User.email.expireValidation(uid),
|
||||
activitypub.actors.remove(uid),
|
||||
!isLocal ? activitypub.actors.remove(uid) : null,
|
||||
]);
|
||||
await db.deleteAll([
|
||||
`followers:${uid}`, `following:${uid}`,
|
||||
`uid:${uid}:followed_tags`, `uid:${uid}:followed_tids`,
|
||||
`uid:${uid}:ignored_tids`,
|
||||
`${utils.isNumber(uid) ? 'user' : 'userRemote'}:${uid}`,
|
||||
`${isLocal ? 'user' : 'userRemote'}:${uid}`,
|
||||
]);
|
||||
delete deletesInProgress[uid];
|
||||
return userData;
|
||||
@@ -184,11 +191,10 @@ module.exports = function (User) {
|
||||
}
|
||||
|
||||
async function deleteVotes(uid) {
|
||||
const [upvotedPids, downvotedPids] = await Promise.all([
|
||||
db.getSortedSetRange(`uid:${uid}:upvote`, 0, -1),
|
||||
db.getSortedSetRange(`uid:${uid}:downvote`, 0, -1),
|
||||
]);
|
||||
const pids = _.uniq(upvotedPids.concat(downvotedPids).filter(Boolean));
|
||||
const upvoteDownvotePids = await db.getSortedSetRange([
|
||||
`uid:${uid}:upvote`, `uid:${uid}:downvote`,
|
||||
], 0, -1);
|
||||
const pids = _.uniq(upvoteDownvotePids).filter(Boolean);
|
||||
await async.eachSeries(pids, async (pid) => {
|
||||
await posts.unvote(pid, uid);
|
||||
});
|
||||
@@ -203,8 +209,10 @@ module.exports = function (User) {
|
||||
|
||||
async function deleteUserIps(uid) {
|
||||
const ips = await db.getSortedSetRange(`uid:${uid}:ip`, 0, -1);
|
||||
await db.sortedSetsRemove(ips.map(ip => `ip:${ip}:uid`), uid);
|
||||
await db.delete(`uid:${uid}:ip`);
|
||||
await Promise.all([
|
||||
db.sortedSetsRemove(ips.map(ip => `ip:${ip}:uid`), uid),
|
||||
db.delete(`uid:${uid}:ip`),
|
||||
]);
|
||||
}
|
||||
|
||||
async function deleteUserFromFollowers(uid) {
|
||||
|
||||
Reference in New Issue
Block a user