Skip to content

Commit

Permalink
memory clean up (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
godind authored Mar 30, 2024
1 parent 1133b76 commit ad2c5a5
Show file tree
Hide file tree
Showing 48 changed files with 360 additions and 16,524 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mxtommy/kip",
"version": "2.9.0",
"version": "2.9.1-beta.1",
"description": "An advanced and versatile marine instrumentation package to display Signal K data.",
"license": "MIT",
"author": {
Expand Down
19 changes: 10 additions & 9 deletions src/app/alarm-menu/alarm-menu.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { NotificationsService, Alarm, IAlarmInfo } from '../core/services/notifications.service';
import { AppSettingsService } from '../core/services/app-settings.service';
import { NotificationsService, Alarm } from '../core/services/notifications.service';
import { Subscription } from 'rxjs';
import { INotificationConfig } from '../core/interfaces/app-settings.interfaces';
import { MatDivider } from '@angular/material/divider';
Expand Down Expand Up @@ -34,8 +33,9 @@ interface IMenuItem {
})
export class AlarmMenuComponent implements OnInit, OnDestroy {

private alarmSub: Subscription;
private notificationServiceSettings: Subscription;
private alarmSubscription: Subscription = null;
private notificationServiceSettingsSubscription: Subscription = null;
private alarmInfoSubscription: Subscription = null;

alarms: { [path: string]: Alarm };
notificationAlarms: { [path: string]: Alarm };
Expand All @@ -54,14 +54,14 @@ export class AlarmMenuComponent implements OnInit, OnDestroy {
constructor(
private notificationsService: NotificationsService,
) {
this.notificationServiceSettings = this.notificationsService.getNotificationServiceConfigAsO().subscribe((config: INotificationConfig) => {
this.notificationServiceSettingsSubscription = this.notificationsService.getNotificationServiceConfigAsO().subscribe((config: INotificationConfig) => {
this.notificationConfig = config;
});
}

ngOnInit() {
// init Alarm stream
this.alarmSub = this.notificationsService.getAlarms().subscribe(
this.alarmSubscription = this.notificationsService.getAlarms().subscribe(
message => {
this.notificationAlarms = message;
// Disabling notifications is done at the service level. No need to handle it here
Expand All @@ -70,7 +70,7 @@ export class AlarmMenuComponent implements OnInit, OnDestroy {
);

// init alarm info
this.notificationsService.getAlarmInfoAsO().subscribe(info => {
this.alarmInfoSubscription = this.notificationsService.getAlarmInfoAsO().subscribe(info => {
this.unAckAlarms = info.unackCount;
this.isMuted = info.isMuted;
this.alarmCount = info.alarmCount;
Expand Down Expand Up @@ -188,8 +188,9 @@ export class AlarmMenuComponent implements OnInit, OnDestroy {
}

ngOnDestroy() {
this.notificationServiceSettings.unsubscribe();
this.alarmSub.unsubscribe();
this.notificationServiceSettingsSubscription?.unsubscribe();
this.alarmSubscription?.unsubscribe();
this.alarmInfoSubscription?.unsubscribe();
}

}
17 changes: 6 additions & 11 deletions src/app/app-help/app-help.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Component, OnInit, ViewEncapsulation, Inject } from '@angular/core';
import { Component, OnInit, ViewEncapsulation, Inject, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

import { AppSettingsService } from '../core/services/app-settings.service';
import { MatAccordion, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle, MatExpansionPanelDescription } from '@angular/material/expansion';
import { NgIf } from '@angular/common';
import { MatTabGroup, MatTab, MatTabContent } from '@angular/material/tabs';



@Component({
selector: 'app-help',
templateUrl: './app-help.component.html',
Expand All @@ -25,13 +23,12 @@ import { MatTabGroup, MatTab, MatTabContent } from '@angular/material/tabs';
MatExpansionPanelDescription,
],
})
export class AppHelpComponent implements OnInit {
export class AppHelpComponent implements OnInit, OnDestroy {

unlockStatusSub: Subscription;
unlockStatus: boolean;

step = -1;

step: number = -1;

constructor( private AppSettingsService: AppSettingsService,) {

Expand All @@ -46,14 +43,12 @@ export class AppHelpComponent implements OnInit {
);
}

ngOnDestroy() {
this.unlockStatusSub.unsubscribe();
}

setStep(index: number) {
this.step = index;
}


ngOnDestroy() {
this.unlockStatusSub?.unsubscribe();
}
}

4 changes: 2 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ export class AppComponent implements OnInit, OnDestroy {
private overlayContainer: OverlayContainer,
private LayoutSplitsService: LayoutSplitsService, // needs AppSettingsService
public appSettingsService: AppSettingsService, // needs storage & AppInit
private DatasetService: DatasetService, // needs AppSettingsService & SignalKService
private DatasetService: DatasetService, // needs AppSettingsService & SignalKDataService
private notificationsService: NotificationsService, // needs AppSettingsService SignalKConnectionService
public authenticationService: AuthenticationService,
private deltaService: SignalKDeltaService,
private appService: AppService,
// below services are needed: first service instantiation after Init Service
private signalKDeltaService: SignalKDeltaService, // needs SignalKService & NotificationsService & SignalKConnectionService
private signalKDeltaService: SignalKDeltaService, // needs SignalKDataService & NotificationsService & SignalKConnectionService
) {}


Expand Down
20 changes: 7 additions & 13 deletions src/app/base-widget/base-widget.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, inject } from '@angular/core';
import { Observable, Observer, OperatorFunction, Subscription, UnaryFunction, delayWhen, filter, map, pipe, retryWhen, sampleTime, tap, throwError, timeout, timer } from 'rxjs';
import { SignalKService, pathRegistrationValue } from '../core/services/signalk.service';
import { Observable, Observer, Subscription, delayWhen, map, retryWhen, sampleTime, tap, throwError, timeout, timer } from 'rxjs';
import { SignalKDataService, pathRegistrationValue } from '../core/services/signalk-data.service';
import { UnitsService } from '../core/services/units.service';
import { ITheme, IWidget, IWidgetSvcConfig } from '../core/interfaces/widgets-interface';
import { cloneDeep, merge } from 'lodash-es';
Expand All @@ -11,12 +11,6 @@ interface IWidgetDataStream {
observable: Observable<pathRegistrationValue>;
};

function filterNullish<T>(): UnaryFunction<Observable<T | null | undefined>, Observable<T>> {
return pipe(
filter(x => x != null) as OperatorFunction<T | null | undefined, T>
);
}

@Component({
template: ''
})
Expand All @@ -31,7 +25,7 @@ export abstract class BaseWidgetComponent {
/** Single Observable Subscription object for all data paths */
private dataSubscription: Subscription = undefined;
/** Signal K data stream service to obtain/observe server data */
protected signalKService = inject(SignalKService);
protected signalKDataService = inject(SignalKDataService);
/** Unit conversion service to convert a wide range of numerical data formats */
protected unitsService = inject(UnitsService);

Expand Down Expand Up @@ -87,7 +81,7 @@ export abstract class BaseWidgetComponent {
} else {
this.dataStream.push({
pathName: pathKey,
observable: this.signalKService.subscribePath(this.widgetProperties.uuid, this.widgetProperties.config.paths[pathKey].path, this.widgetProperties.config.paths[pathKey].source)
observable: this.signalKDataService.subscribePath(this.widgetProperties.uuid, this.widgetProperties.config.paths[pathKey].path, this.widgetProperties.config.paths[pathKey].source)
});
}
})
Expand Down Expand Up @@ -146,7 +140,7 @@ export abstract class BaseWidgetComponent {
with: () =>
throwError(() => {
console.log(timeoutErrorMsg + path);
this.signalKService.timeoutPathObservable(path, pathType)
this.signalKDataService.timeoutPathObservable(path, pathType)
}
)
}),
Expand Down Expand Up @@ -177,7 +171,7 @@ export abstract class BaseWidgetComponent {
with: () =>
throwError(() => {
console.log(timeoutErrorMsg + path);
this.signalKService.timeoutPathObservable(path, pathType)
this.signalKDataService.timeoutPathObservable(path, pathType)
}
)
}),
Expand Down Expand Up @@ -255,7 +249,7 @@ export abstract class BaseWidgetComponent {
this.dataSubscription.unsubscribe();
// Cleanup KIP's pathRegister
Object.keys(this.widgetProperties.config.paths).forEach(pathKey => {
this.signalKService.unsubscribePath(this.widgetProperties.uuid, this.widgetProperties.config.paths[pathKey].path);
this.signalKDataService.unsubscribePath(this.widgetProperties.uuid, this.widgetProperties.config.paths[pathKey].path);
}
);
this.dataSubscription = undefined;
Expand Down
12 changes: 9 additions & 3 deletions src/app/core/interceptors/authentication-interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@

import { Injectable } from '@angular/core';
import { Injectable, OnDestroy } from '@angular/core';
import { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'
import { AuthenticationService, IAuthorizationToken } from '../services/authentication.service';
import { Subscription } from 'rxjs';

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {
export class AuthenticationInterceptor implements HttpInterceptor, OnDestroy {
private authToken: IAuthorizationToken = null;
private authTokenSubscription: Subscription = null;

constructor(private auth: AuthenticationService) {
// Observe the auth token from the Auth service.
this.auth.authToken$.subscribe((token: IAuthorizationToken) => {
this.authTokenSubscription = this.auth.authToken$.subscribe((token: IAuthorizationToken) => {
this.authToken = token;
});
}
Expand All @@ -27,4 +29,8 @@ export class AuthenticationInterceptor implements HttpInterceptor {
// send cloned request with header to the next handler.
return next.handle(authReq);
}

ngOnDestroy(): void {
this.authTokenSubscription?.unsubscribe();
}
}
12 changes: 9 additions & 3 deletions src/app/core/services/app-initNetwork.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ import { StorageService } from './storage.service';
* @usage must return a Promise in all cases or will block app from loading.
* All execution in this service delays app start. Keep code small and simple.
**/
import { Injectable } from '@angular/core';
import { Injectable, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';
import { IConnectionConfig } from "../interfaces/app-settings.interfaces";
import { SignalKConnectionService } from "./signalk-connection.service";
import { AuthenticationService } from './authentication.service';
import { DefaultConnectionConfig } from '../../../default-config/config.blank.const';
import { Subscription } from 'rxjs';

const configFileVersion = 9; // used to change the Signal K configuration storage file name (ie. 9.0.0.json) that contains the configuration definitions. Applies only to remote storage.

@Injectable()
export class AppNetworkInitService {
export class AppNetworkInitService implements OnDestroy {
private config: IConnectionConfig;
private isLoggedIn;
private loggedInSubscription: Subscription = null;

constructor (
private connection: SignalKConnectionService,
Expand All @@ -29,7 +31,7 @@ export class AppNetworkInitService {
private storage: StorageService, // early boot up for AppSetting svc
)
{
this.auth.isLoggedIn$.subscribe((isLoggedIn) => {
this.loggedInSubscription = this.auth.isLoggedIn$.subscribe((isLoggedIn) => {
this.isLoggedIn = isLoggedIn;
})
}
Expand Down Expand Up @@ -100,4 +102,8 @@ export class AppNetworkInitService {
console.log(`[AppInit Network Service] Upgrading Connection version from 9 to 10`);
}
}

ngOnDestroy(): void {
this.loggedInSubscription?.unsubscribe();
}
}
34 changes: 24 additions & 10 deletions src/app/core/services/app-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@ import { IStreamStatus, SignalKDeltaService } from './signalk-delta.service';
import { NotificationsService } from './notifications.service';
import { IConnectionConfig } from '../interfaces/app-settings.interfaces';
import { AppSettingsService } from './app-settings.service';
import { Injectable } from '@angular/core';
import { SignalKService } from './signalk.service';
import { Observable } from 'rxjs';
import { Injectable, OnDestroy } from '@angular/core';
import { SignalKDataService } from './signalk-data.service';
import { Observable, Subscription } from 'rxjs';

const modePath: string = 'self.environment.mode';

@Injectable({
providedIn: 'root'
})
export class AppService {
export class AppService implements OnDestroy {
public autoNightMode: boolean; // from Config value
private sunValue: string = 'day';
private dayTheme: string;
private autoNightDeltaStatus: Subscription = null;
private autoNightModeSubscription: Subscription = null;
private autoNightModePathSubscription: Subscription = null;
private autoNightModeThemeSubscription: Subscription = null;
private pathTimer = null;

constructor(
private settings: AppSettingsService,
private delta: SignalKDeltaService,
private sk: SignalKService,
private sk: SignalKDataService,
private notification: NotificationsService
) {
this.autoNightMode = this.settings.getAutoNightMode();
Expand All @@ -28,26 +33,27 @@ export class AppService {

private autoNightModeObserver(): void {
let deltaStatus = this.delta.getDataStreamStatusAsO(); // wait for delta service to start
deltaStatus.subscribe(stat => {
this.autoNightDeltaStatus = deltaStatus.subscribe(stat => {
stat as IStreamStatus;
if(stat.operation == 2) {

setTimeout(() => { // Wait for path data to come in on startup
this.pathTimer = setTimeout(() => { // Wait for path data to come in on startup
const autoNightMode: Observable<boolean> = this.settings.getAutoNightModeAsO();
autoNightMode.subscribe(mode => {

this.autoNightModeSubscription = autoNightMode.subscribe(mode => {
this.autoNightMode = mode;
if (mode) {
if (this.sk.getPathObject(modePath) !== null) {

// capture none nightMode theme name changes
this.settings.getThemeNameAsO().subscribe(theme => {
this.autoNightModeThemeSubscription = this.settings.getThemeNameAsO().subscribe(theme => {
if (theme != 'nightMode')
this.dayTheme = theme;
});

const connConf: IConnectionConfig = this.settings.getConnectionConfig(); // get app UUUID

this.sk.subscribePath(connConf.kipUUID, modePath, 'default').subscribe(mode => {
this.autoNightModePathSubscription = this.sk.subscribePath(connConf.kipUUID, modePath, 'default').subscribe(mode => {
if (mode.value == 'night' && this.sunValue != mode.value) {
this.sunValue = mode.value;
this.settings.setThemeName('nightMode');
Expand Down Expand Up @@ -76,4 +82,12 @@ export class AppService {
this.settings.setAutoNightMode(isEnabled);
}

ngOnDestroy(): void {
this.autoNightModeSubscription?.unsubscribe();
this.autoNightModePathSubscription?.unsubscribe();
this.autoNightModeThemeSubscription?.unsubscribe();
this.autoNightDeltaStatus?.unsubscribe();
clearTimeout(this.pathTimer);
}

}
3 changes: 2 additions & 1 deletion src/app/core/services/app-settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export class AppSettingsService {
}

private upgradeAppConfig(config: any): void {
console.warn("[AppSettings Service] Configuration upgrade required");

let upgradedAppConfig: IAppConfig = {
configVersion: 9,
Expand Down Expand Up @@ -192,7 +193,7 @@ export class AppSettingsService {
maxDataPoints: null,
sampleTime: null,
smoothingPeriod: null,
label: `${oldDS.path}, Source: ${oldDS.signalKSource}, Scale: second, Period: ${oldDS.dataPoints}`
label: `${oldDS.path}, Source: ${oldDS.signalKSource}, Scale: Needs upgrade, Period: ${oldDS.dataPoints}`
};

upgradedAppConfig.dataSets.push(upgradedDS);
Expand Down
Loading

0 comments on commit ad2c5a5

Please sign in to comment.