perf: delete-account処理を軽くする (#7958)
* Revert "#7892"
This reverts commit 71d9c2a53d
.
* アカウント削除処理でノート削除を重複して行なわないようにする
* ドライブファイル削除時に参照しているノートを削除しないようにする
* 不要となったコードを削除する
This commit is contained in:
parent
71d9c2a53d
commit
07526ada45
|
@ -15,7 +15,7 @@ export async function deleteActor(actor: IRemoteUser, uri: string): Promise<stri
|
||||||
if (actor.isDeleted) {
|
if (actor.isDeleted) {
|
||||||
logger.info(`skip: already deleted`);
|
logger.info(`skip: already deleted`);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
const job = await createDeleteAccountJob(actor);
|
const job = await createDeleteAccountJob(actor);
|
||||||
|
|
||||||
await Users.update(actor.id, {
|
await Users.update(actor.id, {
|
||||||
|
@ -23,7 +23,4 @@ export async function deleteActor(actor: IRemoteUser, uri: string): Promise<stri
|
||||||
});
|
});
|
||||||
|
|
||||||
return `ok: queued ${job.name} ${job.id}`;
|
return `ok: queued ${job.name} ${job.id}`;
|
||||||
*/
|
|
||||||
|
|
||||||
return `skip: account deletion temporaly disabled`;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
import { DriveFile } from '@/models/entities/drive-file';
|
import { DriveFile } from '@/models/entities/drive-file';
|
||||||
import { InternalStorage } from './internal-storage';
|
import { InternalStorage } from './internal-storage';
|
||||||
import { DriveFiles, Instances, Notes, Users } from '@/models/index';
|
import { DriveFiles, Instances } from '@/models/index';
|
||||||
import { driveChart, perUserDriveChart, instanceChart } from '@/services/chart/index';
|
import { driveChart, perUserDriveChart, instanceChart } from '@/services/chart/index';
|
||||||
import { createDeleteObjectStorageFileJob } from '@/queue/index';
|
import { createDeleteObjectStorageFileJob } from '@/queue/index';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { getS3 } from './s3';
|
import { getS3 } from './s3';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { Note } from '@/models/entities/note';
|
|
||||||
import { renderActivity } from '@/remote/activitypub/renderer/index';
|
|
||||||
import renderDelete from '@/remote/activitypub/renderer/delete';
|
|
||||||
import renderTombstone from '@/remote/activitypub/renderer/tombstone';
|
|
||||||
import config from '@/config/index';
|
|
||||||
import { deliverToFollowers } from '@/remote/activitypub/deliver-manager';
|
|
||||||
import { Brackets } from 'typeorm';
|
|
||||||
import { deliverToRelays } from '../relay';
|
|
||||||
|
|
||||||
export async function deleteFile(file: DriveFile, isExpired = false) {
|
export async function deleteFile(file: DriveFile, isExpired = false) {
|
||||||
if (file.storedInternal) {
|
if (file.storedInternal) {
|
||||||
|
@ -87,28 +79,6 @@ async function postProcess(file: DriveFile, isExpired = false) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
DriveFiles.delete(file.id);
|
DriveFiles.delete(file.id);
|
||||||
|
|
||||||
// TODO: トランザクション
|
|
||||||
const relatedNotes = await findRelatedNotes(file.id);
|
|
||||||
for (const relatedNote of relatedNotes) { // for each note with deleted driveFile
|
|
||||||
const cascadingNotes = (await findCascadingNotes(relatedNote)).filter(note => !note.localOnly);
|
|
||||||
for (const cascadingNote of cascadingNotes) { // for each notes subject to cascade deletion
|
|
||||||
if (!cascadingNote.user) continue;
|
|
||||||
if (!Users.isLocalUser(cascadingNote.user)) continue;
|
|
||||||
const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${cascadingNote.id}`), cascadingNote.user));
|
|
||||||
deliverToFollowers(cascadingNote.user, content); // federate delete msg
|
|
||||||
deliverToRelays(cascadingNote.user, content);
|
|
||||||
}
|
|
||||||
if (!relatedNote.user) continue;
|
|
||||||
if (Users.isLocalUser(relatedNote.user)) {
|
|
||||||
const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${relatedNote.id}`), relatedNote.user));
|
|
||||||
deliverToFollowers(relatedNote.user, content);
|
|
||||||
deliverToRelays(relatedNote.user, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Notes.createQueryBuilder().delete()
|
|
||||||
.where(':id = ANY("fileIds")', { id: file.id })
|
|
||||||
.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 統計を更新
|
// 統計を更新
|
||||||
|
@ -131,36 +101,3 @@ export async function deleteObjectStorageFile(key: string) {
|
||||||
Key: key
|
Key: key
|
||||||
}).promise();
|
}).promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findRelatedNotes(fileId: string) {
|
|
||||||
// NOTE: When running raw query, TypeORM converts field name to lowercase. Wrap in quotes to prevent conversion.
|
|
||||||
const relatedNotes = await Notes.createQueryBuilder('note').where(':id = ANY("fileIds")', { id: fileId }).getMany();
|
|
||||||
for (const relatedNote of relatedNotes) {
|
|
||||||
const user = await Users.findOne({ id: relatedNote.userId });
|
|
||||||
if (user)
|
|
||||||
relatedNote.user = user;
|
|
||||||
}
|
|
||||||
return relatedNotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function findCascadingNotes(note: Note) {
|
|
||||||
const cascadingNotes: Note[] = [];
|
|
||||||
|
|
||||||
const recursive = async (noteId: string) => {
|
|
||||||
const query = Notes.createQueryBuilder('note')
|
|
||||||
.where('note.replyId = :noteId', { noteId })
|
|
||||||
.orWhere(new Brackets(q => {
|
|
||||||
q.where('note.renoteId = :noteId', { noteId })
|
|
||||||
.andWhere('note.text IS NOT NULL');
|
|
||||||
}))
|
|
||||||
.leftJoinAndSelect('note.user', 'user');
|
|
||||||
const replies = await query.getMany();
|
|
||||||
for (const reply of replies) {
|
|
||||||
cascadingNotes.push(reply);
|
|
||||||
await recursive(reply.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
await recursive(note.id);
|
|
||||||
|
|
||||||
return cascadingNotes.filter(note => note.userHost === null); // filter out non-local users
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue