mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 17:15:03 -07:00
batch kill dead clients
This commit is contained in:
@@ -19,13 +19,31 @@ export class ClientService {
|
||||
}
|
||||
|
||||
public async killDeadClients() {
|
||||
const batchSize = 500;
|
||||
|
||||
return await this.clientRepository
|
||||
const clients = await this.clientRepository
|
||||
.createQueryBuilder('client')
|
||||
.where('client.deletedAt IS NULL')
|
||||
.andWhere('client.updatedAt < NOW() - INTERVAL \'5 minutes\'')
|
||||
.orderBy('client.id', 'ASC') // consistent lock order ← prevents deadlocks
|
||||
.limit(batchSize) // small batches ← prevents lock explosion
|
||||
.setLock('pessimistic_write') // adds FOR UPDATE SKIP LOCKED
|
||||
.getMany();
|
||||
|
||||
if (clients.length === 0) {
|
||||
return false; // nothing to do (caller can stop looping)
|
||||
}
|
||||
|
||||
const ids = clients.map(c => c.id);
|
||||
|
||||
await this.clientRepository
|
||||
.createQueryBuilder()
|
||||
.update(ClientEntity)
|
||||
.set({ deletedAt: () => "NOW()" })
|
||||
.where("deletedAt IS NULL AND updatedAt < NOW() - interval '5 minutes' ")
|
||||
.set({ deletedAt: () => 'NOW()' })
|
||||
.whereInIds(ids)
|
||||
.execute();
|
||||
|
||||
return true; // tell caller there might be more batches
|
||||
}
|
||||
|
||||
//public async heartbeat(id, hashRate: number, updatedAt: Date) {
|
||||
|
||||
@@ -30,7 +30,9 @@ export class AppService implements OnModuleInit {
|
||||
|
||||
setInterval(async () => {
|
||||
console.log('Killing dead clients');
|
||||
await this.clientService.killDeadClients();
|
||||
while (await this.clientService.killDeadClients()) {
|
||||
console.log('Finished killing clients');
|
||||
}
|
||||
}, 1000 * 60 * 5);
|
||||
|
||||
setInterval(async () => {
|
||||
|
||||
Reference in New Issue
Block a user