Skip to content

Commit c876997

Browse files
committed
implement dynamic remote access timeout job
1 parent 3a2dc2b commit c876997

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

packages/unraid-api-plugin-connect/src/config.entity.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export enum MinigraphStatus {
2525
}
2626

2727
export enum DynamicRemoteAccessType {
28-
NONE = 'none',
29-
UPNP = 'upnp',
30-
MANUAL = 'manual',
28+
STATIC = 'STATIC',
29+
UPNP = 'UPNP',
30+
DISABLED = 'DISABLED',
3131
}
3232

3333
export enum URL_TYPE {
@@ -193,15 +193,18 @@ export class AccessUrlObject {
193193
name!: string | null | undefined;
194194
}
195195

196+
export const makeDisabledDynamicRemoteAccessState = (): DynamicRemoteAccessState =>
197+
plainToInstance(DynamicRemoteAccessState, {
198+
runningType: DynamicRemoteAccessType.DISABLED,
199+
error: null,
200+
lastPing: null,
201+
allowedUrl: null,
202+
});
203+
196204
export const configFeature = registerAs<ConnectConfig>('connect', () => ({
197205
demo: 'hello.unraider',
198206
mothership: plainToInstance(ConnectionMetadata, {
199207
status: MinigraphStatus.PRE_INIT,
200208
}),
201-
dynamicRemoteAccess: plainToInstance(DynamicRemoteAccessState, {
202-
runningType: DynamicRemoteAccessType.NONE,
203-
error: null,
204-
lastPing: null,
205-
allowedUrl: null,
206-
}),
209+
dynamicRemoteAccess: makeDisabledDynamicRemoteAccessState(),
207210
}));
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const ONE_MINUTE_MS = 60 * 1000;
2+
export const THREE_MINUTES_MS = 3 * ONE_MINUTE_MS;

packages/unraid-api-plugin-connect/src/mothership/timeout-checker.job.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { SchedulerRegistry } from '@nestjs/schedule';
44
import { isDefined } from 'class-validator';
55

66
import { MinigraphStatus } from '../config.entity.js';
7+
import { ONE_MINUTE_MS, THREE_MINUTES_MS } from '../helpers/consts.js';
8+
import { DynamicRemoteAccessStateService } from '../remote-access/dynamic-remote-access-state.service.js';
79
import { MothershipConnectionService } from './connection.service.js';
810
import { MothershipSubscriptionHandler } from './mothership-subscription.handler.js';
911

@@ -12,26 +14,23 @@ export class TimeoutCheckerJob {
1214
constructor(
1315
private readonly connectionService: MothershipConnectionService,
1416
private readonly subscriptionHandler: MothershipSubscriptionHandler,
15-
private schedulerRegistry: SchedulerRegistry
17+
private schedulerRegistry: SchedulerRegistry,
18+
private readonly dynamicRemoteAccess: DynamicRemoteAccessStateService
1619
) {}
1720

1821
public jobName = 'connect-timeout-checker';
1922
private readonly logger = new Logger(TimeoutCheckerJob.name);
20-
private THREE_MINUTES_MS = 3 * 60 * 1000;
21-
private ONE_MINUTE_MS = 60 * 1000;
2223

2324
private hasMothershipClientTimedOut() {
2425
const { lastPing, status } = this.connectionService.getConnectionState() ?? {};
2526
return (
26-
status === MinigraphStatus.CONNECTED &&
27-
lastPing &&
28-
Date.now() - lastPing > this.THREE_MINUTES_MS
27+
status === MinigraphStatus.CONNECTED && lastPing && Date.now() - lastPing > THREE_MINUTES_MS
2928
);
3029
}
3130

3231
private checkMothershipClientTimeout() {
3332
if (this.hasMothershipClientTimedOut()) {
34-
const minutes = this.msToMinutes(this.THREE_MINUTES_MS);
33+
const minutes = this.msToMinutes(THREE_MINUTES_MS);
3534
this.logger.warn(`NO PINGS RECEIVED IN ${minutes} MINUTES, SOCKET MUST BE RECONNECTED`);
3635
this.connectionService.setConnectionStatus({
3736
status: MinigraphStatus.PING_FAILURE,
@@ -43,21 +42,17 @@ export class TimeoutCheckerJob {
4342
private msToMinutes(ms: number) {
4443
return ms / 1000 / 60;
4544
}
46-
47-
private checkRemoteAccessTimeout() {
48-
// todo: implement
49-
}
50-
45+
5146
async checkForTimeouts() {
52-
this.subscriptionHandler.clearStaleSubscriptions({ maxAgeMs: this.THREE_MINUTES_MS });
47+
this.subscriptionHandler.clearStaleSubscriptions({ maxAgeMs: THREE_MINUTES_MS });
5348
this.checkMothershipClientTimeout();
54-
this.checkRemoteAccessTimeout();
49+
this.dynamicRemoteAccess.checkForTimeout();
5550
}
5651

5752
start() {
5853
this.stop();
5954
const callback = () => this.checkForTimeouts();
60-
const interval = setInterval(callback, this.ONE_MINUTE_MS);
55+
const interval = setInterval(callback, ONE_MINUTE_MS);
6156
this.schedulerRegistry.addInterval(this.jobName, interval);
6257
}
6358

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Injectable, Logger } from '@nestjs/common';
2+
import { ConfigService } from '@nestjs/config';
3+
4+
import { DynamicRemoteAccessState, makeDisabledDynamicRemoteAccessState } from '../config.entity.js';
5+
import { ONE_MINUTE_MS } from '../helpers/consts.js';
6+
7+
@Injectable()
8+
export class DynamicRemoteAccessStateService {
9+
private readonly logger = new Logger(DynamicRemoteAccessStateService.name);
10+
11+
constructor(private readonly configService: ConfigService) {}
12+
13+
get state() {
14+
return this.configService.getOrThrow<DynamicRemoteAccessState>('connect.dynamicRemoteAccess');
15+
}
16+
17+
checkForTimeout() {
18+
const state = this.state;
19+
if (state.lastPing && Date.now() - state.lastPing > ONE_MINUTE_MS) {
20+
this.logger.warn('No pings received in 1 minute, disabling dynamic remote access');
21+
this.configService.set(
22+
'connect.dynamicRemoteAccess',
23+
makeDisabledDynamicRemoteAccessState()
24+
);
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)