Skip to content

Commit

Permalink
リアクション作成のパフォーマンスを改善 Resolve #2467
Browse files Browse the repository at this point in the history
  • Loading branch information
mei23 authored and fs5m8 committed Aug 16, 2023
1 parent 5ce3038 commit 90abd62
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 21 deletions.
6 changes: 4 additions & 2 deletions src/misc/is-duplicate-key-value-error.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export function isDuplicateKeyValueError(e: Error): boolean {
return e.message.startsWith('duplicate key value');
import { QueryFailedError } from 'typeorm';

export function isDuplicateKeyValueError(e: unknown | Error): boolean {
return e instanceof QueryFailedError && e.driverError.code === '23505';
}
4 changes: 2 additions & 2 deletions src/models/entities/note-reaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class NoteReaction {
onDelete: 'CASCADE'
})
@JoinColumn()
public user: User | null;
public user?: User | null;

@Index()
@Column(id())
Expand All @@ -33,7 +33,7 @@ export class NoteReaction {
onDelete: 'CASCADE'
})
@JoinColumn()
public note: Note | null;
public note?: Note | null;

@Column('varchar', {
length: 260
Expand Down
9 changes: 8 additions & 1 deletion src/remote/activitypub/kernel/like.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ export default async (actor: IRemoteUser, activity: ILike) => {

await extractEmojis(activity.tag || [], actor.host).catch(() => null);

await create(actor, note, activity._misskey_reaction || activity.content || activity.name);
await create(actor, note, activity._misskey_reaction || activity.content || activity.name).catch(e => {
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') {
return 'skip: already reacted';
} else {
throw e;
}
});

return `ok`;
};
43 changes: 27 additions & 16 deletions src/services/note/reaction/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,45 @@ import { perUserReactionsChart } from '../../chart';
import { genId } from '../../../misc/gen-id';
import { createNotification } from '../../create-notification';
import deleteReaction from './delete';
import { NoteReaction } from '../../../models/entities/note-reaction';
import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
import { IdentifiableError } from '../../../misc/identifiable-error';

export default async (user: User, note: Note, reaction?: string) => {

reaction = await toDbReaction(reaction, user.host);

const exist = await NoteReactions.findOne({
const inserted: NoteReaction = {
id: genId(),
createdAt: new Date(),
noteId: note.id,
userId: user.id,
});
reaction,
};

// Create reaction
try {
await NoteReactions.insert(inserted);
} catch (e) {
if (isDuplicateKeyValueError(e)) {
const exists = await NoteReactions.findOneOrFail({
noteId: note.id,
userId: user.id,
});

if (exist) {
if (exist.reaction !== reaction) {
// 別のリアクションがすでにされていたら置き換える
await deleteReaction(user, note);
if (exists.reaction !== reaction) {
// 別のリアクションがすでにされていたら置き換える
await deleteReaction(user, note);
await NoteReactions.insert(inserted);
} else {
// 同じリアクションがすでにされていたらエラー
throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298');
}
} else {
// 同じリアクションがすでにされていたら何もしない
return;
throw e;
}
}

// Create reaction
const inserted = await NoteReactions.save({
id: genId(),
createdAt: new Date(),
noteId: note.id,
userId: user.id,
reaction
});

// Increment reactions count
const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`;
Expand Down

0 comments on commit 90abd62

Please sign in to comment.