mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { In, Repository } from 'typeorm';
|
|
|
|
import { ClientEntity } from './client.entity';
|
|
|
|
const DEFAULT_CLIENT_ACTIVE_WINDOW_MS = 30 * 60 * 1000;
|
|
|
|
@Injectable()
|
|
export class ClientService {
|
|
private readonly activeWindowMs = this.readPositiveInt('CLIENT_REPORT_ACTIVE_WINDOW_MS', DEFAULT_CLIENT_ACTIVE_WINDOW_MS);
|
|
|
|
constructor(
|
|
@InjectRepository(ClientEntity)
|
|
private clientRepository: Repository<ClientEntity>
|
|
) {
|
|
|
|
}
|
|
|
|
public async insert(partialClient: Partial<ClientEntity>): Promise<ClientEntity> {
|
|
const insertResult = await this.clientRepository.insert(partialClient);
|
|
|
|
const client = {
|
|
...partialClient,
|
|
...insertResult.generatedMaps[0]
|
|
};
|
|
|
|
return client as ClientEntity;
|
|
}
|
|
|
|
public async delete(id: string) {
|
|
return await this.clientRepository.softDelete({ id });
|
|
}
|
|
|
|
public async deleteOldClients() {
|
|
|
|
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
|
|
return await this.clientRepository
|
|
.createQueryBuilder()
|
|
.delete()
|
|
.from(ClientEntity)
|
|
.where('deletedAt < :deletedAt', { deletedAt: oneDayAgo })
|
|
.execute();
|
|
|
|
}
|
|
|
|
public async updateBestDifficulty(id: string, bestDifficulty: number) {
|
|
return await this.clientRepository.update({ id }, { bestDifficulty });
|
|
}
|
|
|
|
public async updateBestDifficultyIfHigher(id: string, bestDifficulty: number) {
|
|
return await this.clientRepository
|
|
.createQueryBuilder()
|
|
.update(ClientEntity)
|
|
.set({ bestDifficulty })
|
|
.where('id = :id', { id })
|
|
.andWhere('"bestDifficulty" < :bestDifficulty', { bestDifficulty })
|
|
.execute();
|
|
}
|
|
|
|
public async updateHashRate(id: string, hashRate: number, updatedAt = new Date()) {
|
|
return await this.clientRepository.update({ id }, { hashRate, updatedAt, deletedAt: null });
|
|
}
|
|
|
|
public async connectedClientCount(): Promise<number> {
|
|
return await this.clientRepository.count();
|
|
}
|
|
|
|
public async getActiveIds(ids: string[]): Promise<Set<string>> {
|
|
if (ids.length === 0) {
|
|
return new Set();
|
|
}
|
|
|
|
const clients = await this.clientRepository.find({
|
|
select: {
|
|
id: true,
|
|
},
|
|
where: {
|
|
id: In(ids),
|
|
},
|
|
});
|
|
|
|
return new Set(clients.map(client => client.id));
|
|
}
|
|
|
|
public async getByAddress(address: string): Promise<ClientEntity[]> {
|
|
const activeSince = new Date(Date.now() - this.activeWindowMs);
|
|
return await this.clientRepository
|
|
.createQueryBuilder('client')
|
|
.where('client.address = :address', { address })
|
|
.andWhere('client.deletedAt IS NULL')
|
|
.andWhere('client.updatedAt > :activeSince', { activeSince })
|
|
.andWhere('client.hashRate > 0')
|
|
.orderBy('client.updatedAt', 'DESC')
|
|
.getMany();
|
|
}
|
|
|
|
|
|
public async getByName(address: string, clientName: string): Promise<ClientEntity[]> {
|
|
return await this.clientRepository.find({
|
|
where: {
|
|
address,
|
|
clientName
|
|
}
|
|
})
|
|
}
|
|
|
|
public async getBySessionId(address: string, clientName: string, sessionId: string): Promise<ClientEntity> {
|
|
return await this.clientRepository.findOne({
|
|
where: {
|
|
address,
|
|
clientName,
|
|
sessionId
|
|
}
|
|
})
|
|
}
|
|
|
|
public async deleteAll() {
|
|
return await this.clientRepository
|
|
.createQueryBuilder()
|
|
.delete()
|
|
.from(ClientEntity)
|
|
.where('"deletedAt" IS NULL')
|
|
.execute();
|
|
}
|
|
|
|
// public async getUserAgents() {
|
|
// const result = await this.clientRepository.createQueryBuilder('client')
|
|
// .select('client.userAgent as "userAgent"')
|
|
// .addSelect('COUNT(client.userAgent)', 'count')
|
|
// .addSelect('MAX(client.bestDifficulty)', 'bestDifficulty')
|
|
// .addSelect('SUM(client.hashRate)', 'totalHashRate')
|
|
// .groupBy('client.userAgent')
|
|
// .orderBy('"totalHashRate"', 'DESC')
|
|
// .getRawMany();
|
|
// return result;
|
|
// }
|
|
|
|
private readPositiveInt(name: string, defaultValue: number): number {
|
|
const value = Number(process.env[name]);
|
|
if (Number.isInteger(value) && value > 0) {
|
|
return value;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
}
|