arvo-event-handler 2.3.3 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AbstractArvoEventHandler/index.d.ts +1 -1
- package/dist/ArvoEventHandler/helpers.d.ts +40 -6
- package/dist/ArvoEventHandler/helpers.js +40 -6
- package/dist/ArvoEventHandler/index.d.ts +78 -49
- package/dist/ArvoEventHandler/index.js +152 -83
- package/dist/ArvoEventHandler/types.d.ts +25 -2
- package/dist/ArvoMachine/createMachine.d.ts +208 -0
- package/dist/ArvoMachine/createMachine.js +283 -0
- package/dist/ArvoMachine/index.d.ts +93 -0
- package/dist/ArvoMachine/index.js +160 -0
- package/dist/ArvoMachine/types.d.ts +194 -0
- package/dist/ArvoMachine/utils.d.ts +40 -0
- package/dist/ArvoMachine/utils.js +70 -0
- package/dist/ArvoOrchestrator/error.d.ts +16 -0
- package/dist/ArvoOrchestrator/error.js +43 -0
- package/dist/ArvoOrchestrator/factory.d.ts +28 -0
- package/dist/ArvoOrchestrator/factory.js +56 -0
- package/dist/ArvoOrchestrator/index.d.ts +69 -0
- package/dist/ArvoOrchestrator/index.js +597 -0
- package/dist/ArvoOrchestrator/types.d.ts +98 -0
- package/dist/ArvoResumable/factory.d.ts +50 -0
- package/dist/ArvoResumable/factory.js +70 -0
- package/dist/ArvoResumable/index.d.ts +141 -0
- package/dist/ArvoResumable/index.js +694 -0
- package/dist/ArvoResumable/types.d.ts +147 -0
- package/dist/ArvoResumable/types.js +2 -0
- package/dist/MachineExecutionEngine/index.d.ts +29 -0
- package/dist/MachineExecutionEngine/index.js +132 -0
- package/dist/MachineExecutionEngine/interface.d.ts +14 -0
- package/dist/MachineExecutionEngine/interface.js +2 -0
- package/dist/MachineExecutionEngine/types.d.ts +14 -0
- package/dist/MachineExecutionEngine/types.js +2 -0
- package/dist/MachineMemory/Simple.d.ts +51 -0
- package/dist/MachineMemory/Simple.js +158 -0
- package/dist/MachineMemory/TelemetredSimple.d.ts +51 -0
- package/dist/MachineMemory/TelemetredSimple.js +230 -0
- package/dist/MachineMemory/interface.d.ts +57 -0
- package/dist/MachineMemory/interface.js +2 -0
- package/dist/MachineMemory/utils.d.ts +1 -0
- package/dist/MachineMemory/utils.js +18 -0
- package/dist/MachineRegistry/index.d.ts +37 -0
- package/dist/MachineRegistry/index.js +87 -0
- package/dist/MachineRegistry/interface.d.ts +21 -0
- package/dist/MachineRegistry/interface.js +2 -0
- package/dist/SyncEventResource/index.d.ts +110 -0
- package/dist/SyncEventResource/index.js +280 -0
- package/dist/SyncEventResource/types.d.ts +2 -0
- package/dist/SyncEventResource/types.js +2 -0
- package/dist/index.d.ts +26 -8
- package/dist/index.js +39 -16
- package/dist/utils/SimpleEventBroker/helper.d.ts +166 -0
- package/dist/utils/SimpleEventBroker/helper.js +276 -0
- package/dist/utils/SimpleEventBroker/index.d.ts +96 -0
- package/dist/utils/SimpleEventBroker/index.js +259 -0
- package/dist/utils/SimpleEventBroker/types.d.ts +6 -0
- package/dist/utils/SimpleEventBroker/types.js +2 -0
- package/dist/utils/SimpleEventBroker/utils.d.ts +1 -0
- package/dist/utils/SimpleEventBroker/utils.js +10 -0
- package/dist/{utils.d.ts → utils/index.d.ts} +3 -36
- package/dist/utils/index.js +91 -0
- package/dist/utils/object/index.d.ts +37 -0
- package/dist/utils/object/index.js +63 -0
- package/package.json +5 -3
- package/dist/ArvoEventRouter/helpers.d.ts +0 -19
- package/dist/ArvoEventRouter/helpers.js +0 -22
- package/dist/ArvoEventRouter/index.d.ts +0 -89
- package/dist/ArvoEventRouter/index.js +0 -268
- package/dist/ArvoEventRouter/types.d.ts +0 -36
- package/dist/ArvoEventRouter/utils.d.ts +0 -30
- package/dist/ArvoEventRouter/utils.js +0 -43
- package/dist/MultiArvoEventHandler/helpers.d.ts +0 -48
- package/dist/MultiArvoEventHandler/helpers.js +0 -56
- package/dist/MultiArvoEventHandler/index.d.ts +0 -68
- package/dist/MultiArvoEventHandler/index.js +0 -205
- package/dist/MultiArvoEventHandler/types.d.ts +0 -64
- package/dist/utils.js +0 -191
- /package/dist/{ArvoEventRouter → ArvoMachine}/types.js +0 -0
- /package/dist/{MultiArvoEventHandler → ArvoOrchestrator}/types.js +0 -0
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
28
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
38
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
39
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
40
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
41
|
+
function step(op) {
|
|
42
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
43
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
44
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
45
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
46
|
+
switch (op[0]) {
|
|
47
|
+
case 0: case 1: t = op; break;
|
|
48
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
49
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
50
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
51
|
+
default:
|
|
52
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
53
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
54
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
55
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
56
|
+
if (t[2]) _.ops.pop();
|
|
57
|
+
_.trys.pop(); continue;
|
|
58
|
+
}
|
|
59
|
+
op = body.call(thisArg, _);
|
|
60
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
61
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
65
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
66
|
+
if (ar || !(i in from)) {
|
|
67
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
68
|
+
ar[i] = from[i];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
|
+
};
|
|
73
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
74
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
75
|
+
};
|
|
76
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
77
|
+
exports.ArvoResumable = void 0;
|
|
78
|
+
var api_1 = require("@opentelemetry/api");
|
|
79
|
+
var arvo_core_1 = require("arvo-core");
|
|
80
|
+
var error_1 = require("../ArvoOrchestrator/error");
|
|
81
|
+
var index_1 = require("../SyncEventResource/index");
|
|
82
|
+
var index_2 = require("../utils/index");
|
|
83
|
+
var AbstractArvoEventHandler_1 = __importDefault(require("../AbstractArvoEventHandler"));
|
|
84
|
+
var errors_1 = require("../errors");
|
|
85
|
+
/**
|
|
86
|
+
* ArvoResumable - A stateful orchestration handler for managing distributed workflows
|
|
87
|
+
*
|
|
88
|
+
* ArvoResumable provides a handler-based approach to workflow orchestration that prioritizes
|
|
89
|
+
* explicit control and simplicity over declarative abstractions. It excels at straightforward
|
|
90
|
+
* request-response patterns and linear workflows while maintaining full type safety and
|
|
91
|
+
* contract validation throughout the execution lifecycle.
|
|
92
|
+
*
|
|
93
|
+
* This class addresses fundamental issues in event-driven architecture including:
|
|
94
|
+
* - Contract management with runtime validation and type safety
|
|
95
|
+
* - Graduated complexity allowing simple workflows to remain simple
|
|
96
|
+
* - Unified event handling across initialization and service responses
|
|
97
|
+
* - Explicit state management without hidden abstractions
|
|
98
|
+
*
|
|
99
|
+
* Key capabilities:
|
|
100
|
+
* - Handler-based workflow orchestration with explicit state control
|
|
101
|
+
* - Contract-driven event validation with runtime schema enforcement
|
|
102
|
+
* - Distributed resource locking for transaction safety
|
|
103
|
+
* - Comprehensive OpenTelemetry integration for observability
|
|
104
|
+
* - Automatic error handling with system error event generation
|
|
105
|
+
* - Support for orchestrator chaining and nested workflow patterns
|
|
106
|
+
* - Domain-based event routing and organization
|
|
107
|
+
*
|
|
108
|
+
* Unlike state machine approaches, ArvoResumable uses imperative handler functions
|
|
109
|
+
* that provide direct control over workflow logic. This makes debugging easier and
|
|
110
|
+
* reduces the learning curve for teams familiar with traditional programming patterns.
|
|
111
|
+
*
|
|
112
|
+
* @see {@link createArvoResumable} Factory function for creating instances
|
|
113
|
+
* @see {@link ArvoResumableHandler} Handler interface documentation
|
|
114
|
+
* @see {@link ArvoResumableState} State structure documentation
|
|
115
|
+
*/
|
|
116
|
+
var ArvoResumable = /** @class */ (function (_super) {
|
|
117
|
+
__extends(ArvoResumable, _super);
|
|
118
|
+
function ArvoResumable(param) {
|
|
119
|
+
var _a;
|
|
120
|
+
var _this = _super.call(this) || this;
|
|
121
|
+
_this.executionunits = param.executionunits;
|
|
122
|
+
_this.source = param.contracts.self.type;
|
|
123
|
+
_this.syncEventResource = new index_1.SyncEventResource(param.memory, (_a = param.requiresResourceLocking) !== null && _a !== void 0 ? _a : true);
|
|
124
|
+
_this.contracts = param.contracts;
|
|
125
|
+
_this.handler = param.handler;
|
|
126
|
+
return _this;
|
|
127
|
+
}
|
|
128
|
+
Object.defineProperty(ArvoResumable.prototype, "requiresResourceLocking", {
|
|
129
|
+
get: function () {
|
|
130
|
+
return this.syncEventResource.requiresResourceLocking;
|
|
131
|
+
},
|
|
132
|
+
enumerable: false,
|
|
133
|
+
configurable: true
|
|
134
|
+
});
|
|
135
|
+
Object.defineProperty(ArvoResumable.prototype, "memory", {
|
|
136
|
+
get: function () {
|
|
137
|
+
return this.syncEventResource.memory;
|
|
138
|
+
},
|
|
139
|
+
enumerable: false,
|
|
140
|
+
configurable: true
|
|
141
|
+
});
|
|
142
|
+
Object.defineProperty(ArvoResumable.prototype, "domain", {
|
|
143
|
+
get: function () {
|
|
144
|
+
return this.contracts.self.domain;
|
|
145
|
+
},
|
|
146
|
+
enumerable: false,
|
|
147
|
+
configurable: true
|
|
148
|
+
});
|
|
149
|
+
ArvoResumable.prototype.validateInput = function (event) {
|
|
150
|
+
var _a;
|
|
151
|
+
var resolvedContract = null;
|
|
152
|
+
var contractType;
|
|
153
|
+
var parsedEventDataSchema = arvo_core_1.EventDataschemaUtil.parse(event);
|
|
154
|
+
if (!parsedEventDataSchema) {
|
|
155
|
+
throw new errors_1.ExecutionViolation("Event dataschema resolution failed: Unable to parse dataschema='".concat(event.dataschema, "' for event(id='").concat(event.id, "', type='").concat(event.type, "'). This makes the event opaque and does not allow contract resolution"));
|
|
156
|
+
}
|
|
157
|
+
if (event.type === this.contracts.self.type) {
|
|
158
|
+
contractType = 'self';
|
|
159
|
+
resolvedContract = this.contracts.self.version(parsedEventDataSchema.version);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
contractType = 'service';
|
|
163
|
+
for (var _i = 0, _b = Object.values(this.contracts.services); _i < _b.length; _i++) {
|
|
164
|
+
var contract = _b[_i];
|
|
165
|
+
if (resolvedContract)
|
|
166
|
+
break;
|
|
167
|
+
for (var _c = 0, _d = __spreadArray(__spreadArray([], contract.emitList, true), [contract.systemError], false); _c < _d.length; _c++) {
|
|
168
|
+
var emitType = _d[_c];
|
|
169
|
+
if (resolvedContract)
|
|
170
|
+
break;
|
|
171
|
+
if (event.type === emitType.type) {
|
|
172
|
+
resolvedContract = contract;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!resolvedContract) {
|
|
178
|
+
throw new errors_1.ConfigViolation("Contract resolution failed: No matching contract found for event (id='".concat(event.id, "', type='").concat(event.type, "')"));
|
|
179
|
+
}
|
|
180
|
+
(0, arvo_core_1.logToSpan)({
|
|
181
|
+
level: 'INFO',
|
|
182
|
+
message: "Dataschema resolved: ".concat(event.dataschema, " matches contract(uri='").concat(resolvedContract.uri, "', version='").concat(resolvedContract.version, "')"),
|
|
183
|
+
});
|
|
184
|
+
if (parsedEventDataSchema.uri !== resolvedContract.uri) {
|
|
185
|
+
throw new Error("Contract URI mismatch: ".concat(contractType, " Contract(uri='").concat(resolvedContract.uri, "', type='").concat(resolvedContract.accepts.type, "') does not match Event(dataschema='").concat(event.dataschema, "', type='").concat(event.type, "')"));
|
|
186
|
+
}
|
|
187
|
+
if (!(0, arvo_core_1.isWildCardArvoSematicVersion)(parsedEventDataSchema.version) &&
|
|
188
|
+
parsedEventDataSchema.version !== resolvedContract.version) {
|
|
189
|
+
throw new Error("Contract version mismatch: ".concat(contractType, " Contract(version='").concat(resolvedContract.version, "', type='").concat(resolvedContract.accepts.type, "', uri=").concat(resolvedContract.uri, ") does not match Event(dataschema='").concat(event.dataschema, "', type='").concat(event.type, "')"));
|
|
190
|
+
}
|
|
191
|
+
var validationSchema = contractType === 'self'
|
|
192
|
+
? resolvedContract.accepts.schema
|
|
193
|
+
: ((_a = resolvedContract.emits[event.type]) !== null && _a !== void 0 ? _a : resolvedContract.systemError.schema);
|
|
194
|
+
validationSchema.parse(event.data);
|
|
195
|
+
return { contractType: contractType };
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Creates emittable event from execution result
|
|
199
|
+
* @param event - Source event to emit
|
|
200
|
+
* @param otelHeaders - OpenTelemetry headers
|
|
201
|
+
* @param orchestrationParentSubject - Parent orchestration subject
|
|
202
|
+
* @param sourceEvent - Original triggering event
|
|
203
|
+
* @param selfVersionedContract - The self versioned contract
|
|
204
|
+
* @param initEventId - The id of the event which initiated the orchestration in the first place
|
|
205
|
+
* @param _domain - The domain of the event.
|
|
206
|
+
*
|
|
207
|
+
* @throws {ContractViolation} On schema/contract mismatch
|
|
208
|
+
* @throws {ExecutionViolation} On invalid parentSubject$$ format
|
|
209
|
+
*/
|
|
210
|
+
ArvoResumable.prototype.createEmittableEvent = function (event, otelHeaders, orchestrationParentSubject, sourceEvent, selfVersionedContract, initEventId, _domain) {
|
|
211
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
212
|
+
(0, arvo_core_1.logToSpan)({
|
|
213
|
+
level: 'INFO',
|
|
214
|
+
message: "Creating emittable event: ".concat(event.type),
|
|
215
|
+
});
|
|
216
|
+
var serviceContract = Object.fromEntries(Object.values(this.contracts.services).map(function (item) { return [item.accepts.type, item]; }));
|
|
217
|
+
var schema = null;
|
|
218
|
+
var contract = null;
|
|
219
|
+
var subject = sourceEvent.subject;
|
|
220
|
+
var parentId = sourceEvent.id;
|
|
221
|
+
var domain = _domain === undefined ? ((_b = (_a = sourceEvent.domain) !== null && _a !== void 0 ? _a : this.domain) !== null && _b !== void 0 ? _b : null) : _domain;
|
|
222
|
+
if (event.type === selfVersionedContract.metadata.completeEventType) {
|
|
223
|
+
(0, arvo_core_1.logToSpan)({
|
|
224
|
+
level: 'INFO',
|
|
225
|
+
message: "Creating event for machine workflow completion: ".concat(event.type),
|
|
226
|
+
});
|
|
227
|
+
contract = selfVersionedContract;
|
|
228
|
+
schema = selfVersionedContract.emits[selfVersionedContract.metadata.completeEventType];
|
|
229
|
+
subject = orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : sourceEvent.subject;
|
|
230
|
+
parentId = initEventId;
|
|
231
|
+
domain =
|
|
232
|
+
_domain === undefined ? ((_e = (_d = (_c = selfVersionedContract.domain) !== null && _c !== void 0 ? _c : sourceEvent.domain) !== null && _d !== void 0 ? _d : this.domain) !== null && _e !== void 0 ? _e : null) : _domain;
|
|
233
|
+
}
|
|
234
|
+
else if (serviceContract[event.type]) {
|
|
235
|
+
(0, arvo_core_1.logToSpan)({
|
|
236
|
+
level: 'INFO',
|
|
237
|
+
message: "Creating service event for external system: ".concat(event.type),
|
|
238
|
+
});
|
|
239
|
+
contract = serviceContract[event.type];
|
|
240
|
+
schema = serviceContract[event.type].accepts.schema;
|
|
241
|
+
domain = _domain === undefined ? ((_h = (_g = (_f = contract === null || contract === void 0 ? void 0 : contract.domain) !== null && _f !== void 0 ? _f : sourceEvent.domain) !== null && _g !== void 0 ? _g : this.domain) !== null && _h !== void 0 ? _h : null) : _domain;
|
|
242
|
+
// If the event is to call another orchestrator then, extract the parent subject
|
|
243
|
+
// passed to it and then form an new subject. This allows for event chaining
|
|
244
|
+
// between orchestrators
|
|
245
|
+
if (contract.metadata.contractType === 'ArvoOrchestratorContract') {
|
|
246
|
+
if (event.data.parentSubject$$) {
|
|
247
|
+
try {
|
|
248
|
+
arvo_core_1.ArvoOrchestrationSubject.parse(event.data.parentSubject$$);
|
|
249
|
+
}
|
|
250
|
+
catch (_v) {
|
|
251
|
+
throw new errors_1.ExecutionViolation("Invalid parentSubject$$ for the event(type='".concat(event.type, "', uri='").concat((_j = event.dataschema) !== null && _j !== void 0 ? _j : arvo_core_1.EventDataschemaUtil.create(contract), "').It must be follow the ArvoOrchestrationSubject schema. The easiest way is to use the current orchestration subject by storing the subject via the context block in the machine definition."));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
if (event.data.parentSubject$$) {
|
|
256
|
+
subject = arvo_core_1.ArvoOrchestrationSubject.from({
|
|
257
|
+
orchestator: contract.accepts.type,
|
|
258
|
+
version: contract.version,
|
|
259
|
+
subject: event.data.parentSubject$$,
|
|
260
|
+
domain: domain !== null && domain !== void 0 ? domain : null,
|
|
261
|
+
meta: {
|
|
262
|
+
redirectto: (_k = event.redirectto) !== null && _k !== void 0 ? _k : this.source,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
subject = arvo_core_1.ArvoOrchestrationSubject.new({
|
|
268
|
+
version: contract.version,
|
|
269
|
+
orchestator: contract.accepts.type,
|
|
270
|
+
initiator: this.source,
|
|
271
|
+
domain: domain !== null && domain !== void 0 ? domain : undefined,
|
|
272
|
+
meta: {
|
|
273
|
+
redirectto: (_l = event.redirectto) !== null && _l !== void 0 ? _l : this.source,
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
// This is a execution violation because it indicates faulty parent subject
|
|
280
|
+
// or some fundamental error with subject creation which must be not be propagated
|
|
281
|
+
// any further and investigated manually.
|
|
282
|
+
throw new errors_1.ExecutionViolation("Orchestration subject creation failed due to invalid parameters - Event: ".concat(event.type, " - Check event emit parameters in the machine definition. ").concat(error === null || error === void 0 ? void 0 : error.message));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
var finalDataschema = event.dataschema;
|
|
287
|
+
var finalData = event.data;
|
|
288
|
+
// finally if the contract and the schema are available
|
|
289
|
+
// then use them to validate the event. Otherwise just use
|
|
290
|
+
// the data from the incoming event which is raw and created
|
|
291
|
+
// by the machine
|
|
292
|
+
if (contract && schema) {
|
|
293
|
+
try {
|
|
294
|
+
finalData = schema.parse(event.data);
|
|
295
|
+
finalDataschema = arvo_core_1.EventDataschemaUtil.create(contract);
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
throw new errors_1.ContractViolation("Invalid event data: Schema validation failed - Check emit parameters in machine definition.\nEvent type: ".concat(event.type, "\nDetails: ").concat(error.message));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Create the event
|
|
302
|
+
var emittableEvent = (0, arvo_core_1.createArvoEvent)({
|
|
303
|
+
source: this.source,
|
|
304
|
+
type: event.type,
|
|
305
|
+
subject: subject,
|
|
306
|
+
dataschema: finalDataschema !== null && finalDataschema !== void 0 ? finalDataschema : undefined,
|
|
307
|
+
data: finalData,
|
|
308
|
+
to: (_m = event.to) !== null && _m !== void 0 ? _m : event.type,
|
|
309
|
+
accesscontrol: (_p = (_o = event.accesscontrol) !== null && _o !== void 0 ? _o : sourceEvent.accesscontrol) !== null && _p !== void 0 ? _p : undefined,
|
|
310
|
+
// The orchestrator/ resumable does not respect redirectto from the source event
|
|
311
|
+
redirectto: (_q = event.redirectto) !== null && _q !== void 0 ? _q : this.source,
|
|
312
|
+
executionunits: (_r = event.executionunits) !== null && _r !== void 0 ? _r : this.executionunits,
|
|
313
|
+
traceparent: (_s = otelHeaders.traceparent) !== null && _s !== void 0 ? _s : undefined,
|
|
314
|
+
tracestate: (_t = otelHeaders.tracestate) !== null && _t !== void 0 ? _t : undefined,
|
|
315
|
+
parentid: parentId,
|
|
316
|
+
domain: domain !== null && domain !== void 0 ? domain : undefined,
|
|
317
|
+
}, (_u = event.__extensions) !== null && _u !== void 0 ? _u : {});
|
|
318
|
+
(0, arvo_core_1.logToSpan)({
|
|
319
|
+
level: 'INFO',
|
|
320
|
+
message: "Event created successfully: ".concat(emittableEvent.type),
|
|
321
|
+
});
|
|
322
|
+
return emittableEvent;
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Executes the orchestration workflow for an incoming event
|
|
326
|
+
*
|
|
327
|
+
* This is the main orchestration entry point that coordinates the complete event
|
|
328
|
+
* processing lifecycle. It implements the core workflow execution pattern including
|
|
329
|
+
* validation, locking, state management, handler invocation, event creation, and
|
|
330
|
+
* persistence with comprehensive error handling and observability.
|
|
331
|
+
*
|
|
332
|
+
* The execution process follows these phases:
|
|
333
|
+
* 1. **Validation & Setup** - Subject parsing, handler resolution, contract validation
|
|
334
|
+
* 2. **Resource Management** - Distributed lock acquisition and state loading
|
|
335
|
+
* 3. **Handler Execution** - Context preparation and user handler invocation
|
|
336
|
+
* 4. **Event Processing** - Result transformation and emittable event creation
|
|
337
|
+
* 5. **State Persistence** - Atomic state updates and event tracking
|
|
338
|
+
* 6. **Cleanup & Return** - Resource release and structured result return
|
|
339
|
+
*
|
|
340
|
+
* @param event - The triggering event to process
|
|
341
|
+
* @param opentelemetry - OpenTelemetry configuration for trace inheritance
|
|
342
|
+
*
|
|
343
|
+
* @returns Object containing domained events
|
|
344
|
+
*
|
|
345
|
+
* @throws {TransactionViolation} When distributed lock acquisition fails
|
|
346
|
+
* @throws {ConfigViolation} When handler resolution or contract validation fails
|
|
347
|
+
* @throws {ContractViolation} When event schema validation fails
|
|
348
|
+
* @throws {ExecutionViolation} When workflow execution encounters critical errors
|
|
349
|
+
*
|
|
350
|
+
* @remarks
|
|
351
|
+
* **Execution Safety:**
|
|
352
|
+
* The method implements comprehensive error recovery with proper resource cleanup
|
|
353
|
+
* in all execution paths. ViolationErrors are rethrown for system handling while
|
|
354
|
+
* workflow errors become system error events for graceful degradation.
|
|
355
|
+
*
|
|
356
|
+
* **State Management:**
|
|
357
|
+
* Workflow state is managed atomically with optimistic concurrency control.
|
|
358
|
+
* Status transitions from 'active' to 'done' occur only when completion events
|
|
359
|
+
* are generated, ensuring proper workflow lifecycle management.
|
|
360
|
+
*
|
|
361
|
+
* **Observability:**
|
|
362
|
+
* Complete execution is traced using OpenTelemetry with detailed span attributes
|
|
363
|
+
* for debugging and monitoring. Event metadata includes processing context and
|
|
364
|
+
* routing information for operational visibility.
|
|
365
|
+
*
|
|
366
|
+
* **Terminal State Handling:**
|
|
367
|
+
* Workflows in 'done' status ignore additional events to prevent state corruption
|
|
368
|
+
* while preserving audit trails for completed workflow executions.
|
|
369
|
+
*/
|
|
370
|
+
ArvoResumable.prototype.execute = function (event, opentelemetry) {
|
|
371
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
372
|
+
var _a;
|
|
373
|
+
var _this = this;
|
|
374
|
+
return __generator(this, function (_b) {
|
|
375
|
+
return [2 /*return*/, arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
|
|
376
|
+
name: "ArvoResumable<".concat(this.contracts.self.uri, ">@<").concat(event.type, ">"),
|
|
377
|
+
spanOptions: {
|
|
378
|
+
kind: api_1.SpanKind.PRODUCER,
|
|
379
|
+
attributes: __assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.ORCHESTRATOR, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), Object.fromEntries(Object.entries(event.otelAttributes).map(function (_a) {
|
|
380
|
+
var key = _a[0], value = _a[1];
|
|
381
|
+
return ["to_process.0.".concat(key), value];
|
|
382
|
+
}))),
|
|
383
|
+
},
|
|
384
|
+
context: opentelemetry.inheritFrom === 'EVENT'
|
|
385
|
+
? {
|
|
386
|
+
inheritFrom: 'TRACE_HEADERS',
|
|
387
|
+
traceHeaders: {
|
|
388
|
+
traceparent: event.traceparent,
|
|
389
|
+
tracestate: event.tracestate,
|
|
390
|
+
},
|
|
391
|
+
}
|
|
392
|
+
: {
|
|
393
|
+
inheritFrom: 'CONTEXT',
|
|
394
|
+
context: api_1.context.active(),
|
|
395
|
+
},
|
|
396
|
+
disableSpanManagement: true,
|
|
397
|
+
fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
|
|
398
|
+
var otelHeaders, orchestrationParentSubject, acquiredLock, initEventId, parsedEventSubject, contractType, state, eventTypeToExpectedEvent, _i, _a, _b, _, eventList, _c, eventList_1, _evt, handler, executionResult, emittables, _d, _e, item, domains, _f, _g, _dom, evt, _h, _j, _k, key, value, eventTrackingState, error_2, e, parsedEventSubject, result, _l, _m, _dom, _o, _p, _q, key, value;
|
|
399
|
+
var _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
|
|
400
|
+
return __generator(this, function (_13) {
|
|
401
|
+
switch (_13.label) {
|
|
402
|
+
case 0:
|
|
403
|
+
(0, arvo_core_1.logToSpan)({
|
|
404
|
+
level: 'INFO',
|
|
405
|
+
message: "Resumable function starting execution for ".concat(event.type, " on subject ").concat(event.subject),
|
|
406
|
+
});
|
|
407
|
+
otelHeaders = (0, arvo_core_1.currentOpenTelemetryHeaders)();
|
|
408
|
+
orchestrationParentSubject = null;
|
|
409
|
+
acquiredLock = null;
|
|
410
|
+
initEventId = null;
|
|
411
|
+
_13.label = 1;
|
|
412
|
+
case 1:
|
|
413
|
+
_13.trys.push([1, 6, 7, 9]);
|
|
414
|
+
///////////////////////////////////////////////////////////////
|
|
415
|
+
// Subject resolution, handler resolution and input validation
|
|
416
|
+
///////////////
|
|
417
|
+
// ////////////////////////////////////////////////
|
|
418
|
+
this.syncEventResource.validateEventSubject(event);
|
|
419
|
+
parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
|
|
420
|
+
span.setAttributes({
|
|
421
|
+
'arvo.parsed.subject.orchestrator.name': parsedEventSubject.orchestrator.name,
|
|
422
|
+
'arvo.parsed.subject.orchestrator.version': parsedEventSubject.orchestrator.version,
|
|
423
|
+
});
|
|
424
|
+
// The wrong source is not a big violation. May be some routing went wrong. So just ignore the event
|
|
425
|
+
if (parsedEventSubject.orchestrator.name !== this.source) {
|
|
426
|
+
(0, arvo_core_1.logToSpan)({
|
|
427
|
+
level: 'WARNING',
|
|
428
|
+
message: "Event subject mismatch detected. Expected orchestrator '".concat(this.source, "' but subject indicates '").concat(parsedEventSubject.orchestrator.name, "'. This indicates either a routing error or a non-applicable event that can be safely ignored."),
|
|
429
|
+
});
|
|
430
|
+
(0, arvo_core_1.logToSpan)({
|
|
431
|
+
level: 'INFO',
|
|
432
|
+
message: 'Orchestration executed with issues and emitted 0 events',
|
|
433
|
+
});
|
|
434
|
+
return [2 /*return*/, {
|
|
435
|
+
events: [],
|
|
436
|
+
allEventDomains: [],
|
|
437
|
+
domainedEvents: {
|
|
438
|
+
all: [],
|
|
439
|
+
},
|
|
440
|
+
}];
|
|
441
|
+
}
|
|
442
|
+
(0, arvo_core_1.logToSpan)({
|
|
443
|
+
level: 'INFO',
|
|
444
|
+
message: "Resolving machine for event ".concat(event.type),
|
|
445
|
+
});
|
|
446
|
+
// Handler not found means that the handler is not defined which is not allowed and a critical bug
|
|
447
|
+
if (!this.handler[parsedEventSubject.orchestrator.version]) {
|
|
448
|
+
throw new errors_1.ConfigViolation("Handler resolution failed: No handler found matching orchestrator name='".concat(parsedEventSubject.orchestrator.name, "' and version='").concat(parsedEventSubject.orchestrator.version, "'."));
|
|
449
|
+
}
|
|
450
|
+
(0, arvo_core_1.logToSpan)({
|
|
451
|
+
level: 'INFO',
|
|
452
|
+
message: "Input validation started for event ".concat(event.type),
|
|
453
|
+
});
|
|
454
|
+
contractType = this.validateInput(event).contractType;
|
|
455
|
+
return [4 /*yield*/, this.syncEventResource.acquireLock(event)];
|
|
456
|
+
case 2:
|
|
457
|
+
///////////////////////////////////////////////////////////////
|
|
458
|
+
// State locking, acquiry and handler exection
|
|
459
|
+
///////////////////////////////////////////////////////////////
|
|
460
|
+
acquiredLock = _13.sent();
|
|
461
|
+
if (acquiredLock === 'NOT_ACQUIRED') {
|
|
462
|
+
throw new error_1.TransactionViolation({
|
|
463
|
+
cause: error_1.TransactionViolationCause.LOCK_UNACQUIRED,
|
|
464
|
+
message: 'Lock acquisition denied - Unable to obtain exclusive access to event processing',
|
|
465
|
+
initiatingEvent: event,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
if (acquiredLock === 'ACQUIRED') {
|
|
469
|
+
(0, arvo_core_1.logToSpan)({
|
|
470
|
+
level: 'INFO',
|
|
471
|
+
message: "This execution acquired lock at resource '".concat(event.subject, "'"),
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return [4 /*yield*/, this.syncEventResource.acquireState(event)];
|
|
475
|
+
case 3:
|
|
476
|
+
state = _13.sent();
|
|
477
|
+
orchestrationParentSubject = (_r = state === null || state === void 0 ? void 0 : state.parentSubject) !== null && _r !== void 0 ? _r : null;
|
|
478
|
+
initEventId = (_s = state === null || state === void 0 ? void 0 : state.initEventId) !== null && _s !== void 0 ? _s : event.id;
|
|
479
|
+
if ((state === null || state === void 0 ? void 0 : state.status) === 'done') {
|
|
480
|
+
(0, arvo_core_1.logToSpan)({
|
|
481
|
+
level: 'INFO',
|
|
482
|
+
message: "The resumable has already reached the terminal state. Ignoring event(id=".concat(event.id, ")"),
|
|
483
|
+
});
|
|
484
|
+
return [2 /*return*/, {
|
|
485
|
+
events: [],
|
|
486
|
+
}];
|
|
487
|
+
}
|
|
488
|
+
if (!state) {
|
|
489
|
+
(0, arvo_core_1.logToSpan)({
|
|
490
|
+
level: 'INFO',
|
|
491
|
+
message: "Initializing new execution state for subject: ".concat(event.subject),
|
|
492
|
+
});
|
|
493
|
+
if (event.type !== this.source) {
|
|
494
|
+
(0, arvo_core_1.logToSpan)({
|
|
495
|
+
level: 'WARNING',
|
|
496
|
+
message: "Invalid initialization event detected. Expected type '".concat(this.source, "' but received '").concat(event.type, "'. This may indicate an incorrectly routed event or a non-initialization event that can be safely ignored."),
|
|
497
|
+
});
|
|
498
|
+
return [2 /*return*/, {
|
|
499
|
+
events: [],
|
|
500
|
+
}];
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
(0, arvo_core_1.logToSpan)({
|
|
505
|
+
level: 'INFO',
|
|
506
|
+
message: "Resuming execution with existing state for subject: ".concat(event.subject),
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
// In case the event is the init event then
|
|
510
|
+
// extract the parent subject from it and assume
|
|
511
|
+
// it to be the orchestration parent subject
|
|
512
|
+
if (event.type === this.source) {
|
|
513
|
+
orchestrationParentSubject = (_u = (_t = event === null || event === void 0 ? void 0 : event.data) === null || _t === void 0 ? void 0 : _t.parentSubject$$) !== null && _u !== void 0 ? _u : null;
|
|
514
|
+
}
|
|
515
|
+
// This is not persisted until handling. The reason is that if the event
|
|
516
|
+
// is causing a fault then what is the point of persisting it
|
|
517
|
+
if (event.parentid &&
|
|
518
|
+
((_w = (_v = state === null || state === void 0 ? void 0 : state.events) === null || _v === void 0 ? void 0 : _v.expected) === null || _w === void 0 ? void 0 : _w[event.parentid]) &&
|
|
519
|
+
Array.isArray((_y = (_x = state === null || state === void 0 ? void 0 : state.events) === null || _x === void 0 ? void 0 : _x.expected) === null || _y === void 0 ? void 0 : _y[event.parentid])) {
|
|
520
|
+
state.events.expected[event.parentid].push(event.toJSON());
|
|
521
|
+
}
|
|
522
|
+
eventTypeToExpectedEvent = {};
|
|
523
|
+
for (_i = 0, _a = Object.entries((_0 = (_z = state === null || state === void 0 ? void 0 : state.events) === null || _z === void 0 ? void 0 : _z.expected) !== null && _0 !== void 0 ? _0 : {}); _i < _a.length; _i++) {
|
|
524
|
+
_b = _a[_i], _ = _b[0], eventList = _b[1];
|
|
525
|
+
for (_c = 0, eventList_1 = eventList; _c < eventList_1.length; _c++) {
|
|
526
|
+
_evt = eventList_1[_c];
|
|
527
|
+
if (!eventTypeToExpectedEvent[_evt.type]) {
|
|
528
|
+
eventTypeToExpectedEvent[_evt.type] = [];
|
|
529
|
+
}
|
|
530
|
+
eventTypeToExpectedEvent[_evt.type].push(_evt);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
handler = this.handler[parsedEventSubject.orchestrator.version];
|
|
534
|
+
return [4 /*yield*/, handler({
|
|
535
|
+
span: span,
|
|
536
|
+
context: (_1 = state === null || state === void 0 ? void 0 : state.state$$) !== null && _1 !== void 0 ? _1 : null,
|
|
537
|
+
metadata: state !== null && state !== void 0 ? state : null,
|
|
538
|
+
collectedEvents: eventTypeToExpectedEvent,
|
|
539
|
+
input: contractType === 'self' ? event.toJSON() : null,
|
|
540
|
+
service: contractType === 'service' ? event.toJSON() : null,
|
|
541
|
+
contracts: {
|
|
542
|
+
self: this.contracts.self.version(parsedEventSubject.orchestrator.version),
|
|
543
|
+
services: this.contracts.services,
|
|
544
|
+
},
|
|
545
|
+
})];
|
|
546
|
+
case 4:
|
|
547
|
+
executionResult = _13.sent();
|
|
548
|
+
emittables = [];
|
|
549
|
+
for (_d = 0, _e = __spreadArray(__spreadArray([], ((executionResult === null || executionResult === void 0 ? void 0 : executionResult.output)
|
|
550
|
+
? [
|
|
551
|
+
{
|
|
552
|
+
data: executionResult.output,
|
|
553
|
+
type: this.contracts.self.metadata.completeEventType,
|
|
554
|
+
to: (_3 = (_2 = parsedEventSubject.meta) === null || _2 === void 0 ? void 0 : _2.redirectto) !== null && _3 !== void 0 ? _3 : parsedEventSubject.execution.initiator,
|
|
555
|
+
domain: orchestrationParentSubject
|
|
556
|
+
? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
|
|
557
|
+
: [undefined],
|
|
558
|
+
},
|
|
559
|
+
]
|
|
560
|
+
: []), true), ((_4 = executionResult === null || executionResult === void 0 ? void 0 : executionResult.services) !== null && _4 !== void 0 ? _4 : []), true); _d < _e.length; _d++) {
|
|
561
|
+
item = _e[_d];
|
|
562
|
+
domains = (_5 = item.domain) !== null && _5 !== void 0 ? _5 : [null];
|
|
563
|
+
for (_f = 0, _g = Array.from(new Set(domains)); _f < _g.length; _f++) {
|
|
564
|
+
_dom = _g[_f];
|
|
565
|
+
evt = this.createEmittableEvent(item, otelHeaders, orchestrationParentSubject, event, this.contracts.self.version(parsedEventSubject.orchestrator.version), initEventId, _dom);
|
|
566
|
+
emittables.push(evt);
|
|
567
|
+
for (_h = 0, _j = Object.entries(emittables[emittables.length - 1].otelAttributes); _h < _j.length; _h++) {
|
|
568
|
+
_k = _j[_h], key = _k[0], value = _k[1];
|
|
569
|
+
span.setAttribute("to_emit.".concat(emittables.length - 1, ".").concat(key), value);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
(0, arvo_core_1.logToSpan)({
|
|
574
|
+
level: 'INFO',
|
|
575
|
+
message: "Resumable execution completed. Generated events: ".concat(emittables.length),
|
|
576
|
+
});
|
|
577
|
+
eventTrackingState = {
|
|
578
|
+
consumed: event.toJSON(),
|
|
579
|
+
expected: emittables.length
|
|
580
|
+
? Object.fromEntries(emittables.map(function (item) { return [item.id, []]; }))
|
|
581
|
+
: ((_6 = state === null || state === void 0 ? void 0 : state.events.expected) !== null && _6 !== void 0 ? _6 : null),
|
|
582
|
+
produced: emittables.map(function (item) { return item.toJSON(); }),
|
|
583
|
+
};
|
|
584
|
+
// Write to the memory
|
|
585
|
+
return [4 /*yield*/, this.syncEventResource.persistState(event, {
|
|
586
|
+
status: (executionResult === null || executionResult === void 0 ? void 0 : executionResult.output) ? 'done' : 'active',
|
|
587
|
+
initEventId: initEventId,
|
|
588
|
+
parentSubject: orchestrationParentSubject,
|
|
589
|
+
subject: event.subject,
|
|
590
|
+
events: eventTrackingState,
|
|
591
|
+
state$$: (_8 = (_7 = executionResult === null || executionResult === void 0 ? void 0 : executionResult.context) !== null && _7 !== void 0 ? _7 : state === null || state === void 0 ? void 0 : state.state$$) !== null && _8 !== void 0 ? _8 : null,
|
|
592
|
+
}, state, span)];
|
|
593
|
+
case 5:
|
|
594
|
+
// Write to the memory
|
|
595
|
+
_13.sent();
|
|
596
|
+
(0, arvo_core_1.logToSpan)({
|
|
597
|
+
level: 'INFO',
|
|
598
|
+
message: "State update persisted in memory for subject ".concat(event.subject),
|
|
599
|
+
});
|
|
600
|
+
(0, arvo_core_1.logToSpan)({
|
|
601
|
+
level: 'INFO',
|
|
602
|
+
message: "Resumable successfully executed and emitted ".concat(emittables.length, " events"),
|
|
603
|
+
});
|
|
604
|
+
return [2 /*return*/, { events: emittables }];
|
|
605
|
+
case 6:
|
|
606
|
+
error_2 = _13.sent();
|
|
607
|
+
e = (0, index_2.isError)(error_2)
|
|
608
|
+
? error_2
|
|
609
|
+
: new errors_1.ExecutionViolation("Non-Error object thrown during machine execution: ".concat(typeof error_2, ". This indicates a serious implementation flaw."));
|
|
610
|
+
(0, arvo_core_1.exceptionToSpan)(e);
|
|
611
|
+
span.setStatus({
|
|
612
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
613
|
+
message: e.message,
|
|
614
|
+
});
|
|
615
|
+
// For any violation errors bubble them up to the
|
|
616
|
+
// called of the function so that they can
|
|
617
|
+
// be handled gracefully
|
|
618
|
+
if (e.name.includes('ViolationError')) {
|
|
619
|
+
(0, arvo_core_1.logToSpan)({
|
|
620
|
+
level: 'CRITICAL',
|
|
621
|
+
message: "Resumable violation error: ".concat(e.message),
|
|
622
|
+
});
|
|
623
|
+
throw e;
|
|
624
|
+
}
|
|
625
|
+
(0, arvo_core_1.logToSpan)({
|
|
626
|
+
level: 'ERROR',
|
|
627
|
+
message: "Resumable execution failed: ".concat(e.message),
|
|
628
|
+
});
|
|
629
|
+
parsedEventSubject = null;
|
|
630
|
+
try {
|
|
631
|
+
parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
|
|
632
|
+
}
|
|
633
|
+
catch (e) {
|
|
634
|
+
(0, arvo_core_1.logToSpan)({
|
|
635
|
+
level: 'WARNING',
|
|
636
|
+
message: "Unable to parse event subject: ".concat(e.message),
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
result = [];
|
|
640
|
+
for (_l = 0, _m = Array.from(new Set([event.domain, this.domain, null])); _l < _m.length; _l++) {
|
|
641
|
+
_dom = _m[_l];
|
|
642
|
+
result.push((0, arvo_core_1.createArvoOrchestratorEventFactory)(this.contracts.self.version('any')).systemError({
|
|
643
|
+
source: this.source,
|
|
644
|
+
// If the initiator of the workflow exist then match the
|
|
645
|
+
// subject so that it can incorporate it in its state. If
|
|
646
|
+
// parent does not exist then this is the root workflow so
|
|
647
|
+
// use its own subject
|
|
648
|
+
subject: orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : event.subject,
|
|
649
|
+
// The system error must always go back to
|
|
650
|
+
// the source which initiated it
|
|
651
|
+
to: (_9 = parsedEventSubject === null || parsedEventSubject === void 0 ? void 0 : parsedEventSubject.execution.initiator) !== null && _9 !== void 0 ? _9 : event.source,
|
|
652
|
+
error: e,
|
|
653
|
+
traceparent: (_10 = otelHeaders.traceparent) !== null && _10 !== void 0 ? _10 : undefined,
|
|
654
|
+
tracestate: (_11 = otelHeaders.tracestate) !== null && _11 !== void 0 ? _11 : undefined,
|
|
655
|
+
accesscontrol: (_12 = event.accesscontrol) !== null && _12 !== void 0 ? _12 : undefined,
|
|
656
|
+
executionunits: this.executionunits,
|
|
657
|
+
// If there is initEventID then use that.
|
|
658
|
+
// Otherwise, use event id. If the error is in init event
|
|
659
|
+
// then it will be the same as initEventId. Otherwise,
|
|
660
|
+
// we still would know what cause this error
|
|
661
|
+
parentid: initEventId !== null && initEventId !== void 0 ? initEventId : event.id,
|
|
662
|
+
domain: _dom,
|
|
663
|
+
}));
|
|
664
|
+
for (_o = 0, _p = Object.entries(result[result.length - 1].otelAttributes); _o < _p.length; _o++) {
|
|
665
|
+
_q = _p[_o], key = _q[0], value = _q[1];
|
|
666
|
+
span.setAttribute("to_emit.".concat(result.length - 1, ".").concat(key), value);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return [2 /*return*/, {
|
|
670
|
+
events: result,
|
|
671
|
+
}];
|
|
672
|
+
case 7: return [4 /*yield*/, this.syncEventResource.releaseLock(event, acquiredLock, span)];
|
|
673
|
+
case 8:
|
|
674
|
+
_13.sent();
|
|
675
|
+
span.end();
|
|
676
|
+
return [7 /*endfinally*/];
|
|
677
|
+
case 9: return [2 /*return*/];
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}); },
|
|
681
|
+
})];
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
};
|
|
685
|
+
Object.defineProperty(ArvoResumable.prototype, "systemErrorSchema", {
|
|
686
|
+
get: function () {
|
|
687
|
+
return this.contracts.self.systemError;
|
|
688
|
+
},
|
|
689
|
+
enumerable: false,
|
|
690
|
+
configurable: true
|
|
691
|
+
});
|
|
692
|
+
return ArvoResumable;
|
|
693
|
+
}(AbstractArvoEventHandler_1.default));
|
|
694
|
+
exports.ArvoResumable = ArvoResumable;
|