heartbeat updates

This commit is contained in:
Benjamin Wilson
2025-02-26 17:48:27 -05:00
parent 8584c442dc
commit c5c8810da6
3 changed files with 63 additions and 10 deletions
+54 -6
View File
@@ -9,7 +9,7 @@ import { ClientEntity } from './client.entity';
@Injectable() @Injectable()
export class ClientService { export class ClientService {
private heartbeatBulkUpdate: { [id: string]:{id: string, hashRate: number, updatedAt: Date}} = {};
constructor( constructor(
@InjectRepository(ClientEntity) @InjectRepository(ClientEntity)
@@ -28,13 +28,61 @@ export class ClientService {
.execute(); .execute();
} }
public async heartbeat(id, hashRate: number, updatedAt: Date) { //public async heartbeat(id, hashRate: number, updatedAt: Date) {
return await this.clientRepository.update({ id }, { hashRate, deletedAt: null, updatedAt }); // return await this.clientRepository.update({ id }, { hashRate, deletedAt: null, updatedAt });
// }
public heartbeatBulkAsync(id, hashRate: number, updatedAt: Date){
if(this.heartbeatBulkUpdate[id] != null){
this.heartbeatBulkUpdate[id].hashRate = hashRate;
this.heartbeatBulkUpdate[id].updatedAt = updatedAt;
return;
}
this.heartbeatBulkUpdate[id] = {id, hashRate, updatedAt};
} }
// public async save(client: Partial<ClientEntity>) { public async doBulkHeartbeatUpdate(){
// return await this.clientRepository.save(client); if(Object.keys(this.heartbeatBulkUpdate).length < 1){
// } console.log('No heartbeats to update.')
return;
}
const values = Object.entries(this.heartbeatBulkUpdate).map(([key, value]) => {
return `('${value.id}', ${value.hashRate}, '${value.updatedAt.toISOString()}')`
}).join(',');
const query = `
DO $$
BEGIN
CREATE TEMP TABLE temp_heartbeats (
id UUID,
"hashRate" DECIMAL,
"updatedAt" TIMESTAMP
) ON COMMIT DROP;
INSERT INTO temp_heartbeats (id, "hashRate", "updatedAt")
VALUES ${values};
UPDATE "client_entity" ce
SET "hashRate" = th."hashRate",
"deletedAt" = NULL,
"updatedAt" = th."updatedAt"
FROM temp_heartbeats th
WHERE ce.id = th.id;
END;
$$;
`;
try {
await this.clientRepository.query(query);
console.log(`Bulk updated ${this.heartbeatBulkUpdate.length} client heartbeats`);
} catch (error) {
console.error('Bulk heartbeat failed:', error.message, 'Query:', query);
throw error;
}
this.heartbeatBulkUpdate = {};
}
public async insert(partialClient: Partial<ClientEntity>): Promise<ClientEntity> { public async insert(partialClient: Partial<ClientEntity>): Promise<ClientEntity> {
+4 -4
View File
@@ -545,10 +545,10 @@ export class StratumV1Client {
await this.statistics.addShares(this.clientEntity, this.sessionDifficulty); await this.statistics.addShares(this.clientEntity, this.sessionDifficulty);
const now = new Date(); const now = new Date();
// only update every minute // only update every minute
if (this.clientEntity.updatedAt == null || now.getTime() - this.clientEntity.updatedAt.getTime() > 1000 * 60) { //if (this.clientEntity.updatedAt == null || now.getTime() - this.clientEntity.updatedAt.getTime() > 1000 * 60) {
await this.clientService.heartbeat(this.clientEntity.id, this.hashRate, now); await this.clientService.heartbeatBulkAsync(this.clientEntity.id, this.hashRate, now);
this.clientEntity.updatedAt = now; this.clientEntity.updatedAt = now;
} //}
} catch (e) { } catch (e) {
console.log(e); console.log(e);
+5
View File
@@ -55,6 +55,11 @@ export class AppService implements OnModuleInit {
await this.clientStatisticsService.doBulkAsyncUpdate(); await this.clientStatisticsService.doBulkAsyncUpdate();
}, 1000 * 60 * 1); }, 1000 * 60 * 1);
setInterval(async () => {
//console.log('Bulk update client stats');
await this.clientService.doBulkHeartbeatUpdate();
}, 1000 * 60 * 1);
} }