mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
fix note/user accumulation in NoteEntityService.packMany, improving performance and avoiding extra sub-packs and fetches
This commit is contained in:
parent
c9884a74fc
commit
223cdc9ea9
1 changed files with 48 additions and 25 deletions
|
@ -425,6 +425,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
polls: Map<string, MiPoll>;
|
polls: Map<string, MiPoll>;
|
||||||
pollVotes: Map<string, Map<string, MiPollVote[]>>;
|
pollVotes: Map<string, Map<string, MiPollVote[]>>;
|
||||||
channels: Map<string, MiChannel>;
|
channels: Map<string, MiChannel>;
|
||||||
|
notes: Map<string, MiNote>;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
): Promise<Packed<'Note'>> {
|
): Promise<Packed<'Note'>> {
|
||||||
|
@ -517,14 +518,14 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
clippedCount: note.clippedCount,
|
clippedCount: note.clippedCount,
|
||||||
processErrors: note.processErrors,
|
processErrors: note.processErrors,
|
||||||
|
|
||||||
reply: note.replyId ? this.pack(note.reply ?? note.replyId, me, {
|
reply: note.replyId ? this.pack(note.reply ?? opts._hint_?.notes.get(note.replyId) ?? note.replyId, me, {
|
||||||
detail: false,
|
detail: false,
|
||||||
skipHide: opts.skipHide,
|
skipHide: opts.skipHide,
|
||||||
withReactionAndUserPairCache: opts.withReactionAndUserPairCache,
|
withReactionAndUserPairCache: opts.withReactionAndUserPairCache,
|
||||||
_hint_: options?._hint_,
|
_hint_: options?._hint_,
|
||||||
}) : undefined,
|
}) : undefined,
|
||||||
|
|
||||||
renote: note.renoteId ? this.pack(note.renote ?? note.renoteId, me, {
|
renote: note.renoteId ? this.pack(note.renote ?? opts._hint_?.notes.get(note.renoteId) ?? note.renoteId, me, {
|
||||||
detail: true,
|
detail: true,
|
||||||
skipHide: opts.skipHide,
|
skipHide: opts.skipHide,
|
||||||
withReactionAndUserPairCache: opts.withReactionAndUserPairCache,
|
withReactionAndUserPairCache: opts.withReactionAndUserPairCache,
|
||||||
|
@ -556,16 +557,16 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
) {
|
) {
|
||||||
if (notes.length === 0) return [];
|
if (notes.length === 0) return [];
|
||||||
|
|
||||||
const targetNotes: MiNote[] = [];
|
const targetNotesMap = new Map<string, MiNote>();
|
||||||
const targetNotesToFetch: string[] = [];
|
const targetNotesToFetch : string[] = [];
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
if (isPureRenote(note)) {
|
if (isPureRenote(note)) {
|
||||||
// we may need to fetch 'my reaction' for renote target.
|
// we may need to fetch 'my reaction' for renote target.
|
||||||
if (note.renote) {
|
if (note.renote) {
|
||||||
targetNotes.push(note.renote);
|
targetNotesMap.set(note.renote.id, note.renote);
|
||||||
if (note.renote.reply) {
|
if (note.renote.reply) {
|
||||||
// idem if the renote is also a reply.
|
// idem if the renote is also a reply.
|
||||||
targetNotes.push(note.renote.reply);
|
targetNotesMap.set(note.renote.reply.id, note.renote.reply);
|
||||||
}
|
}
|
||||||
} else if (options?.detail) {
|
} else if (options?.detail) {
|
||||||
targetNotesToFetch.push(note.renoteId);
|
targetNotesToFetch.push(note.renoteId);
|
||||||
|
@ -573,12 +574,19 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
} else {
|
} else {
|
||||||
if (note.reply) {
|
if (note.reply) {
|
||||||
// idem for OP of a regular reply.
|
// idem for OP of a regular reply.
|
||||||
targetNotes.push(note.reply);
|
targetNotesMap.set(note.reply.id, note.reply);
|
||||||
} else if (note.replyId && options?.detail) {
|
} else if (note.replyId && options?.detail) {
|
||||||
targetNotesToFetch.push(note.replyId);
|
targetNotesToFetch.push(note.replyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
targetNotes.push(note);
|
targetNotesMap.set(note.id, note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't fetch notes that were added by ID and then found inline in another note.
|
||||||
|
for (let i = targetNotesToFetch.length - 1; i >= 0; i--) {
|
||||||
|
if (targetNotesMap.has(targetNotesToFetch[i])) {
|
||||||
|
targetNotesToFetch.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,36 +618,50 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
channel: true,
|
channel: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
targetNotes.push(...newNotes);
|
|
||||||
|
for (const note of newNotes) {
|
||||||
|
targetNotesMap.set(note.id, note);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileIds = notes.map(n => [n.fileIds, n.renote?.fileIds, n.reply?.fileIds]).flat(2).filter(x => x != null);
|
const targetNotes = Array.from(targetNotesMap.values());
|
||||||
const users = [
|
const noteIds = Array.from(targetNotesMap.keys());
|
||||||
...notes.map(({ user, userId }) => user ?? userId),
|
|
||||||
...notes.map(({ reply, replyUserId }) => reply?.user ?? replyUserId).filter(x => x != null),
|
|
||||||
...notes.map(({ renote, renoteUserId }) => renote?.user ?? renoteUserId).filter(x => x != null),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Recursively add all mentioned users from all notes + replies + renotes
|
const usersMap = new Map<string, MiUser | string>();
|
||||||
const allMentionedUsers = targetNotes.reduce((users, note) => {
|
const allUsers = notes.flatMap(note => [
|
||||||
for (const user of note.mentions) {
|
note.user ?? note.userId,
|
||||||
users.add(user);
|
note.reply?.user ?? note.replyUserId,
|
||||||
|
note.renote?.user ?? note.renoteUserId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
for (const user of allUsers) {
|
||||||
|
if (!user) continue;
|
||||||
|
|
||||||
|
if (typeof(user) === 'object') {
|
||||||
|
// ID -> Entity
|
||||||
|
usersMap.set(user.id, user);
|
||||||
|
} else if (!usersMap.has(user)) {
|
||||||
|
// ID -> ID
|
||||||
|
usersMap.set(user, user);
|
||||||
}
|
}
|
||||||
return users;
|
}
|
||||||
}, new Set<string>());
|
|
||||||
|
const users = Array.from(usersMap.values());
|
||||||
|
const userIds = Array.from(usersMap.keys());
|
||||||
|
|
||||||
|
const fileIds = new Set(targetNotes.flatMap(n => n.fileIds));
|
||||||
|
const mentionedUsers = new Set(targetNotes.flatMap(note => note.mentions));
|
||||||
|
|
||||||
const userIds = Array.from(new Set(users.map(u => typeof(u) === 'string' ? u : u.id)));
|
|
||||||
const noteIds = Array.from(new Set(targetNotes.map(n => n.id)));
|
|
||||||
const [{ bufferedReactions, myReactionsMap }, packedFiles, packedUsers, mentionHandles, userFollowings, userBlockers, polls, pollVotes, channels] = await Promise.all([
|
const [{ bufferedReactions, myReactionsMap }, packedFiles, packedUsers, mentionHandles, userFollowings, userBlockers, polls, pollVotes, channels] = await Promise.all([
|
||||||
// bufferedReactions & myReactionsMap
|
// bufferedReactions & myReactionsMap
|
||||||
this.getReactions(targetNotes, me),
|
this.getReactions(targetNotes, me),
|
||||||
// packedFiles
|
// packedFiles
|
||||||
this.driveFileEntityService.packManyByIdsMap(fileIds),
|
this.driveFileEntityService.packManyByIdsMap(Array.from(fileIds)),
|
||||||
// packedUsers
|
// packedUsers
|
||||||
this.userEntityService.packMany(users, me)
|
this.userEntityService.packMany(users, me)
|
||||||
.then(users => new Map(users.map(u => [u.id, u]))),
|
.then(users => new Map(users.map(u => [u.id, u]))),
|
||||||
// mentionHandles
|
// mentionHandles
|
||||||
this.getUserHandles(Array.from(allMentionedUsers)),
|
this.getUserHandles(Array.from(mentionedUsers)),
|
||||||
// userFollowings
|
// userFollowings
|
||||||
this.cacheService.getUserFollowings(userIds),
|
this.cacheService.getUserFollowings(userIds),
|
||||||
// userBlockers
|
// userBlockers
|
||||||
|
@ -682,6 +704,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
polls,
|
polls,
|
||||||
pollVotes,
|
pollVotes,
|
||||||
channels,
|
channels,
|
||||||
|
notes: new Map(targetNotes.map(n => [n.id, n])),
|
||||||
},
|
},
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue