mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	perf(backend): improve streaming api performance (#12033)
* wip * Update NoteEntityService.ts * wip * wip * wip * wip
This commit is contained in:
		
							parent
							
								
									329830e2c3
								
							
						
					
					
						commit
						3f4ee98405
					
				
					 9 changed files with 58 additions and 115 deletions
				
			
		| 
						 | 
				
			
			@ -577,7 +577,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			// Pack the note
 | 
			
		||||
			const noteObj = await this.noteEntityService.pack(note);
 | 
			
		||||
			const noteObj = await this.noteEntityService.pack(note, null, { skipHide: true });
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishNotesStream(noteObj);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepos
 | 
			
		|||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { isNotNull } from '@/misc/is-not-null.js';
 | 
			
		||||
import { DebounceLoader } from '@/misc/loader.js';
 | 
			
		||||
import { IdService } from '@/core/IdService.js';
 | 
			
		||||
import type { OnModuleInit } from '@nestjs/common';
 | 
			
		||||
import type { CustomEmojiService } from '../CustomEmojiService.js';
 | 
			
		||||
import type { ReactionService } from '../ReactionService.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,7 @@ export class NoteEntityService implements OnModuleInit {
 | 
			
		|||
	private driveFileEntityService: DriveFileEntityService;
 | 
			
		||||
	private customEmojiService: CustomEmojiService;
 | 
			
		||||
	private reactionService: ReactionService;
 | 
			
		||||
	private idService: IdService;
 | 
			
		||||
	private noteLoader = new DebounceLoader(this.findNoteOrFail);
 | 
			
		||||
 | 
			
		||||
	constructor(
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +68,7 @@ export class NoteEntityService implements OnModuleInit {
 | 
			
		|||
		this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService');
 | 
			
		||||
		this.customEmojiService = this.moduleRef.get('CustomEmojiService');
 | 
			
		||||
		this.reactionService = this.moduleRef.get('ReactionService');
 | 
			
		||||
		this.idService = this.moduleRef.get('IdService');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
| 
						 | 
				
			
			@ -167,11 +170,11 @@ export class NoteEntityService implements OnModuleInit {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	private async populateMyReaction(note: MiNote, meId: MiUser['id'], _hint_?: {
 | 
			
		||||
	public async populateMyReaction(noteId: MiNote['id'], meId: MiUser['id'], _hint_?: {
 | 
			
		||||
		myReactions: Map<MiNote['id'], MiNoteReaction | null>;
 | 
			
		||||
	}) {
 | 
			
		||||
		if (_hint_?.myReactions) {
 | 
			
		||||
			const reaction = _hint_.myReactions.get(note.id);
 | 
			
		||||
			const reaction = _hint_.myReactions.get(noteId);
 | 
			
		||||
			if (reaction) {
 | 
			
		||||
				return this.reactionService.convertLegacyReaction(reaction.reaction);
 | 
			
		||||
			} else if (reaction === null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -181,13 +184,13 @@ export class NoteEntityService implements OnModuleInit {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// パフォーマンスのためノートが作成されてから2秒以上経っていない場合はリアクションを取得しない
 | 
			
		||||
		if (note.createdAt.getTime() + 2000 > Date.now()) {
 | 
			
		||||
		if (this.idService.parse(noteId).date.getTime() + 2000 > Date.now()) {
 | 
			
		||||
			return undefined;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const reaction = await this.noteReactionsRepository.findOneBy({
 | 
			
		||||
			userId: meId,
 | 
			
		||||
			noteId: note.id,
 | 
			
		||||
			noteId: noteId,
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		if (reaction) {
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +358,7 @@ export class NoteEntityService implements OnModuleInit {
 | 
			
		|||
				poll: note.hasPoll ? this.populatePoll(note, meId) : undefined,
 | 
			
		||||
 | 
			
		||||
				...(meId ? {
 | 
			
		||||
					myReaction: this.populateMyReaction(note, meId, options?._hint_),
 | 
			
		||||
					myReaction: this.populateMyReaction(note.id, meId, options?._hint_),
 | 
			
		||||
				} : {}),
 | 
			
		||||
			} : {}),
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,19 +38,6 @@ class ChannelChannel extends Channel {
 | 
			
		|||
	private async onNote(note: Packed<'Note'>) {
 | 
			
		||||
		if (note.channelId !== this.channelId) return;
 | 
			
		||||
 | 
			
		||||
		// リプライなら再pack
 | 
			
		||||
		if (note.replyId != null) {
 | 
			
		||||
			note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		// Renoteなら再pack
 | 
			
		||||
		if (note.renoteId != null) {
 | 
			
		||||
			note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 | 
			
		||||
		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 | 
			
		||||
		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +45,11 @@ class ChannelChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,19 +52,6 @@ class GlobalTimelineChannel extends Channel {
 | 
			
		|||
		if (note.visibility !== 'public') return;
 | 
			
		||||
		if (note.channelId != null) return;
 | 
			
		||||
 | 
			
		||||
		// リプライなら再pack
 | 
			
		||||
		if (note.replyId != null) {
 | 
			
		||||
			note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		// Renoteなら再pack
 | 
			
		||||
		if (note.renoteId != null) {
 | 
			
		||||
			note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 関係ない返信は除外
 | 
			
		||||
		if (note.reply && !this.following[note.userId]?.withReplies) {
 | 
			
		||||
			const reply = note.reply;
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +71,11 @@ class GlobalTimelineChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,13 +43,6 @@ class HashtagChannel extends Channel {
 | 
			
		|||
		const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag))));
 | 
			
		||||
		if (!matched) return;
 | 
			
		||||
 | 
			
		||||
		// Renoteなら再pack
 | 
			
		||||
		if (note.renoteId != null) {
 | 
			
		||||
			note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 | 
			
		||||
		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 | 
			
		||||
		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +50,11 @@ class HashtagChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,27 +51,10 @@ class HomeTimelineChannel extends Channel {
 | 
			
		|||
		// Ignore notes from instances the user has muted
 | 
			
		||||
		if (isInstanceMuted(note, new Set<string>(this.userProfile!.mutedInstances ?? []))) return;
 | 
			
		||||
 | 
			
		||||
		if (['followers', 'specified'].includes(note.visibility)) {
 | 
			
		||||
			note = await this.noteEntityService.pack(note.id, this.user!, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			if (note.isHidden) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// リプライなら再pack
 | 
			
		||||
			if (note.replyId != null) {
 | 
			
		||||
				note.reply = await this.noteEntityService.pack(note.replyId, this.user!, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			// Renoteなら再pack
 | 
			
		||||
			if (note.renoteId != null) {
 | 
			
		||||
				note.renote = await this.noteEntityService.pack(note.renoteId, this.user!, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		if (note.visibility === 'followers') {
 | 
			
		||||
			if (!Object.hasOwn(this.following, note.userId)) return;
 | 
			
		||||
		} else if (note.visibility === 'specified') {
 | 
			
		||||
			if (!note.visibleUserIds!.includes(this.user!.id)) return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 関係ない返信は除外
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +73,11 @@ class HomeTimelineChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,27 +62,10 @@ class HybridTimelineChannel extends Channel {
 | 
			
		|||
			(note.channelId != null && this.followingChannels.has(note.channelId))
 | 
			
		||||
		)) return;
 | 
			
		||||
 | 
			
		||||
		if (['followers', 'specified'].includes(note.visibility)) {
 | 
			
		||||
			note = await this.noteEntityService.pack(note.id, this.user!, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			if (note.isHidden) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// リプライなら再pack
 | 
			
		||||
			if (note.replyId != null) {
 | 
			
		||||
				note.reply = await this.noteEntityService.pack(note.replyId, this.user!, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			// Renoteなら再pack
 | 
			
		||||
			if (note.renoteId != null) {
 | 
			
		||||
				note.renote = await this.noteEntityService.pack(note.renoteId, this.user!, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		if (note.visibility === 'followers') {
 | 
			
		||||
			if (!Object.hasOwn(this.following, note.userId)) return;
 | 
			
		||||
		} else if (note.visibility === 'specified') {
 | 
			
		||||
			if (!note.visibleUserIds!.includes(this.user!.id)) return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Ignore notes from instances the user has muted
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +87,11 @@ class HybridTimelineChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,19 +54,6 @@ class LocalTimelineChannel extends Channel {
 | 
			
		|||
		if (note.visibility !== 'public') return;
 | 
			
		||||
		if (note.channelId != null && !this.followingChannels.has(note.channelId)) return;
 | 
			
		||||
 | 
			
		||||
		// リプライなら再pack
 | 
			
		||||
		if (note.replyId != null) {
 | 
			
		||||
			note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		// Renoteなら再pack
 | 
			
		||||
		if (note.renoteId != null) {
 | 
			
		||||
			note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 関係ない返信は除外
 | 
			
		||||
		if (note.reply && this.user && !this.following[note.userId]?.withReplies && !this.withReplies) {
 | 
			
		||||
			const reply = note.reply;
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +70,11 @@ class LocalTimelineChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,27 +82,10 @@ class UserListChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (!Object.hasOwn(this.membershipsMap, note.userId)) return;
 | 
			
		||||
 | 
			
		||||
		if (['followers', 'specified'].includes(note.visibility)) {
 | 
			
		||||
			note = await this.noteEntityService.pack(note.id, this.user, {
 | 
			
		||||
				detail: true,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			if (note.isHidden) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// リプライなら再pack
 | 
			
		||||
			if (note.replyId != null) {
 | 
			
		||||
				note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			// Renoteなら再pack
 | 
			
		||||
			if (note.renoteId != null) {
 | 
			
		||||
				note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
 | 
			
		||||
					detail: true,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		if (note.visibility === 'followers') {
 | 
			
		||||
			if (!Object.hasOwn(this.following, note.userId)) return;
 | 
			
		||||
		} else if (note.visibility === 'specified') {
 | 
			
		||||
			if (!note.visibleUserIds!.includes(this.user!.id)) return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 関係ない返信は除外
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +102,13 @@ class UserListChannel extends Channel {
 | 
			
		|||
 | 
			
		||||
		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 | 
			
		||||
 | 
			
		||||
		if (this.user && note.renoteId && !note.text) {
 | 
			
		||||
			const myRenoteReaction = await this.noteEntityService.populateMyReaction(note.renoteId, this.user.id);
 | 
			
		||||
			note.renote!.myReaction = myRenoteReaction;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.connection.cacheNote(note);
 | 
			
		||||
 | 
			
		||||
		this.send('note', note);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue