Skip to content

Commit

Permalink
Fixed several event listener leaks in DataSync and reduced memory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
mpscholten committed Feb 7, 2022
1 parent e4ef430 commit 78a39d5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
41 changes: 27 additions & 14 deletions lib/IHP/DataSync/ihp-datasync.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class DataSyncController {
}

constructor() {
this.requests = [];
this.pendingRequests = []; // Stores the pending requests, contains objects of shape { requestId, resolve, reject }
this.connection = null;
this.requestIdCounter = 0;
this.receivedFirstResponse = false;
Expand Down Expand Up @@ -86,7 +86,11 @@ class DataSyncController {
onMessage(event) {
const payload = JSON.parse(event.data);
const requestId = payload.requestId;
const request = this.requests.find(request => request.requestId === requestId);
const request = this.pendingRequests.find(request => request.requestId === requestId);

// Remove request from array, as we don't need it anymore. If we don't remove it we will
// build up a lot of memory and slow down the app over time
this.pendingRequests.splice(this.pendingRequests.indexOf(request), 1);

this.receivedFirstResponse = true;

Expand Down Expand Up @@ -122,7 +126,7 @@ class DataSyncController {
return new Promise((resolve, reject) => {
payload.requestId = this.requestIdCounter++;
connection.send(JSON.stringify(payload));
this.requests.push({ requestId: payload.requestId, resolve, reject });
this.pendingRequests.push({ requestId: payload.requestId, resolve, reject });
});
}

Expand Down Expand Up @@ -176,6 +180,10 @@ class DataSubscription {

this.getRecords = this.getRecords.bind(this);
this.subscribe = this.subscribe.bind(this);
this.onDataSyncClosed = this.onDataSyncClosed.bind(this);
this.onDataSyncReconnect = this.onDataSyncReconnect.bind(this);
this.onMessage = this.onMessage.bind(this);


// When a new record is inserted, do we put it at the end or at the beginning?
this.newRecordBehaviour = this.detectNewRecordBehaviour();
Expand All @@ -200,17 +208,9 @@ class DataSubscription {

this.subscriptionId = subscriptionId;

dataSyncController.addEventListener('message', message => {
if (this.isClosed) {
return;
}
if (message.subscriptionId === this.subscriptionId) {
this.receiveUpdate(message);
}
});

dataSyncController.addEventListener('close', this.onDataSyncClosed.bind(this));
dataSyncController.addEventListener('reconnect', this.onDataSyncReconnect.bind(this));
dataSyncController.addEventListener('message', this.onMessage);
dataSyncController.addEventListener('close', this.onDataSyncClosed);
dataSyncController.addEventListener('reconnect', this.onDataSyncReconnect);

this.isConnected = true;
this.records = result;
Expand All @@ -224,6 +224,15 @@ class DataSubscription {
}
}

onMessage(message) {
if (this.isClosed) {
return;
}
if (message.subscriptionId === this.subscriptionId) {
this.receiveUpdate(message);
}
}

receiveUpdate(message) {
const tag = message.tag;
if (tag === 'DidUpdate') {
Expand All @@ -249,6 +258,10 @@ class DataSubscription {

const dataSyncController = DataSyncController.getInstance();
const { subscriptionId } = await dataSyncController.sendMessage({ tag: 'DeleteDataSubscription', subscriptionId: this.subscriptionId });

dataSyncController.removeEventListener('message', this.onMessage);
dataSyncController.removeEventListener('close', this.onDataSyncClosed);
dataSyncController.removeEventListener('reconnect', this.onDataSyncReconnect);

this.isClosed = true;
this.isConnected = false;
Expand Down
2 changes: 2 additions & 0 deletions lib/IHP/DataSync/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class Transaction {
}

await this.dataSyncController.sendMessage({ tag: 'CommitTransaction', id: this.transactionId });
this.onClose();
}

async rollback() {
Expand All @@ -30,6 +31,7 @@ export class Transaction {
}

await this.dataSyncController.sendMessage({ tag: 'RollbackTransaction', id: this.transactionId });
this.onClose();
}

onClose() {
Expand Down

0 comments on commit 78a39d5

Please sign in to comment.