|
1 | 1 | import { Cron } from './cron'; |
2 | 2 | import { User } from '../entity'; |
3 | | -import { LessThan } from 'typeorm'; |
| 3 | +import { LessThan, In } from 'typeorm'; |
4 | 4 | import { subHours } from 'date-fns'; |
5 | 5 |
|
| 6 | +const BATCH_SIZE = 50; |
| 7 | + |
6 | 8 | const cron: Cron = { |
7 | 9 | name: 'clean-zombie-users', |
8 | 10 | handler: async (con, logger) => { |
9 | 11 | logger.info('cleaning zombie users...'); |
10 | 12 | const timeThreshold = subHours(new Date(), 1); |
11 | | - const query = con |
12 | | - .createQueryBuilder() |
13 | | - .delete() |
14 | | - .from(User) |
15 | | - .where([ |
16 | | - { |
17 | | - infoConfirmed: false, |
18 | | - }, |
19 | | - { |
20 | | - emailConfirmed: false, |
21 | | - }, |
22 | | - ]) |
23 | | - .andWhere({ |
24 | | - createdAt: LessThan(timeThreshold), |
25 | | - }); |
| 13 | + const userRepo = con.getRepository(User); |
| 14 | + |
| 15 | + const zombieUsers = await userRepo.find({ |
| 16 | + select: ['id'], |
| 17 | + where: [ |
| 18 | + { infoConfirmed: false, createdAt: LessThan(timeThreshold) }, |
| 19 | + { emailConfirmed: false, createdAt: LessThan(timeThreshold) }, |
| 20 | + ], |
| 21 | + }); |
| 22 | + |
| 23 | + const ids = zombieUsers.map((u) => u.id); |
| 24 | + let totalDeleted = 0; |
| 25 | + |
| 26 | + for (let i = 0; i < ids.length; i += BATCH_SIZE) { |
| 27 | + const batch = ids.slice(i, i + BATCH_SIZE); |
| 28 | + const { affected } = await userRepo.delete({ id: In(batch) }); |
| 29 | + totalDeleted += affected ?? 0; |
| 30 | + } |
26 | 31 |
|
27 | | - const { affected } = await query.execute(); |
28 | | - logger.info({ count: affected }, 'zombies users cleaned! 🧟'); |
| 32 | + logger.info({ count: totalDeleted }, 'zombies users cleaned! 🧟'); |
29 | 33 | }, |
30 | 34 | }; |
31 | 35 |
|
|
0 commit comments