Merge 00b09924a6
into d522d1bf26
This commit is contained in:
commit
e5a084ec15
|
@ -5,7 +5,7 @@
|
|||
|
||||
// https://github.com/typeorm/typeorm/issues/2400
|
||||
import pg from 'pg';
|
||||
import { DataSource, Logger, type QueryRunner } from 'typeorm';
|
||||
import { DataSource, EntityManager, Logger, type QueryRunner } from 'typeorm';
|
||||
import * as highlight from 'cli-highlight';
|
||||
import { entities as charts } from '@/core/chart/entities.js';
|
||||
import { Config } from '@/config.js';
|
||||
|
@ -262,6 +262,33 @@ export const entities = [
|
|||
|
||||
const log = process.env.NODE_ENV !== 'production';
|
||||
|
||||
/**
|
||||
* Execute query with extended timeout.
|
||||
* This can be used to execute long-running queries like deleting many rows CASCADE-ly.
|
||||
*
|
||||
* TODO: consider remove this function when we removed CASCADE delete.
|
||||
*/
|
||||
export async function extendTimeoutQuery(dataSource: DataSource, query: (manager: EntityManager) => Promise<void>): Promise<void> {
|
||||
const queryRunner = dataSource.createQueryRunner('master');
|
||||
const manager = dataSource.createEntityManager(queryRunner);
|
||||
const extendedTimeout = 1000 * 100; // 100 sec for now. How long should it be?
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
try {
|
||||
// it looks postgres doesn't support statement_timeout with placeholder
|
||||
// await manager.query(`set statement_timeout to $1`, [extendedTimeout]);
|
||||
await manager.query(`set statement_timeout to ${extendedTimeout}`);
|
||||
await query(manager);
|
||||
} finally {
|
||||
await manager.query(`set statement_timeout to ${default_statement_timeout}`);
|
||||
}
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
export const default_statement_timeout = 1000 * 10;
|
||||
|
||||
export function createPostgresDataSource(config: Config) {
|
||||
return new DataSource({
|
||||
type: 'postgres',
|
||||
|
@ -271,7 +298,7 @@ export function createPostgresDataSource(config: Config) {
|
|||
password: config.db.pass,
|
||||
database: config.db.db,
|
||||
extra: {
|
||||
statement_timeout: 1000 * 10,
|
||||
statement_timeout: default_statement_timeout,
|
||||
...config.db.extra,
|
||||
},
|
||||
...(config.dbReplications ? {
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { MoreThan } from 'typeorm';
|
||||
import { DataSource, MoreThan } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||
import { MiUser } from '@/models/User.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { DriveService } from '@/core/DriveService.js';
|
||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { MiNote } from '@/models/Note.js';
|
||||
import { EmailService } from '@/core/EmailService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { SearchService } from '@/core/SearchService.js';
|
||||
import { extendTimeoutQuery } from '@/postgres.js';
|
||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||
import type * as Bull from 'bullmq';
|
||||
import type { DbUserDeleteJobData } from '../types.js';
|
||||
|
@ -23,6 +25,9 @@ export class DeleteAccountProcessorService {
|
|||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.db)
|
||||
private db: DataSource,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
|
@ -73,7 +78,9 @@ export class DeleteAccountProcessorService {
|
|||
|
||||
cursor = notes.at(-1)?.id ?? null;
|
||||
|
||||
await this.notesRepository.delete(notes.map(note => note.id));
|
||||
await extendTimeoutQuery(this.db, async (manager) => {
|
||||
await manager.delete(MiNote, notes.map(note => note.id));
|
||||
});
|
||||
|
||||
for (const note of notes) {
|
||||
await this.searchService.unindexNote(note);
|
||||
|
@ -125,7 +132,9 @@ export class DeleteAccountProcessorService {
|
|||
if (job.data.soft) {
|
||||
// nop
|
||||
} else {
|
||||
await this.usersRepository.delete(job.data.user.id);
|
||||
await extendTimeoutQuery(this.db, async (manager) => {
|
||||
await manager.delete(MiUser, job.data.user.id);
|
||||
});
|
||||
}
|
||||
|
||||
return 'Account deleted';
|
||||
|
|
Loading…
Reference in New Issue