[SEBA-240] Better handling of Observable subscription and triggers to prevent the GUI to freeze when multiple notifications are received
Change-Id: I22380409bdb12d6661ff3fbc911d7412776d9e24
diff --git a/package.json b/package.json
index d5aeca9..b231ad6 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "version": "1.0.3",
+ "version": "1.0.4-dev",
"dependencies": {
"angular": "1.6.3",
"angular-animate": "1.6.3",
diff --git a/src/app/datasources/stores/model.store.ts b/src/app/datasources/stores/model.store.ts
index b26c262..7da92f6 100644
--- a/src/app/datasources/stores/model.store.ts
+++ b/src/app/datasources/stores/model.store.ts
@@ -41,8 +41,11 @@
'XosDebouncer',
'XosModeldefsCache'
];
+
private _collections: any; // NOTE contains a map of {model: BehaviourSubject}
private efficientNext: any; // NOTE debounce next
+ private _ws_subscriptions: any = {}; // NOTE contains a list of models that already subscribed to the WS obeservable
+
constructor(
private $log: ng.ILogService,
private webSocket: IWSEventService,
@@ -67,26 +70,25 @@
this._collections[modelName] = new BehaviorSubject([]); // NOTE maybe this can be created when we get response from the resource
this.loadInitialData(modelName, apiUrl);
}
- // else manually trigger the next with the last know value to trigger the subscribe method of who's requesting this data
- else {
- this.$log.debug(`[XosModelStore] QUERY: Calling "next" on: ${modelName}`);
- this.efficientNext(this._collections[modelName]);
- }
- // NOTE do we need to subscribe every time we query?
- this.webSocket.list()
- .filter((e: IWSEvent) => e.model === modelName)
- .subscribe(
- (event: IWSEvent) => {
- if (event.deleted) {
- this.storeHelpers.removeItemFromCollection(event, this._collections[modelName]);
- }
- else {
- this.storeHelpers.updateCollection(event, this._collections[modelName]);
- }
- },
- err => this.$log.error
- );
+ if (!angular.isDefined(this._ws_subscriptions[modelName])) {
+ // NOTE we need to subscribe to the WS observable only once
+ const s = this.webSocket.list()
+ .filter((e: IWSEvent) => e.model === modelName)
+ .subscribe(
+ (event: IWSEvent) => {
+ this.$log.debug(`[XosModelStore] WS Event`, event);
+ if (event.deleted) {
+ this.storeHelpers.removeItemFromCollection(event, this._collections[modelName]);
+ }
+ else {
+ this.storeHelpers.updateCollection(event, this._collections[modelName]);
+ }
+ },
+ err => this.$log.error
+ );
+ this._ws_subscriptions[modelName] = s;
+ }
return this._collections[modelName].asObservable();
}
@@ -130,6 +132,7 @@
}
this.query(modelName)
+ .filter((res) => _.findIndex(res, {id: modelId}) > -1)
.subscribe((res) => {
const model = _.find(res, {id: modelId});
if (model) {
diff --git a/src/app/datasources/websocket/global.ts b/src/app/datasources/websocket/global.ts
index 54c7209..372821c 100644
--- a/src/app/datasources/websocket/global.ts
+++ b/src/app/datasources/websocket/global.ts
@@ -89,6 +89,7 @@
}
public list() {
+ this.$log.debug(`[WebSocket] Active subscriptions: ${this._events.observers.length}`);
return this._events.asObservable();
}