summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2024-09-24 18:29:02 +0900
committerGitHub <noreply@github.com>2024-09-24 18:29:02 +0900
commit6a1a2bef43af929f6def408428bd734ea2bff5c6 (patch)
tree65e843100f1d004c9f7986fd38319924f4cb6a65 /packages
parent:art: (diff)
downloadsharkey-6a1a2bef43af929f6def408428bd734ea2bff5c6.tar.gz
sharkey-6a1a2bef43af929f6def408428bd734ea2bff5c6.tar.bz2
sharkey-6a1a2bef43af929f6def408428bd734ea2bff5c6.zip
fix(backend): RBTの修正 (#14621)
* fix(backend): 絵文字の変換処理が不十分なのを修正 * enhance: リアクションバッファリングが無効になったら即bakeするように * attempt to fix test * fix
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/src/GlobalModule.ts4
-rw-r--r--packages/backend/src/core/GlobalEventService.ts2
-rw-r--r--packages/backend/src/core/MetaService.ts4
-rw-r--r--packages/backend/src/core/ReactionService.ts28
-rw-r--r--packages/backend/src/core/ReactionsBufferingService.ts51
-rw-r--r--packages/backend/src/core/entities/NoteEntityService.ts24
6 files changed, 73 insertions, 40 deletions
diff --git a/packages/backend/src/GlobalModule.ts b/packages/backend/src/GlobalModule.ts
index 0f69cf93a9..6ae8ccfbb3 100644
--- a/packages/backend/src/GlobalModule.ts
+++ b/packages/backend/src/GlobalModule.ts
@@ -126,8 +126,8 @@ const $meta: Provider = {
const { type, body } = obj.message as GlobalEvents['internal']['payload'];
switch (type) {
case 'metaUpdated': {
- for (const key in body) {
- (meta as any)[key] = (body as any)[key];
+ for (const key in body.after) {
+ (meta as any)[key] = (body.after as any)[key];
}
meta.proxyAccount = null; // joinなカラムは通常取ってこないので
break;
diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts
index 87aa70713e..03646ff566 100644
--- a/packages/backend/src/core/GlobalEventService.ts
+++ b/packages/backend/src/core/GlobalEventService.ts
@@ -241,7 +241,7 @@ export interface InternalEventTypes {
avatarDecorationCreated: MiAvatarDecoration;
avatarDecorationDeleted: MiAvatarDecoration;
avatarDecorationUpdated: MiAvatarDecoration;
- metaUpdated: MiMeta;
+ metaUpdated: { before?: MiMeta; after: MiMeta; };
followChannel: { userId: MiUser['id']; channelId: MiChannel['id']; };
unfollowChannel: { userId: MiUser['id']; channelId: MiChannel['id']; };
updateUserProfile: MiUserProfile;
diff --git a/packages/backend/src/core/MetaService.ts b/packages/backend/src/core/MetaService.ts
index ec630f804e..3d88d0aefe 100644
--- a/packages/backend/src/core/MetaService.ts
+++ b/packages/backend/src/core/MetaService.ts
@@ -52,7 +52,7 @@ export class MetaService implements OnApplicationShutdown {
switch (type) {
case 'metaUpdated': {
this.cache = { // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい
- ...body,
+ ...(body.after),
proxyAccount: null, // joinなカラムは通常取ってこないので
};
break;
@@ -141,7 +141,7 @@ export class MetaService implements OnApplicationShutdown {
});
}
- this.globalEventService.publishInternalEvent('metaUpdated', updated);
+ this.globalEventService.publishInternalEvent('metaUpdated', { before, after: updated });
return updated;
}
diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts
index 062d64f46b..6f9fe53937 100644
--- a/packages/backend/src/core/ReactionService.ts
+++ b/packages/backend/src/core/ReactionService.ts
@@ -337,10 +337,22 @@ export class ReactionService {
//#endregion
}
+ /**
+ * - 文字列タイプのレガシーな形式のリアクションを現在の形式に変換する
+ * - ローカルのリアクションのホストを `@.` にする(`decodeReaction()`の効果)
+ */
+ @bindThis
+ public convertLegacyReaction(reaction: string): string {
+ reaction = this.decodeReaction(reaction).reaction;
+ if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
+ return reaction;
+ }
+
// TODO: 廃止
/**
- * 文字列タイプのレガシーな形式のリアクションを現在の形式に変換しつつ、
- * データベース上には存在する「0個のリアクションがついている」という情報を削除する。
+ * - 文字列タイプのレガシーな形式のリアクションを現在の形式に変換する
+ * - ローカルのリアクションのホストを `@.` にする(`decodeReaction()`の効果)
+ * - データベース上には存在する「0個のリアクションがついている」という情報を削除する
*/
@bindThis
public convertLegacyReactions(reactions: MiNote['reactions']): MiNote['reactions'] {
@@ -353,10 +365,7 @@ export class ReactionService {
return count > 0;
})
.map(([reaction, count]) => {
- // unchecked indexed access
- const convertedReaction = legacies[reaction] as string | undefined;
-
- const key = this.decodeReaction(convertedReaction ?? reaction).reaction;
+ const key = this.convertLegacyReaction(reaction);
return [key, count] as const;
})
@@ -411,11 +420,4 @@ export class ReactionService {
host: undefined,
};
}
-
- @bindThis
- public convertLegacyReaction(reaction: string): string {
- reaction = this.decodeReaction(reaction).reaction;
- if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
- return reaction;
- }
}
diff --git a/packages/backend/src/core/ReactionsBufferingService.ts b/packages/backend/src/core/ReactionsBufferingService.ts
index b1a197feeb..b4207c5106 100644
--- a/packages/backend/src/core/ReactionsBufferingService.ts
+++ b/packages/backend/src/core/ReactionsBufferingService.ts
@@ -11,22 +11,48 @@ import { bindThis } from '@/decorators.js';
import type { MiUser, NotesRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import { PER_NOTE_REACTION_USER_PAIR_CACHE_MAX } from '@/const.js';
+import type { GlobalEvents } from '@/core/GlobalEventService.js';
+import type { OnApplicationShutdown } from '@nestjs/common';
const REDIS_DELTA_PREFIX = 'reactionsBufferDeltas';
const REDIS_PAIR_PREFIX = 'reactionsBufferPairs';
@Injectable()
-export class ReactionsBufferingService {
+export class ReactionsBufferingService implements OnApplicationShutdown {
constructor(
@Inject(DI.config)
private config: Config,
+ @Inject(DI.redisForSub)
+ private redisForSub: Redis.Redis,
+
@Inject(DI.redisForReactions)
private redisForReactions: Redis.Redis, // TODO: 専用のRedisインスタンスにする
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
) {
+ this.redisForSub.on('message', this.onMessage);
+ }
+
+ @bindThis
+ private async onMessage(_: string, data: string) {
+ const obj = JSON.parse(data);
+
+ if (obj.channel === 'internal') {
+ const { type, body } = obj.message as GlobalEvents['internal']['payload'];
+ switch (type) {
+ case 'metaUpdated': {
+ // リアクションバッファリングが有効→無効になったら即bake
+ if (body.before != null && body.before.enableReactionsBuffering && !body.after.enableReactionsBuffering) {
+ this.bake();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
}
@bindThis
@@ -159,4 +185,27 @@ export class ReactionsBufferingService {
.execute();
}
}
+
+ @bindThis
+ public mergeReactions(src: MiNote['reactions'], delta: Record<string, number>): MiNote['reactions'] {
+ const reactions = { ...src };
+ for (const [name, count] of Object.entries(delta)) {
+ if (reactions[name] != null) {
+ reactions[name] += count;
+ } else {
+ reactions[name] = count;
+ }
+ }
+ return reactions;
+ }
+
+ @bindThis
+ public dispose(): void {
+ this.redisForSub.off('message', this.onMessage);
+ }
+
+ @bindThis
+ public onApplicationShutdown(signal?: string | undefined): void {
+ this.dispose();
+ }
}
diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts
index 7e64b9fc8d..c64e9151a7 100644
--- a/packages/backend/src/core/entities/NoteEntityService.ts
+++ b/packages/backend/src/core/entities/NoteEntityService.ts
@@ -16,25 +16,12 @@ import { bindThis } from '@/decorators.js';
import { DebounceLoader } from '@/misc/loader.js';
import { IdService } from '@/core/IdService.js';
import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
-import { MetaService } from '@/core/MetaService.js';
import type { OnModuleInit } from '@nestjs/common';
import type { CustomEmojiService } from '../CustomEmojiService.js';
import type { ReactionService } from '../ReactionService.js';
import type { UserEntityService } from './UserEntityService.js';
import type { DriveFileEntityService } from './DriveFileEntityService.js';
-function mergeReactions(src: Record<string, number>, delta: Record<string, number>) {
- const reactions = { ...src };
- for (const [name, count] of Object.entries(delta)) {
- if (reactions[name] != null) {
- reactions[name] += count;
- } else {
- reactions[name] = count;
- }
- }
- return reactions;
-}
-
@Injectable()
export class NoteEntityService implements OnModuleInit {
private userEntityService: UserEntityService;
@@ -329,12 +316,7 @@ export class NoteEntityService implements OnModuleInit {
: this.meta.enableReactionsBuffering
? await this.reactionsBufferingService.get(note.id)
: { deltas: {}, pairs: [] };
- const reactions = mergeReactions(this.reactionService.convertLegacyReactions(note.reactions), bufferedReactions.deltas ?? {});
- for (const [name, count] of Object.entries(reactions)) {
- if (count <= 0) {
- delete reactions[name];
- }
- }
+ const reactions = this.reactionService.convertLegacyReactions(this.reactionsBufferingService.mergeReactions(note.reactions, bufferedReactions.deltas ?? {}));
const reactionAndUserPairCache = note.reactionAndUserPairCache.concat(bufferedReactions.pairs.map(x => x.join('/')));
@@ -451,7 +433,7 @@ export class NoteEntityService implements OnModuleInit {
for (const note of notes) {
if (note.renote && (note.text == null && note.fileIds.length === 0)) { // pure renote
- const reactionsCount = Object.values(mergeReactions(note.renote.reactions, bufferedReactions?.get(note.renote.id)?.deltas ?? {})).reduce((a, b) => a + b, 0);
+ const reactionsCount = Object.values(this.reactionsBufferingService.mergeReactions(note.renote.reactions, bufferedReactions?.get(note.renote.id)?.deltas ?? {})).reduce((a, b) => a + b, 0);
if (reactionsCount === 0) {
myReactionsMap.set(note.renote.id, null);
} else if (reactionsCount <= note.renote.reactionAndUserPairCache.length + (bufferedReactions?.get(note.renote.id)?.pairs.length ?? 0)) {
@@ -467,7 +449,7 @@ export class NoteEntityService implements OnModuleInit {
}
} else {
if (note.id < oldId) {
- const reactionsCount = Object.values(mergeReactions(note.reactions, bufferedReactions?.get(note.id)?.deltas ?? {})).reduce((a, b) => a + b, 0);
+ const reactionsCount = Object.values(this.reactionsBufferingService.mergeReactions(note.reactions, bufferedReactions?.get(note.id)?.deltas ?? {})).reduce((a, b) => a + b, 0);
if (reactionsCount === 0) {
myReactionsMap.set(note.id, null);
} else if (reactionsCount <= note.reactionAndUserPairCache.length + (bufferedReactions?.get(note.id)?.pairs.length ?? 0)) {