@5minds/processcube_engine
Version:
The ProcessCube Engine. Stores and executes BPMNs.
166 lines • 8.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReceiveTaskInstanceHandler = void 0;
const processcube_engine_sdk_1 = require("@5minds/processcube_engine_sdk");
const index_1 = require("../../../Contracts/index");
const AbortablePromise_1 = require("../../../Tools/AbortablePromise");
const ActivityInstanceHandler_1 = require("./ActivityInstanceHandler");
class ReceiveTaskInstanceHandler extends ActivityInstanceHandler_1.ActivityInstanceHandler {
messageEventService;
onMessageSubscriptionId;
acknowledgeEventReceivedId;
triggerValue;
loggerNamespace = 'receive_task';
constructor(eventMiddlewareHandler, flowNodeInstanceDatabaseAdapter, messageEventService, activityHandler, processInstance, previousFlowNodeInstanceId, instanceContext) {
super(eventMiddlewareHandler, flowNodeInstanceDatabaseAdapter, activityHandler, processInstance, previousFlowNodeInstanceId, instanceContext);
this.messageEventService = messageEventService;
}
get receiveTask() {
return this.flowNode;
}
async persistOnSuspend() {
await super.persistOnSuspend(undefined, {
type: index_1.FlowNodeInstanceDataTypes.receiveTask,
eventName: this.receiveTask.messageEventDefinition.name,
triggerValue: this.triggerValue,
});
}
async persistOnExit(dataObjectValues) {
await super.persistOnExit(dataObjectValues, {
type: index_1.FlowNodeInstanceDataTypes.receiveTask,
eventName: this.receiveTask.messageEventDefinition.name,
triggerValue: this.triggerValue,
triggeredByFlowNodeInstanceId: this.triggeredByFlowNodeInstanceId,
});
}
async afterExecute() {
await super.afterExecute();
if (this.acknowledgeEventReceivedId) {
this.messageEventService.acknowledge(this.acknowledgeEventReceivedId);
}
this.messageEventService.unsubscribe(this.onMessageSubscriptionId);
}
async runHandler(executionCanceledCallback) {
this.activityHandler.abortSignal.throwIfAborted();
this.logger.debug(`Executing ReceiveTask instance.`);
return new AbortablePromise_1.AbortablePromise(async (resolve, reject, onCancel) => {
try {
if (executionCanceledCallback) {
onCancel(() => {
if (this.state === processcube_engine_sdk_1.FlowNodeInstanceState.suspended || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.running || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.canceled) {
executionCanceledCallback();
}
});
}
await this.parseTriggerValue();
const receivedMessage = await this.suspendAndWaitForMessage();
this.activityHandler.abortSignal.throwIfAborted();
const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary();
if (canceledByEventBasedGateway) {
this.cancel();
this.activityHandler.abort();
return;
}
this.activityHandler.abortSignal.throwIfAborted();
this.currentToken = receivedMessage?.currentToken ?? {};
return resolve();
}
catch (error) {
return reject(error);
}
}, { signal: this.activityHandler.abortSignal });
}
async resumeAfterSuspend(flowNodeInstance, resumptionCanceledCallback) {
this.activityHandler.abortSignal.throwIfAborted();
return new AbortablePromise_1.AbortablePromise(async (resolve, reject, onCancel) => {
try {
if (resumptionCanceledCallback) {
onCancel(() => {
if (this.state === processcube_engine_sdk_1.FlowNodeInstanceState.suspended || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.running || this.state === processcube_engine_sdk_1.FlowNodeInstanceState.canceled) {
resumptionCanceledCallback();
}
});
}
this.triggerValue = flowNodeInstance.triggerValue;
const receivedMessage = await this.waitForMessage();
this.activityHandler.abortSignal.throwIfAborted();
const canceledByEventBasedGateway = await this.passTriggerThroughEventBasedGatwwayIfNecessary();
if (canceledByEventBasedGateway) {
this.cancel();
this.activityHandler.abort();
return;
}
this.activityHandler.abortSignal.throwIfAborted();
this.currentToken = receivedMessage?.currentToken ?? {};
return resolve();
}
catch (error) {
return reject(error);
}
}, { signal: this.activityHandler.abortSignal });
}
async suspendAndWaitForMessage() {
const waitForMessagePromise = this.waitForMessage();
await this.persistOnSuspend();
return waitForMessagePromise;
}
async waitForMessage() {
this.logger.debug(`Waiting for a "${this.receiveTask.messageEventDefinition.name}" Message`);
this.activityHandler.abortSignal.throwIfAborted();
return new Promise((resolve) => {
const messageReceivedCallback = async (message) => {
if (this.activityHandler.abortSignal.aborted) {
this.messageEventService.acknowledge(message.eventId);
return;
}
this.logger.debug(`ReceiveTask instance ${this.flowNodeInstanceId} received message:`, {
receivedMessage: message,
});
this.triggeredByFlowNodeInstanceId = message.flowNodeInstanceId;
this.acknowledgeEventReceivedId = message.eventId;
resolve(message);
};
this.onMessageSubscriptionId = this.messageEventService.onMessage(this.receiveTask.messageEventDefinition.name, messageReceivedCallback, true, this.processInstance.getProcessInstanceId(), this.triggerValue, this.receiveTask.messageChannel);
});
}
async passTriggerThroughEventBasedGatwwayIfNecessary() {
const processInstanceId = this.processInstance.getProcessInstanceId();
const eventBasedGatewayIocKey = `EventBasedGatewayHandlerInstance-${processInstanceId}-${this.previousFlowNodeInstanceId}`;
const isEventBasedGatewayRegistered = this.processInstance.getContainer().isBound(eventBasedGatewayIocKey);
if (!isEventBasedGatewayRegistered) {
return false;
}
const eventBasedGateway = this.processInstance.getContainer().get(eventBasedGatewayIocKey);
if (eventBasedGateway.hasBeenTriggered) {
return true;
}
const triggerConfirmedByEventBasedGateway = await eventBasedGateway.evaluateAndTriggerCatchEvent(this.flowNodeInstanceId);
return !triggerConfirmedByEventBasedGateway;
}
async parseTriggerValue() {
if (!this.receiveTask.triggerValueInToken) {
return;
}
try {
this.triggerValue = await this.executeRuntimeExpressionOnInstanceContext({
expression: `\`${this.receiveTask.triggerValueInToken}\``,
currentFlowNode: this.receiveTask,
currentToken: this.currentToken,
previousFlowNode: this.processInstance.getProcessModelFacade().getPreviousFlowNodesFor(this.flowNode)?.pop(),
allowNonObjectResults: true,
});
}
catch (error) {
const errorToThrow = new processcube_engine_sdk_1.BadRequestError(`ReceiveTask configuration for setTriggerValueInToken is invalid.`, error.category);
errorToThrow.additionalInformation = {
setTriggerValueInToken: this.receiveTask.triggerValueInToken,
processInstanceId: this.processInstance.getProcessInstanceId(),
correlationId: this.processInstance.getCorrelationId(),
};
this.logger.error(errorToThrow.message);
throw errorToThrow;
}
}
}
exports.ReceiveTaskInstanceHandler = ReceiveTaskInstanceHandler;
//# sourceMappingURL=ReceiveTaskInstanceHandler.js.map