@5minds/processcube_engine
Version:
The ProcessCube Engine. Stores and executes BPMNs.
137 lines • 7.29 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventBasedGatewayHandler = void 0;
const async_lock_1 = __importDefault(require("async-lock"));
const inversify_1 = require("inversify");
const processcube_engine_sdk_1 = require("@5minds/processcube_engine_sdk");
const index_1 = require("../../../Tools/DatabaseAdaptersSequelize/index");
const EventMiddlewareHandler_1 = require("../../../Tools/EventMiddlewareHandler");
const ProcessInstance_1 = require("../../ProcessInstance");
const FlowNodeHandlerFactory_1 = require("../FlowNodeHandlerFactory");
const GatewayHandler_1 = require("./GatewayHandler");
const lock = new async_lock_1.default({ maxPending: 100000 });
let EventBasedGatewayHandler = class EventBasedGatewayHandler extends GatewayHandler_1.GatewayHandler {
triggered = false;
connectedCatchEvents = [];
constructor(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, eventBasedGatewayModel, processInstance) {
super(eventMiddlewareHandler, flowNodeHandlerFactory, flowNodeInstanceDatabaseAdapter, eventBasedGatewayModel, processInstance, 'event_based_gateway_handler');
}
get hasBeenTriggered() {
return this.triggered;
}
get eventBasedGateway() {
return this.flowNode;
}
get iocKey() {
const processInstanceId = this.processInstance.getProcessInstanceId();
return `EventBasedGatewayHandlerInstance-${processInstanceId}-${this.flowNodeInstanceId}`;
}
/**
* Takes a Catch Event Handler Instance ID and cancels all OTHER connected catch event instances,
* if the given Flow Node Instance ID is elligble for triggering the gateway.
*
* @param flowNodeInstanceId The Instance ID of the triggering Catch Event.
* @returns True, if the gateway was triggered.
*/
async evaluateAndTriggerCatchEvent(flowNodeInstanceId) {
return lock.acquire(`trigger-event-based-gateway-${this.flowNodeInstanceId}`, async () => {
if (this.triggered) {
return false;
}
const connectedHandler = this.connectedCatchEvents.find((handler) => handler.getInstanceId() === flowNodeInstanceId);
if (!connectedHandler) {
return false;
}
this.triggered = true;
for (const handler of this.connectedCatchEvents.filter((handler) => handler.getInstanceId() !== flowNodeInstanceId)) {
handler.cancel(this.processToken);
}
this.connectedCatchEvents = [];
this.cleanup();
await super.persistOnExit();
await super.afterExecute();
return true;
});
}
// Bind this instance to the container, so that the intermediate catch event handlers can access it.
async beforeExecute(resolveFunction, rejectFunction, resumedFlowNodeInstances) {
await super.beforeExecute(resolveFunction, rejectFunction, resumedFlowNodeInstances);
const container = this.processInstance.getContainer();
if (!container.isBound(this.iocKey)) {
container.bind(this.iocKey).toConstantValue(this);
}
}
// Because the gateway needs to wait for one of the follow-up events, it cannot persist its final state until that event occurs.
// But since the handler must resolve with a list of FlowNode Instances to execute after him, we must override the hook, to prevent an early state transition.
async afterExecute() { }
async persistOnExit() { }
async persistOnError(error, typeData) {
await this.cleanup();
await super.persistOnError(error, typeData);
}
async persistOnTerminate(typeData) {
this.cleanup();
await super.persistOnTerminate(typeData);
}
async startExecution() {
this.logger.debug(`Executing EventBasedGateway instance.`);
return this.executeHandler();
}
async executeHandler() {
const connectedFlowNodes = this.processInstance.getProcessModelFacade().getNextFlowNodesFor(this.eventBasedGateway);
return connectedFlowNodes;
}
async resumeAfterExit(allFlowNodeInstances) {
const intermediateCatchEventInstances = allFlowNodeInstances.filter((flowNodeInstance) => {
return flowNodeInstance.previousFlowNodeInstanceId === this.flowNodeInstanceId;
});
const triggeredCatchEvent = intermediateCatchEventInstances.find((intermediateCatchEventInstance) => intermediateCatchEventInstance.state !== processcube_engine_sdk_1.FlowNodeInstanceState.canceled);
const nextFlowNode = this.processInstance.getProcessModelFacade().getFlowNodeById(triggeredCatchEvent.flowNodeId);
return [nextFlowNode];
}
async handleNextFlowNode(nextFlowNode, allFlowNodeInstancesToResume) {
const nextFlowNodeInstance = allFlowNodeInstancesToResume ? this.findNextFlowNodeInstance(allFlowNodeInstancesToResume, nextFlowNode.id) : undefined;
const nextFlowNodeHandler = this.flowNodeHandlerFactory.create(nextFlowNode, this.processInstance);
this.connectedCatchEvents.push(nextFlowNodeHandler);
return new Promise(async (resolve, reject) => {
try {
if (nextFlowNodeInstance) {
await nextFlowNodeHandler.resume(nextFlowNodeInstance, allFlowNodeInstancesToResume, resolve);
}
else {
await nextFlowNodeHandler.execute(this.flowNodeInstanceId, this.processToken, resolve);
}
return resolve();
}
catch (error) {
return reject(error);
}
});
}
async cleanup() {
const container = this.processInstance.getContainer();
if (container.isBound(this.iocKey)) {
await container.unbind(this.iocKey);
}
}
};
exports.EventBasedGatewayHandler = EventBasedGatewayHandler;
exports.EventBasedGatewayHandler = EventBasedGatewayHandler = __decorate([
(0, inversify_1.injectable)(),
__metadata("design:paramtypes", [EventMiddlewareHandler_1.EventMiddlewareHandler,
FlowNodeHandlerFactory_1.FlowNodeHandlerFactory,
index_1.FlowNodeInstanceDatabaseAdapter, Object, ProcessInstance_1.ProcessInstance])
], EventBasedGatewayHandler);
//# sourceMappingURL=EventBasedGatewayHandler.js.map