Split user deletion job and add more job logs

This commit is contained in:
William Oldham
2023-11-04 12:30:04 +00:00
parent 04175fafae
commit 4b79a43e15
5 changed files with 111 additions and 51 deletions

View File

@@ -1,5 +1,9 @@
import { challengeCodeJob } from '@/modules/jobs/list/challengeCode';
import { sessionExpiryJob } from '@/modules/jobs/list/sessionExpiry';
import { userDeletionJob } from '@/modules/jobs/list/userDeletion';
export async function setupJobs() {
challengeCodeJob.start();
sessionExpiryJob.start();
userDeletionJob.start();
}

View File

@@ -20,9 +20,11 @@ const wait = (sec: number) =>
* @param cron crontime in this order: (min of hour) (hour of day) (day of month) (day of week) (sec of month)
*/
export function job(
name: string,
cron: string,
cb: (ctx: { em: EntityManager; log: Logger }) => Promise<void>,
): CronJob {
log.info(`Registering job '${name}' with cron '${cron}'`);
return CronJob.from({
cronTime: cron,
onTick: async () => {
@@ -33,9 +35,10 @@ export function job(
// actually run the job
try {
const em = getORM().em.fork();
log.info(`Starting job '${name}' with cron '${cron}'`);
await cb({ em, log });
} catch (err) {
log.error('Failed to run job!');
log.error(`Failed to run '${name}' job!`);
log.error(err);
}
},

View File

@@ -2,7 +2,10 @@ import { ChallengeCode } from '@/db/models/ChallengeCode';
import { job } from '@/modules/jobs/job';
// every day at 12:00:00
export const sessionExpiryJob = job('0 12 * * *', async ({ em }) => {
export const challengeCodeJob = job(
'Challenge Code Expiry',
'0 12 * * *',
async ({ em }) => {
await em
.createQueryBuilder(ChallengeCode)
.delete()
@@ -12,4 +15,5 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em }) => {
},
})
.execute();
});
},
);

View File

@@ -1,8 +1,12 @@
import { Session } from '@/db/models/Session';
import { User } from '@/db/models/User';
import { job } from '@/modules/jobs/job';
// every day at 12:00:00
export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
export const sessionExpiryJob = job(
'Session Expiry',
'0 12 * * *',
async ({ em, log }) => {
const deletedSessions = await em
.createQueryBuilder(Session)
.delete()
@@ -13,7 +17,9 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
})
.execute<{ affectedRows: number }>('run');
log.info(`Removed ${deletedSessions.affectedRows} sessions that had expired`);
log.info(
`Removed ${deletedSessions.affectedRows} sessions that had expired`,
);
const knex = em.getKnex();
@@ -46,4 +52,5 @@ export const sessionExpiryJob = job('0 12 * * *', async ({ em, log }) => {
log.info(
`Removed ${deletedUsers.affectedRows} users older than 1 year with no sessions`,
);
});
},
);

View File

@@ -0,0 +1,42 @@
import { Session } from '@/db/models/Session';
import { User } from '@/db/models/User';
import { job } from '@/modules/jobs/job';
// every day at 12:00:00
export const userDeletionJob = job(
'User Deletion',
'0 12 * * *',
async ({ em, log }) => {
const knex = em.getKnex();
// Count all sessions for a user ID
const sessionCountForUser = em
.createQueryBuilder(Session, 'session')
.count()
.where({ user: knex.ref('user.id') })
.getKnexQuery();
const now = new Date();
const oneYearAgo = new Date();
oneYearAgo.setFullYear(now.getFullYear() - 1);
// Delete all users who do not have any sessions AND
// (their login date is null OR they last logged in over 1 year ago)
const deletedUsers = await em
.createQueryBuilder(User, 'user')
.delete()
.withSubQuery(sessionCountForUser, 'session.sessionCount')
.where({
'session.sessionCount': 0,
$or: [
{ lastLoggedIn: { $eq: undefined } },
{ lastLoggedIn: { $lt: oneYearAgo } },
],
})
.execute<{ affectedRows: number }>('run');
log.info(
`Removed ${deletedUsers.affectedRows} users older than 1 year with no sessions`,
);
},
);