feat(server): custom library scanning interval (#4390)
* add automatic library scan config options * add validation * open api * use CronJob instead of cron-validator * fix tests * catch potential error of the library scan initialization * better description for input field * move library scan job initialization to server app service * fix tests * add comments to all parameters of cronjob contructor * make scan a child of a more general library object * open api * chore: cleanup * move cronjob handling to job repoistory * web: select for common cron expressions * fix open api * fix tests * put scanning settings in nested accordion * fix system config validation * refactor, tests --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
@@ -94,6 +94,9 @@ export enum SystemConfigKey {
|
||||
TRASH_DAYS = 'trash.days',
|
||||
|
||||
THEME_CUSTOM_CSS = 'theme.customCss',
|
||||
|
||||
LIBRARY_SCAN_ENABLED = 'library.scan.enabled',
|
||||
LIBRARY_SCAN_CRON_EXPRESSION = 'library.scan.cronExpression',
|
||||
}
|
||||
|
||||
export enum TranscodePolicy {
|
||||
@@ -232,4 +235,10 @@ export interface SystemConfig {
|
||||
theme: {
|
||||
customCss: string;
|
||||
};
|
||||
library: {
|
||||
scan: {
|
||||
enabled: boolean;
|
||||
cronExpression: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ import { IJobRepository, JobCounts, JobItem, JobName, JOBS_TO_QUEUE, QueueName,
|
||||
import { getQueueToken } from '@nestjs/bullmq';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { Job, JobsOptions, Processor, Queue, Worker, WorkerOptions } from 'bullmq';
|
||||
import { CronJob, CronTime } from 'cron';
|
||||
import { bullConfig } from '../infra.config';
|
||||
|
||||
@Injectable()
|
||||
@@ -10,7 +12,10 @@ export class JobRepository implements IJobRepository {
|
||||
private workers: Partial<Record<QueueName, Worker>> = {};
|
||||
private logger = new Logger(JobRepository.name);
|
||||
|
||||
constructor(private moduleRef: ModuleRef) {}
|
||||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
private schedulerReqistry: SchedulerRegistry,
|
||||
) {}
|
||||
|
||||
addHandler(queueName: QueueName, concurrency: number, handler: (item: JobItem) => Promise<void>) {
|
||||
const workerHandler: Processor = async (job: Job) => handler(job as JobItem);
|
||||
@@ -18,6 +23,43 @@ export class JobRepository implements IJobRepository {
|
||||
this.workers[queueName] = new Worker(queueName, workerHandler, workerOptions);
|
||||
}
|
||||
|
||||
addCronJob(name: string, expression: string, onTick: () => void, start = true): void {
|
||||
const job = new CronJob(
|
||||
expression,
|
||||
onTick,
|
||||
// function to run onComplete
|
||||
undefined,
|
||||
// whether it should start directly
|
||||
start,
|
||||
// timezone
|
||||
undefined,
|
||||
// context
|
||||
undefined,
|
||||
// runOnInit
|
||||
undefined,
|
||||
// utcOffset
|
||||
undefined,
|
||||
// prevents memory leaking by automatically stopping when the node process finishes
|
||||
true,
|
||||
);
|
||||
|
||||
this.schedulerReqistry.addCronJob(name, job);
|
||||
}
|
||||
|
||||
updateCronJob(name: string, expression?: string, start?: boolean): void {
|
||||
const job = this.schedulerReqistry.getCronJob(name);
|
||||
if (expression) {
|
||||
job.setTime(new CronTime(expression));
|
||||
}
|
||||
if (start !== undefined) {
|
||||
start ? job.start() : job.stop();
|
||||
}
|
||||
}
|
||||
|
||||
deleteCronJob(name: string): void {
|
||||
this.schedulerReqistry.deleteCronJob(name);
|
||||
}
|
||||
|
||||
setConcurrency(queueName: QueueName, concurrency: number) {
|
||||
const worker = this.workers[queueName];
|
||||
if (!worker) {
|
||||
|
||||
Reference in New Issue
Block a user