X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FUIServiceWorkerBroadcastChannel.ts;h=5f77b0e3450768bc79a87cacbfa744e77c3f268b;hb=721f634101285d00d1c695031ed357b090d1a8f3;hp=a94f2b31d263fa086153984c61d36a8ddffb4aa0;hpb=53e5fd67dea2dd83ec9c34d963dd6e502ec46f5c;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/UIServiceWorkerBroadcastChannel.ts b/src/charging-station/UIServiceWorkerBroadcastChannel.ts index a94f2b31..5f77b0e3 100644 --- a/src/charging-station/UIServiceWorkerBroadcastChannel.ts +++ b/src/charging-station/UIServiceWorkerBroadcastChannel.ts @@ -1,37 +1,107 @@ -import BaseError from '../exception/BaseError'; -import { BroadcastChannelResponse, MessageEvent } from '../types/WorkerBroadcastChannel'; -import logger from '../utils/Logger'; -import type AbstractUIService from './ui-server/ui-services/AbstractUIService'; -import WorkerBroadcastChannel from './WorkerBroadcastChannel'; +import { type AbstractUIService, WorkerBroadcastChannel } from './internal'; +import { + type BroadcastChannelResponse, + type BroadcastChannelResponsePayload, + type MessageEvent, + type ResponsePayload, + ResponseStatus, +} from '../types'; +import { Utils, logger } from '../utils'; const moduleName = 'UIServiceWorkerBroadcastChannel'; -export default class UIServiceWorkerBroadcastChannel extends WorkerBroadcastChannel { - private uiService: AbstractUIService; +type Responses = { + responsesExpected: number; + responsesReceived: number; + responses: BroadcastChannelResponsePayload[]; +}; + +export class UIServiceWorkerBroadcastChannel extends WorkerBroadcastChannel { + private readonly uiService: AbstractUIService; + private readonly responses: Map; constructor(uiService: AbstractUIService) { super(); this.uiService = uiService; this.onmessage = this.responseHandler.bind(this) as (message: MessageEvent) => void; this.onmessageerror = this.messageErrorHandler.bind(this) as (message: MessageEvent) => void; + this.responses = new Map(); } private responseHandler(messageEvent: MessageEvent): void { - if (this.isRequest(messageEvent.data)) { + const validatedMessageEvent = this.validateMessageEvent(messageEvent); + if (validatedMessageEvent === false) { + return; + } + if (this.isRequest(validatedMessageEvent.data) === true) { return; } - if (Array.isArray(messageEvent.data) === false) { - throw new BaseError('Worker broadcast channel protocol response is not an array'); + const [uuid, responsePayload] = validatedMessageEvent.data as BroadcastChannelResponse; + if (this.responses.has(uuid) === false) { + this.responses.set(uuid, { + responsesExpected: this.uiService.getBroadcastChannelExpectedResponses(uuid), + responsesReceived: 1, + responses: [responsePayload], + }); + } else if ( + this.responses.get(uuid)?.responsesReceived <= this.responses.get(uuid)?.responsesExpected + ) { + this.responses.get(uuid).responsesReceived++; + this.responses.get(uuid)?.responses.push(responsePayload); } - const [uuid, responsePayload] = messageEvent.data as BroadcastChannelResponse; + if ( + this.responses.get(uuid)?.responsesReceived === this.responses.get(uuid)?.responsesExpected + ) { + this.uiService.sendResponse(uuid, this.buildResponsePayload(uuid)); + this.responses.delete(uuid); + this.uiService.deleteBroadcastChannelRequest(uuid); + } + } - this.uiService.sendResponse(uuid, responsePayload); + private buildResponsePayload(uuid: string): ResponsePayload { + const responsesStatus = + this.responses + .get(uuid) + ?.responses.every(({ status }) => status === ResponseStatus.SUCCESS) === true + ? ResponseStatus.SUCCESS + : ResponseStatus.FAILURE; + return { + status: responsesStatus, + hashIdsSucceeded: this.responses + .get(uuid) + ?.responses.filter(({ hashId }) => !Utils.isNullOrUndefined(hashId)) + .map(({ status, hashId }) => { + if (status === ResponseStatus.SUCCESS) { + return hashId; + } + }), + ...(responsesStatus === ResponseStatus.FAILURE && { + hashIdsFailed: this.responses + .get(uuid) + ?.responses.filter(({ hashId }) => !Utils.isNullOrUndefined(hashId)) + .map(({ status, hashId }) => { + if (status === ResponseStatus.FAILURE) { + return hashId; + } + }), + }), + ...(responsesStatus === ResponseStatus.FAILURE && { + responsesFailed: this.responses + .get(uuid) + ?.responses.filter((response) => !Utils.isNullOrUndefined(response)) + .map((response) => { + if (response.status === ResponseStatus.FAILURE) { + return response; + } + }), + }), + }; } private messageErrorHandler(messageEvent: MessageEvent): void { logger.error( `${this.uiService.logPrefix(moduleName, 'messageErrorHandler')} Error at handling message:`, - { messageEvent, messageEventData: messageEvent.data } + messageEvent ); } }