From 82fa111074a9a4eed94579c0ff734a1564f8f8e6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 19 Nov 2023 10:51:04 +0100 Subject: [PATCH] perf: cache request promise after sending it MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../ocpp/OCPPRequestService.ts | 100 ++++++++++-------- ui/web/src/composables/UIClient.ts | 13 ++- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/charging-station/ocpp/OCPPRequestService.ts b/src/charging-station/ocpp/OCPPRequestService.ts index b1b3edfa..a6993ccd 100644 --- a/src/charging-station/ocpp/OCPPRequestService.ts +++ b/src/charging-station/ocpp/OCPPRequestService.ts @@ -93,8 +93,6 @@ export abstract class OCPPRequestService { messagePayload: JsonType | OCPPError, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand, - responseCallback: ResponseCallback, - errorCallback: ErrorCallback, ) => string; this.validateRequestPayload = this.validateRequestPayload.bind(this) as ( chargingStation: ChargingStation, @@ -381,8 +379,6 @@ export abstract class OCPPRequestService { messagePayload, messageType, commandName, - responseCallback, - errorCallback, ); // Check if wsConnection opened if (chargingStation.isWebSocketConnectionOpened() === true) { @@ -399,27 +395,23 @@ export abstract class OCPPRequestService { ); }, OCPPConstants.OCPP_WEBSOCKET_TIMEOUT); chargingStation.wsConnection?.send(messageToSend, (error?: Error) => { - if (error && params?.skipBufferingOnError === false) { - // Buffer - chargingStation.bufferMessage(messageToSend); - // Reject and keep request in the cache - return reject( - new OCPPError( - ErrorType.GENERIC_ERROR, - `WebSocket errored for buffered message id '${messageId}' with content '${messageToSend}'`, - commandName, - { name: error.name, message: error.message, stack: error.stack } ?? - Constants.EMPTY_FROZEN_OBJECT, - ), - ); - } else if (error) { + clearTimeout(sendTimeout); + if (error) { const ocppError = new OCPPError( ErrorType.GENERIC_ERROR, - `WebSocket errored for non buffered message id '${messageId}' with content '${messageToSend}'`, + `WebSocket errored for ${ + params?.skipBufferingOnError === false ? '' : 'non ' + }buffered message id '${messageId}' with content '${messageToSend}'`, commandName, { name: error.name, message: error.message, stack: error.stack } ?? Constants.EMPTY_FROZEN_OBJECT, ); + if (params?.skipBufferingOnError === false) { + // Buffer + chargingStation.bufferMessage(messageToSend); + // Reject and keep request in the cache + return reject(ocppError); + } // Reject response if (messageType !== MessageType.CALL_MESSAGE) { return reject(ocppError); @@ -427,39 +419,49 @@ export abstract class OCPPRequestService { // Reject and remove request from the cache return errorCallback(ocppError, false); } - clearTimeout(sendTimeout); }); + if (messageType === MessageType.CALL_MESSAGE) { + this.cacheRequestPromise( + chargingStation, + responseCallback, + errorCallback, + messageId, + messagePayload as JsonType, + commandName, + ); + } logger.debug( `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${OCPPServiceUtils.getMessageTypeString( messageType, )} payload: ${messageToSend}`, ); PerformanceStatistics.endMeasure(commandName, beginId); - } else if (params?.skipBufferingOnError === false) { - // Buffer - chargingStation.bufferMessage(messageToSend); + } else { + if (params?.skipBufferingOnError === false) { + // Buffer + chargingStation.bufferMessage(messageToSend); + if (messageType === MessageType.CALL_MESSAGE) { + this.cacheRequestPromise( + chargingStation, + responseCallback, + errorCallback, + messageId, + messagePayload as JsonType, + commandName, + ); + } + } // Reject and keep request in the cache return reject( new OCPPError( ErrorType.GENERIC_ERROR, - `WebSocket closed for buffered message id '${messageId}' with content '${messageToSend}'`, + `WebSocket closed for ${ + params?.skipBufferingOnError === false ? '' : 'non ' + }buffered message id '${messageId}' with content '${messageToSend}'`, commandName, (messagePayload as JsonObject)?.details ?? Constants.EMPTY_FROZEN_OBJECT, ), ); - } else { - const ocppError = new OCPPError( - ErrorType.GENERIC_ERROR, - `WebSocket closed for non buffered message id '${messageId}' with content '${messageToSend}'`, - commandName, - (messagePayload as JsonObject)?.details ?? Constants.EMPTY_FROZEN_OBJECT, - ); - // Reject response - if (messageType !== MessageType.CALL_MESSAGE) { - return reject(ocppError); - } - // Reject and remove request from the cache - return errorCallback(ocppError, false); } // Resolve response if (messageType !== MessageType.CALL_MESSAGE) { @@ -480,8 +482,6 @@ export abstract class OCPPRequestService { messagePayload: JsonType | OCPPError, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand, - responseCallback: ResponseCallback, - errorCallback: ErrorCallback, ): string { let messageToSend: string; // Type of message @@ -490,12 +490,6 @@ export abstract class OCPPRequestService { case MessageType.CALL_MESSAGE: // Build request this.validateRequestPayload(chargingStation, commandName, messagePayload as JsonType); - chargingStation.requests.set(messageId, [ - responseCallback, - errorCallback, - commandName, - messagePayload as JsonType, - ]); messageToSend = JSON.stringify([ messageType, messageId, @@ -528,6 +522,22 @@ export abstract class OCPPRequestService { return messageToSend; } + private cacheRequestPromise( + chargingStation: ChargingStation, + responseCallback: ResponseCallback, + errorCallback: ErrorCallback, + messageId: string, + messagePayload: JsonType, + commandName: RequestCommand | IncomingRequestCommand, + ): void { + chargingStation.requests.set(messageId, [ + responseCallback, + errorCallback, + commandName, + messagePayload, + ]); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public abstract requestHandler( chargingStation: ChargingStation, diff --git a/ui/web/src/composables/UIClient.ts b/ui/web/src/composables/UIClient.ts index 745accdf..841ec3dc 100644 --- a/ui/web/src/composables/UIClient.ts +++ b/ui/web/src/composables/UIClient.ts @@ -159,7 +159,9 @@ export class UIClient { }, 60 * 1000); try { this.ws.send(msg); + this.setResponseHandler(uuid, command, resolve, reject); } catch (error) { + this.deleteResponseHandler(uuid); reject(error); } finally { clearTimeout(sendTimeout); @@ -167,8 +169,6 @@ export class UIClient { } else { throw new Error(`Send request '${command}' message: connection not opened`); } - - this.setResponseHandler(uuid, command, resolve, reject); }); } @@ -182,15 +182,18 @@ export class UIClient { const [uuid, responsePayload] = response; if (this.responseHandlers.has(uuid) === true) { + const { procedureName, resolve, reject } = this.getResponseHandler(uuid)!; switch (responsePayload.status) { case ResponseStatus.SUCCESS: - this.getResponseHandler(uuid)?.resolve(responsePayload); + resolve(responsePayload); break; case ResponseStatus.FAILURE: - this.getResponseHandler(uuid)?.reject(responsePayload); + reject(responsePayload); break; default: - console.error(`Response status not supported: ${responsePayload.status}`); + console.error( + `Response status for procedure '${procedureName}' not supported: '${responsePayload.status}'`, + ); } this.deleteResponseHandler(uuid); } else { -- 2.34.1