mirror of
https://github.com/movie-web/backend.git
synced 2025-09-13 14:53:25 +00:00
scheduled cleanup jobs
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { setupFastify, startFastify } from '@/modules/fastify';
|
||||
import { setupJobs } from '@/modules/jobs';
|
||||
import { setupMetrics } from '@/modules/metrics';
|
||||
import { setupMikroORM } from '@/modules/mikro';
|
||||
import { scopedLogger } from '@/services/logger';
|
||||
@@ -13,6 +14,7 @@ async function bootstrap(): Promise<void> {
|
||||
const app = await setupFastify();
|
||||
await setupMikroORM();
|
||||
await setupMetrics(app);
|
||||
await setupJobs();
|
||||
|
||||
await startFastify(app);
|
||||
|
||||
|
5
src/modules/jobs/index.ts
Normal file
5
src/modules/jobs/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { sessionExpiryJob } from '@/modules/jobs/list/sessionExpiry';
|
||||
|
||||
export async function setupJobs() {
|
||||
sessionExpiryJob.start();
|
||||
}
|
43
src/modules/jobs/job.ts
Normal file
43
src/modules/jobs/job.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { getORM } from '@/modules/mikro';
|
||||
import { scopedLogger } from '@/services/logger';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { CronJob } from 'cron';
|
||||
|
||||
const minOffset = 0;
|
||||
const maxOffset = 60 * 4;
|
||||
const secondsOffset =
|
||||
Math.floor(Math.random() * (maxOffset - minOffset)) + minOffset;
|
||||
|
||||
const log = scopedLogger('jobs');
|
||||
|
||||
const wait = (sec: number) =>
|
||||
new Promise<void>((resolve) => {
|
||||
setTimeout(() => resolve(), sec * 1000);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param cron crontime in this order: (min of hour) (hour of day) (day of month) (day of week) (sec of month)
|
||||
*/
|
||||
export function job(
|
||||
cron: string,
|
||||
cb: (ctx: { em: EntityManager }) => Promise<void>,
|
||||
): CronJob {
|
||||
return CronJob.from({
|
||||
cronTime: cron,
|
||||
onTick: async () => {
|
||||
// offset by random amount of seconds, just to prevent jobs running at
|
||||
// the same time when running multiple instances
|
||||
await wait(secondsOffset);
|
||||
|
||||
// actually run the job
|
||||
try {
|
||||
const em = getORM().em.fork();
|
||||
await cb({ em });
|
||||
} catch (err) {
|
||||
log.error('Failed to run job!');
|
||||
log.error(err);
|
||||
}
|
||||
},
|
||||
start: false,
|
||||
});
|
||||
}
|
15
src/modules/jobs/list/sessionExpiry.ts
Normal file
15
src/modules/jobs/list/sessionExpiry.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Session } from '@/db/models/Session';
|
||||
import { job } from '@/modules/jobs/job';
|
||||
|
||||
// every day at 12:00:00
|
||||
export const sessionExpiryJob = job('0 12 * * *', async ({ em }) => {
|
||||
await em
|
||||
.createQueryBuilder(Session)
|
||||
.delete()
|
||||
.where({
|
||||
expiresAt: {
|
||||
$lt: new Date(),
|
||||
},
|
||||
})
|
||||
.execute();
|
||||
});
|
Reference in New Issue
Block a user