feat: cleanup old download requests

pull/24121/head
Diogo Correia 2025-12-02 22:57:01 +07:00
parent 642fcd12ec
commit bb0ee28486
No known key found for this signature in database
GPG Key ID: 12B4F3AC9C065D08
5 changed files with 27 additions and 2 deletions

@ -564,6 +564,8 @@ export enum JobName {
DatabaseBackup = 'DatabaseBackup',
DownloadRequestCleanup = 'DownloadRequestCleanup',
FacialRecognitionQueueAll = 'FacialRecognitionQueueAll',
FacialRecognition = 'FacialRecognition',

@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, sql } from 'kysely';
import _ from 'lodash';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely';
import { DummyValue, GenerateSql } from 'src/decorators';
import { DB } from 'src/schema';
@ -10,12 +11,22 @@ import { DownloadRequestTable } from 'src/schema/tables/download-request.table';
export class DownloadRequestRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
cleanup() {
return this.db
.deleteFrom('download_request')
.where('download_request.expiresAt', '<=', DateTime.now().toJSDate())
.returning(['id'])
.execute();
}
@GenerateSql({ params: [DummyValue.UUID] })
get(id: string) {
return this.db
.selectFrom('download_request')
.selectAll('download_request')
.where('download_request.id', '=', id)
.where((eb) =>
eb.and([eb('download_request.id', '=', id), eb('download_request.expiresAt', '>', DateTime.now().toJSDate())]),
)
.leftJoin('download_request_asset', 'download_request_asset.downloadRequestId', 'download_request.id')
.select((eb) =>
eb.fn

@ -2,6 +2,7 @@ import { BadRequestException, Injectable } from '@nestjs/common';
import { DateTime } from 'luxon';
import { parse } from 'node:path';
import { StorageCore } from 'src/cores/storage.core';
import { OnJob } from 'src/decorators';
import { AssetIdsDto } from 'src/dtos/asset.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import {
@ -10,7 +11,7 @@ import {
DownloadResponseDto,
PrepareDownloadResponseDto,
} from 'src/dtos/download.dto';
import { Permission } from 'src/enum';
import { JobName, JobStatus, Permission, QueueName } from 'src/enum';
import { ImmichReadStream } from 'src/repositories/storage.repository';
import { BaseService } from 'src/services/base.service';
import { HumanReadableSize } from 'src/utils/bytes';
@ -18,6 +19,15 @@ import { getPreferences } from 'src/utils/preferences';
@Injectable()
export class DownloadService extends BaseService {
@OnJob({ name: JobName.DownloadRequestCleanup, queue: QueueName.BackgroundTask })
async handleDownloadRequestCleanup(): Promise<JobStatus> {
const requests = await this.downloadRequestRepository.cleanup();
this.logger.log(`Deleted ${requests.length} expired download requests`);
return JobStatus.Success;
}
async getDownloadInfo(auth: AuthDto, dto: DownloadInfoDto): Promise<DownloadResponseDto> {
let assets;

@ -226,6 +226,7 @@ export class QueueService extends BaseService {
{ name: JobName.SessionCleanup },
{ name: JobName.AuditTableCleanup },
{ name: JobName.AuditLogCleanup },
{ name: JobName.DownloadRequestCleanup },
);
}

@ -362,6 +362,7 @@ export type JobItem =
// Cleanup
| { name: JobName.AuditLogCleanup; data?: IBaseJob }
| { name: JobName.DownloadRequestCleanup; data?: IBaseJob }
| { name: JobName.SessionCleanup; data?: IBaseJob }
// Tags