perf: single transaction for archiving messages

This commit is contained in:
Isaac 2025-02-12 21:08:22 +00:00
parent 440a9b745c
commit b5384bca6c
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33

View File

@ -31,48 +31,66 @@ module.exports = class TicketArchiver {
} }
} }
const channels = message.mentions.channels;
const channels = [...message.mentions.channels.values()];
const members = [...message.mentions.members.values()]; const members = [...message.mentions.members.values()];
const roles = [...message.mentions.roles.values()]; const roles = [...message.mentions.roles.values()];
if (message.member) { // const ticket = { connect: { id: ticketId } };
members.push(message.member);
roles.push(hoistedRole(message.member));
} else {
this.client.log.warn('Message member does not exist');
await this.client.prisma.archivedUser.upsert({
create: {},
update: {},
where: {
ticketId_userId: {
ticketId,
userId: 'default',
},
},
});
}
for (const role of roles) {
const data = {
colour: role.hexColor.slice(1),
name: role.name,
roleId: role.id,
ticket: { connect: { id: ticketId } },
};
await this.client.prisma.archivedRole.upsert({
create: data,
update: data,
where: {
ticketId_roleId: {
roleId: role.id,
ticketId,
},
},
});
}
const worker = await reusable('crypto'); const worker = await reusable('crypto');
try { try {
const queries = [];
if (message.member) {
members.push(message.member);
roles.push(hoistedRole(message.member));
} else {
this.client.log.warn('Message member does not exist');
queries.push(
this.client.prisma.archivedUser.upsert({
create: {
ticketId,
userId: 'default',
},
select: { ticketId: true }, // default is to return all scalar fields
update: {},
where: {
ticketId_userId: {
ticketId,
userId: 'default',
},
},
}),
);
}
for (const role of roles) {
const data = {
colour: role.hexColor.slice(1),
name: role.name,
};
queries.push(
this.client.prisma.archivedRole.upsert({
create: {
...data,
roleId: role.id,
ticketId,
},
select: { ticketId: true },
update: data,
where: {
ticketId_roleId: {
roleId: role.id,
ticketId,
},
},
}),
);
}
for (const member of members) { for (const member of members) {
const data = { const data = {
avatar: member.avatar || member.user.avatar, // TODO: save avatar in user/avatars/ avatar: member.avatar || member.user.avatar, // TODO: save avatar in user/avatars/
@ -80,79 +98,86 @@ module.exports = class TicketArchiver {
discriminator: member.user.discriminator, discriminator: member.user.discriminator,
displayName: member.displayName ? await worker.encrypt(member.displayName) : null, displayName: member.displayName ? await worker.encrypt(member.displayName) : null,
roleId: !!member && hoistedRole(member).id, roleId: !!member && hoistedRole(member).id,
ticketId,
userId: member.user.id,
username: await worker.encrypt(member.user.username), username: await worker.encrypt(member.user.username),
}; };
await this.client.prisma.archivedUser.upsert({ queries.push(
create: data, this.client.prisma.archivedUser.upsert({
update: data, create: {
where: { ...data,
ticketId_userId: {
ticketId, ticketId,
userId: member.user.id, userId: member.user.id,
}, },
}, select: { ticketId: true },
}); update: data,
where: {
ticketId_userId: {
ticketId,
userId: member.user.id,
},
},
}),
);
} }
let reference; for (const channel of channels) {
if (message.reference) reference = await message.fetchReference(); const data = {
channelId: channel.id,
const messageD = { name: channel.name,
author: { ticketId,
connect: { };
ticketId_userId: { queries.push(
ticketId, this.client.prisma.archivedChannel.upsert({
userId: message.author?.id || 'default', create: data,
select: { ticketId: true },
update: data,
where: {
ticketId_channelId: {
channelId: channel.id,
ticketId,
},
}, },
}, }),
}, );
}
const data = {
// author: {
// connect: {
// ticketId_userId: {
// ticketId,
// userId: message.author?.id || 'default',
// },
// },
// },
content: await worker.encrypt( content: await worker.encrypt(
JSON.stringify({ JSON.stringify({
attachments: [...message.attachments.values()], attachments: [...message.attachments.values()],
components: [...message.components.values()], components: [...message.components.values()],
content: message.content, content: message.content,
embeds: message.embeds.map(embed => ({ ...embed })), embeds: message.embeds.map(embed => ({ ...embed })),
reference: reference ? reference.id : null, reference: message.reference?.messageId ?? null,
}), }),
), ),
createdAt: message.createdAt, createdAt: message.createdAt,
edited: !!message.editedAt, edited: !!message.editedAt,
external, external,
id: message.id,
}; };
return await this.client.prisma.ticket.update({ queries.push(
data: { this.client.prisma.archivedMessage.upsert({
archivedChannels: { create: {
upsert: channels.map(channel => { ...data,
const data = { authorId: message.author?.id || 'default',
channelId: channel.id, id: message.id,
name: channel.name, ticketId,
};
return {
create: data,
update: data,
where: {
ticketId_channelId: {
channelId: channel.id,
ticketId,
},
},
};
}),
}, },
archivedMessages: { select: { ticketId: true },
upsert: { update: data,
create: messageD, where: { id: message.id },
update: messageD, }),
where: { id: message.id }, );
},
}, return await this.client.prisma.$transaction(queries);
},
where: { id: ticketId },
});
} finally { } finally {
await worker.terminate(); await worker.terminate();
} }