refactor(api): streamline InfoResolver and SubscriptionTrackerService

- Removed unnecessary imports and parameters in InfoResolver for cleaner code.
- Updated CPU utilization method to directly use infoService for generating CPU load.
- Enhanced SubscriptionTrackerService to improve subscriber count management and added early return for idempotency in unsubscribe method.
This commit is contained in:
Eli Bosley
2025-08-18 18:25:08 -04:00
parent 476abd5f53
commit 3afc4219ee
2 changed files with 21 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
import { OnModuleInit } from '@nestjs/common';
import { Parent, Query, ResolveField, Resolver, Subscription } from '@nestjs/graphql';
import { Query, ResolveField, Resolver, Subscription } from '@nestjs/graphql';
import { Resource } from '@unraid/shared/graphql.model.js';
import {
@@ -7,7 +7,6 @@ import {
AuthPossession,
UsePermissions,
} from '@unraid/shared/use-permissions.directive.js';
import { PubSub } from 'graphql-subscriptions';
import { baseboard as getBaseboard, system as getSystem } from 'systeminformation';
import { createSubscription, pubsub, PUBSUB_CHANNEL } from '@app/core/pubsub.js';
@@ -37,8 +36,7 @@ export class InfoResolver implements OnModuleInit {
constructor(
private readonly infoService: InfoService,
private readonly displayService: DisplayService,
private readonly subscriptionTracker: SubscriptionTrackerService,
private readonly cpuDataService: CpuDataService
private readonly subscriptionTracker: SubscriptionTrackerService
) {}
onModuleInit() {
@@ -148,12 +146,7 @@ export class InfoResolver implements OnModuleInit {
possession: AuthPossession.ANY,
})
public async cpuUtilization(): Promise<CpuUtilization> {
const { currentLoad: load, cpus } = await this.cpuDataService.getCpuLoad();
return {
id: 'info/cpu-load',
load,
cpus,
};
return this.infoService.generateCpuLoad();
}
@Subscription(() => CpuUtilization, {
@@ -189,7 +182,7 @@ export class InfoCpuResolver {
description: 'CPU utilization in percent',
nullable: true,
})
public async utilization(@Parent() cpu: InfoCpu): Promise<number> {
public async utilization(): Promise<number> {
const { currentLoad } = await this.cpuDataService.getCpuLoad();
return currentLoad;
}

View File

@@ -10,28 +10,39 @@ export class SubscriptionTrackerService {
}
public subscribe(topic: string): void {
const currentCount = this.subscriberCounts.get(topic) || 0;
const currentCount = this.subscriberCounts.get(topic) ?? 0;
this.subscriberCounts.set(topic, currentCount + 1);
if (currentCount === 0) {
const handlers = this.topicHandlers.get(topic);
if (handlers) {
if (handlers?.onStart) {
handlers.onStart();
}
}
}
public unsubscribe(topic: string): void {
const currentCount = this.subscriberCounts.get(topic) || 1;
const currentCount = this.subscriberCounts.get(topic) ?? 0;
// Early return for idempotency - if already at 0, do nothing
if (currentCount === 0) {
return;
}
const newCount = currentCount - 1;
this.subscriberCounts.set(topic, newCount);
if (newCount === 0) {
// Delete the topic entry when reaching zero
this.subscriberCounts.delete(topic);
// Call onStop handler if it exists
const handlers = this.topicHandlers.get(topic);
if (handlers) {
if (handlers?.onStop) {
handlers.onStop();
}
} else {
// Only update the count if not zero
this.subscriberCounts.set(topic, newCount);
}
}
}