mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
Filter stale clients from live miner report
This commit is contained in:
@@ -51,6 +51,10 @@ describe('UserAgentReportService', () => {
|
|||||||
]);
|
]);
|
||||||
expect(userAgentReport.find).not.toHaveBeenCalled();
|
expect(userAgentReport.find).not.toHaveBeenCalled();
|
||||||
expect(clientRepository.createQueryBuilder).toHaveBeenCalled();
|
expect(clientRepository.createQueryBuilder).toHaveBeenCalled();
|
||||||
|
expect(clientRepository.queryBuilder.andWhere).toHaveBeenCalledWith(
|
||||||
|
'client.updatedAt > :activeSince',
|
||||||
|
expect.objectContaining({ activeSince: expect.any(Date) }),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to the materialized view when no active database clients exist', async () => {
|
it('falls back to the materialized view when no active database clients exist', async () => {
|
||||||
@@ -114,6 +118,7 @@ function createClientRepository(rows: unknown[]) {
|
|||||||
select: jest.fn().mockReturnThis(),
|
select: jest.fn().mockReturnThis(),
|
||||||
addSelect: jest.fn().mockReturnThis(),
|
addSelect: jest.fn().mockReturnThis(),
|
||||||
where: jest.fn().mockReturnThis(),
|
where: jest.fn().mockReturnThis(),
|
||||||
|
andWhere: jest.fn().mockReturnThis(),
|
||||||
groupBy: jest.fn().mockReturnThis(),
|
groupBy: jest.fn().mockReturnThis(),
|
||||||
orderBy: jest.fn().mockReturnThis(),
|
orderBy: jest.fn().mockReturnThis(),
|
||||||
getRawMany: jest.fn().mockResolvedValue(rows),
|
getRawMany: jest.fn().mockResolvedValue(rows),
|
||||||
@@ -121,5 +126,6 @@ function createClientRepository(rows: unknown[]) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
createQueryBuilder: jest.fn().mockReturnValue(queryBuilder),
|
createQueryBuilder: jest.fn().mockReturnValue(queryBuilder),
|
||||||
|
queryBuilder,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ import { ClientEntity } from '../../client/client.entity';
|
|||||||
import { UserAgentReportView } from './user-agent-report.view';
|
import { UserAgentReportView } from './user-agent-report.view';
|
||||||
import { RedisMessagingService } from '../../../services/redis-messaging.service';
|
import { RedisMessagingService } from '../../../services/redis-messaging.service';
|
||||||
|
|
||||||
|
const DEFAULT_CLIENT_REPORT_ACTIVE_WINDOW_MS = 30 * 60 * 1000;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserAgentReportService {
|
export class UserAgentReportService {
|
||||||
private readonly liveReportCacheKey = 'presence:user-agent-report';
|
private readonly liveReportCacheKey = 'presence:user-agent-report';
|
||||||
|
private readonly activeWindowMs = this.readPositiveInt('CLIENT_REPORT_ACTIVE_WINDOW_MS', DEFAULT_CLIENT_REPORT_ACTIVE_WINDOW_MS);
|
||||||
private liveRefreshPromise: Promise<UserAgentReportView[]> | null = null;
|
private liveRefreshPromise: Promise<UserAgentReportView[]> | null = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -60,6 +63,7 @@ export class UserAgentReportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async buildLiveReport() {
|
private async buildLiveReport() {
|
||||||
|
const activeSince = new Date(Date.now() - this.activeWindowMs);
|
||||||
const rows = await this.clientRepository
|
const rows = await this.clientRepository
|
||||||
.createQueryBuilder('client')
|
.createQueryBuilder('client')
|
||||||
.select('COALESCE(NULLIF(client.userAgent, \'\'), \'Other\')', 'userAgent')
|
.select('COALESCE(NULLIF(client.userAgent, \'\'), \'Other\')', 'userAgent')
|
||||||
@@ -67,6 +71,7 @@ export class UserAgentReportService {
|
|||||||
.addSelect('MAX(client.bestDifficulty)', 'bestDifficulty')
|
.addSelect('MAX(client.bestDifficulty)', 'bestDifficulty')
|
||||||
.addSelect('COALESCE(SUM(client.hashRate), 0)', 'totalHashRate')
|
.addSelect('COALESCE(SUM(client.hashRate), 0)', 'totalHashRate')
|
||||||
.where('client.deletedAt IS NULL')
|
.where('client.deletedAt IS NULL')
|
||||||
|
.andWhere('client.updatedAt > :activeSince', { activeSince })
|
||||||
.groupBy('COALESCE(NULLIF(client.userAgent, \'\'), \'Other\')')
|
.groupBy('COALESCE(NULLIF(client.userAgent, \'\'), \'Other\')')
|
||||||
.orderBy('"totalHashRate"', 'DESC')
|
.orderBy('"totalHashRate"', 'DESC')
|
||||||
.getRawMany<UserAgentReportView>();
|
.getRawMany<UserAgentReportView>();
|
||||||
@@ -94,4 +99,12 @@ export class UserAgentReportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readPositiveInt(name: string, defaultValue: number): number {
|
||||||
|
const value = Number(process.env[name]);
|
||||||
|
if (Number.isInteger(value) && value > 0) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export class ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async updateHashRate(id: string, hashRate: number, updatedAt = new Date()) {
|
public async updateHashRate(id: string, hashRate: number, updatedAt = new Date()) {
|
||||||
return await this.clientRepository.update({ id }, { hashRate, updatedAt });
|
return await this.clientRepository.update({ id }, { hashRate, updatedAt, deletedAt: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connectedClientCount(): Promise<number> {
|
public async connectedClientCount(): Promise<number> {
|
||||||
|
|||||||
Reference in New Issue
Block a user