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,17 +31,31 @@ 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()];
// const ticket = { connect: { id: ticketId } };
const worker = await reusable('crypto');
try {
const queries = [];
if (message.member) { if (message.member) {
members.push(message.member); members.push(message.member);
roles.push(hoistedRole(message.member)); roles.push(hoistedRole(message.member));
} else { } else {
this.client.log.warn('Message member does not exist'); this.client.log.warn('Message member does not exist');
await this.client.prisma.archivedUser.upsert({ queries.push(
create: {}, this.client.prisma.archivedUser.upsert({
create: {
ticketId,
userId: 'default',
},
select: { ticketId: true }, // default is to return all scalar fields
update: {}, update: {},
where: { where: {
ticketId_userId: { ticketId_userId: {
@ -49,18 +63,23 @@ module.exports = class TicketArchiver {
userId: 'default', userId: 'default',
}, },
}, },
}); }),
);
} }
for (const role of roles) { for (const role of roles) {
const data = { const data = {
colour: role.hexColor.slice(1), colour: role.hexColor.slice(1),
name: role.name, name: role.name,
roleId: role.id,
ticket: { connect: { id: ticketId } },
}; };
await this.client.prisma.archivedRole.upsert({ queries.push(
create: data, this.client.prisma.archivedRole.upsert({
create: {
...data,
roleId: role.id,
ticketId,
},
select: { ticketId: true },
update: data, update: data,
where: { where: {
ticketId_roleId: { ticketId_roleId: {
@ -68,11 +87,10 @@ module.exports = class TicketArchiver {
ticketId, ticketId,
}, },
}, },
}); }),
);
} }
const worker = await reusable('crypto');
try {
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,12 +98,16 @@ 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({
create: {
...data,
ticketId,
userId: member.user.id,
},
select: { ticketId: true },
update: data, update: data,
where: { where: {
ticketId_userId: { ticketId_userId: {
@ -93,46 +115,20 @@ module.exports = class TicketArchiver {
userId: member.user.id, userId: member.user.id,
}, },
}, },
}); }),
);
} }
let reference; for (const channel of channels) {
if (message.reference) reference = await message.fetchReference();
const messageD = {
author: {
connect: {
ticketId_userId: {
ticketId,
userId: message.author?.id || 'default',
},
},
},
content: await worker.encrypt(
JSON.stringify({
attachments: [...message.attachments.values()],
components: [...message.components.values()],
content: message.content,
embeds: message.embeds.map(embed => ({ ...embed })),
reference: reference ? reference.id : null,
}),
),
createdAt: message.createdAt,
edited: !!message.editedAt,
external,
id: message.id,
};
return await this.client.prisma.ticket.update({
data: {
archivedChannels: {
upsert: channels.map(channel => {
const data = { const data = {
channelId: channel.id, channelId: channel.id,
name: channel.name, name: channel.name,
ticketId,
}; };
return { queries.push(
this.client.prisma.archivedChannel.upsert({
create: data, create: data,
select: { ticketId: true },
update: data, update: data,
where: { where: {
ticketId_channelId: { ticketId_channelId: {
@ -140,19 +136,48 @@ module.exports = class TicketArchiver {
ticketId, ticketId,
}, },
}, },
};
}), }),
);
}
const data = {
// author: {
// connect: {
// ticketId_userId: {
// ticketId,
// userId: message.author?.id || 'default',
// },
// },
// },
content: await worker.encrypt(
JSON.stringify({
attachments: [...message.attachments.values()],
components: [...message.components.values()],
content: message.content,
embeds: message.embeds.map(embed => ({ ...embed })),
reference: message.reference?.messageId ?? null,
}),
),
createdAt: message.createdAt,
edited: !!message.editedAt,
external,
};
queries.push(
this.client.prisma.archivedMessage.upsert({
create: {
...data,
authorId: message.author?.id || 'default',
id: message.id,
ticketId,
}, },
archivedMessages: { select: { ticketId: true },
upsert: { update: data,
create: messageD,
update: messageD,
where: { id: message.id }, where: { id: message.id },
}, }),
}, );
},
where: { id: ticketId }, return await this.client.prisma.$transaction(queries);
});
} finally { } finally {
await worker.terminate(); await worker.terminate();
} }