summaryrefslogtreecommitdiff
path: root/packages/backend/src/core/NoteDeleteService.ts
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2024-10-13 18:11:16 -0400
committerHazelnoot <acomputerdog@gmail.com>2024-10-15 14:17:19 -0400
commit93cf2f9045e4af485a29690313b7d74b0f54cab6 (patch)
tree607b7952d47c687b6d4cd236557969afeab5be9f /packages/backend/src/core/NoteDeleteService.ts
parentupdate latest note in background (don't await the result) (diff)
downloadsharkey-93cf2f9045e4af485a29690313b7d74b0f54cab6.tar.gz
sharkey-93cf2f9045e4af485a29690313b7d74b0f54cab6.tar.bz2
sharkey-93cf2f9045e4af485a29690313b7d74b0f54cab6.zip
factor out latest_note logic into LatestNoteService
Diffstat (limited to 'packages/backend/src/core/NoteDeleteService.ts')
-rw-r--r--packages/backend/src/core/NoteDeleteService.ts84
1 files changed, 6 insertions, 78 deletions
diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts
index 3f1eef39c9..bdafad3f02 100644
--- a/packages/backend/src/core/NoteDeleteService.ts
+++ b/packages/backend/src/core/NoteDeleteService.ts
@@ -3,12 +3,11 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { Brackets, In, Not } from 'typeorm';
+import { Brackets, In } from 'typeorm';
import { Injectable, Inject } from '@nestjs/common';
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
import { MiNote, IMentionedRemoteUsers } from '@/models/Note.js';
-import { SkLatestNote } from '@/models/LatestNote.js';
-import type { InstancesRepository, LatestNotesRepository, NotesRepository, UsersRepository } from '@/models/_.js';
+import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/_.js';
import { RelayService } from '@/core/RelayService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { DI } from '@/di-symbols.js';
@@ -20,12 +19,12 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
-import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { MetaService } from '@/core/MetaService.js';
import { SearchService } from '@/core/SearchService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
-import { isPureRenote, isQuote, isRenote } from '@/misc/is-renote.js';
+import { isQuote, isRenote } from '@/misc/is-renote.js';
+import { LatestNoteService } from '@/core/LatestNoteService.js';
@Injectable()
export class NoteDeleteService {
@@ -39,14 +38,10 @@ export class NoteDeleteService {
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
- @Inject(DI.latestNotesRepository)
- private latestNotesRepository: LatestNotesRepository,
-
@Inject(DI.instancesRepository)
private instancesRepository: InstancesRepository,
private userEntityService: UserEntityService,
- private noteEntityService: NoteEntityService,
private globalEventService: GlobalEventService,
private relayService: RelayService,
private federatedInstanceService: FederatedInstanceService,
@@ -58,6 +53,7 @@ export class NoteDeleteService {
private notesChart: NotesChart,
private perUserNotesChart: PerUserNotesChart,
private instanceChart: InstanceChart,
+ private latestNoteService: LatestNoteService,
) {}
/**
@@ -152,7 +148,7 @@ export class NoteDeleteService {
userId: user.id,
});
- this.updateLatestNoteBG(note);
+ this.latestNoteService.handleDeletedNoteBG(note);
if (deleter && (note.userId !== deleter.id)) {
const user = await this.usersRepository.findOneByOrFail({ id: note.userId });
@@ -235,72 +231,4 @@ export class NoteDeleteService {
this.apDeliverManagerService.deliverToUser(user, content, remoteUser);
}
}
-
- private updateLatestNoteBG(note: MiNote): void {
- this
- .updateLatestNote(note)
- .catch(err => console.error('Unhandled exception while updating latest_note (after delete):', err));
- }
-
- private async updateLatestNote(note: MiNote) {
- // If it's a DM, then it can't possibly be the latest note so we can safely skip this.
- if (note.visibility === 'specified') return;
-
- // If it's a pure renote, then it can't possibly be the latest note so we can safely skip this.
- if (isPureRenote(note)) return;
-
- // Compute the compound key of the entry to check
- const key = SkLatestNote.keyFor(note);
-
- // Check if the deleted note was possibly the latest for the user
- const hasLatestNote = await this.latestNotesRepository.existsBy(key);
- if (hasLatestNote) return;
-
- // Find the newest remaining note for the user.
- // We exclude DMs and pure renotes.
- const nextLatest = await this.notesRepository
- .createQueryBuilder('note')
- .select()
- .where({
- userId: key.userId,
- visibility: key.isPublic
- ? 'public'
- : Not('specified'),
- replyId: key.isReply
- ? Not(null)
- : null,
- renoteId: key.isQuote
- ? Not(null)
- : null,
- })
- .andWhere(`
- (
- note."renoteId" IS NULL
- OR note.text IS NOT NULL
- OR note.cw IS NOT NULL
- OR note."replyId" IS NOT NULL
- OR note."hasPoll"
- OR note."fileIds" != '{}'
- )
- `)
- .orderBy({ id: 'DESC' })
- .getOne();
- if (!nextLatest) return;
-
- // Record it as the latest
- const latestNote = new SkLatestNote({
- ...key,
- noteId: nextLatest.id,
- });
-
- // When inserting the latest note, it's possible that another worker has "raced" the insert and already added a newer note.
- // We must use orIgnore() to ensure that the query ignores conflicts, otherwise an exception may be thrown.
- await this.latestNotesRepository
- .createQueryBuilder('latest')
- .insert()
- .into(SkLatestNote)
- .values(latestNote)
- .orIgnore()
- .execute();
- }
}