arvo-event-handler 3.0.7 → 3.0.8
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/ArvoEventHandler/index.d.ts +1 -1
- package/dist/ArvoEventHandler/index.js +1 -1
- package/dist/ArvoMachine/createMachine.d.ts +1 -1
- package/dist/ArvoMachine/createMachine.js +1 -1
- package/dist/ArvoOrchestrationUtils/createEmitableEvent.d.ts +30 -0
- package/dist/ArvoOrchestrationUtils/createEmitableEvent.js +160 -0
- package/dist/ArvoOrchestrationUtils/error.d.ts +18 -0
- package/dist/{ArvoOrchestrator → ArvoOrchestrationUtils}/error.js +14 -9
- package/dist/ArvoOrchestrationUtils/handlerErrors.d.ts +35 -0
- package/dist/ArvoOrchestrationUtils/handlerErrors.js +184 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionState.d.ts +11 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionState.js +7 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/acquireLockWithValidation.d.ts +8 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/acquireLockWithValidation.js +69 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/index.d.ts +40 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/index.js +228 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/validateAndParseSubject.d.ts +7 -0
- package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/validateAndParseSubject.js +25 -0
- package/dist/ArvoOrchestrationUtils/types.d.ts +1 -0
- package/dist/ArvoOrchestrationUtils/types.js +2 -0
- package/dist/ArvoOrchestrator/factory.js +13 -0
- package/dist/ArvoOrchestrator/index.d.ts +3 -19
- package/dist/ArvoOrchestrator/index.js +85 -477
- package/dist/ArvoOrchestrator/types.d.ts +3 -2
- package/dist/ArvoResumable/factory.d.ts +2 -2
- package/dist/ArvoResumable/factory.js +1 -1
- package/dist/ArvoResumable/index.d.ts +5 -19
- package/dist/ArvoResumable/index.js +76 -433
- package/dist/ArvoResumable/types.d.ts +5 -4
- package/dist/IArvoEventHandler/index.d.ts +0 -1
- package/dist/MachineExecutionEngine/index.d.ts +1 -1
- package/dist/MachineRegistry/index.d.ts +1 -1
- package/dist/SyncEventResource/index.d.ts +1 -1
- package/dist/SyncEventResource/index.js +1 -1
- package/dist/index.d.ts +12 -11
- package/dist/index.js +24 -21
- package/package.json +2 -2
- package/dist/ArvoOrchestrator/error.d.ts +0 -16
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SpanOptions } from '@opentelemetry/api';
|
|
2
2
|
import { type ArvoContract, type ArvoEvent } from 'arvo-core';
|
|
3
|
-
import IArvoEventHandler from '../IArvoEventHandler';
|
|
3
|
+
import type IArvoEventHandler from '../IArvoEventHandler';
|
|
4
4
|
import type { ArvoEventHandlerOpenTelemetryOptions } from '../types';
|
|
5
5
|
import type { ArvoEventHandlerFunction, ArvoEventHandlerParam } from './types';
|
|
6
6
|
/**
|
|
@@ -60,9 +60,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
60
60
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
61
61
|
var api_1 = require("@opentelemetry/api");
|
|
62
62
|
var arvo_core_1 = require("arvo-core");
|
|
63
|
+
var ArvoDomain_1 = require("../ArvoDomain");
|
|
63
64
|
var errors_1 = require("../errors");
|
|
64
65
|
var utils_1 = require("../utils");
|
|
65
|
-
var ArvoDomain_1 = require("../ArvoDomain");
|
|
66
66
|
/**
|
|
67
67
|
* `ArvoEventHandler` is the foundational component for building stateless,
|
|
68
68
|
* contract-bound services in the Arvo system.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ArvoOrchestratorEventTypeGen, CreateArvoEvent, type InferVersionedArvoContract, type VersionedArvoContract } from 'arvo-core';
|
|
1
|
+
import { type ArvoOrchestratorEventTypeGen, type CreateArvoEvent, type InferVersionedArvoContract, type VersionedArvoContract } from 'arvo-core';
|
|
2
2
|
import { type ActionFunction, type MachineConfig, type MachineContext, type MetaObject, type ParameterizedObject, type SetupTypes } from 'xstate';
|
|
3
3
|
import type { z } from 'zod';
|
|
4
4
|
import ArvoMachine from '.';
|
|
@@ -25,11 +25,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.setupArvoMachine = setupArvoMachine;
|
|
27
27
|
var arvo_core_1 = require("arvo-core");
|
|
28
|
+
var uuid_1 = require("uuid");
|
|
28
29
|
var xstate_1 = require("xstate");
|
|
29
30
|
var _1 = __importDefault(require("."));
|
|
30
31
|
var object_1 = require("../utils/object");
|
|
31
32
|
var utils_1 = require("./utils");
|
|
32
|
-
var uuid_1 = require("uuid");
|
|
33
33
|
/**
|
|
34
34
|
* Establishes the foundation for creating Arvo-compatible state machines.
|
|
35
35
|
*
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Span } from '@opentelemetry/api';
|
|
2
|
+
import { type ArvoEvent, type ArvoOrchestratorContract, type ArvoSemanticVersion, type OpenTelemetryHeaders, type VersionedArvoContract } from 'arvo-core';
|
|
3
|
+
import type { EnqueueArvoEventActionParam } from '../ArvoMachine/types';
|
|
4
|
+
export type CreateEmittableEventParams = {
|
|
5
|
+
event: EnqueueArvoEventActionParam;
|
|
6
|
+
otelHeaders: OpenTelemetryHeaders;
|
|
7
|
+
orchestrationParentSubject: string | null;
|
|
8
|
+
sourceEvent: ArvoEvent;
|
|
9
|
+
selfContract: VersionedArvoContract<ArvoOrchestratorContract, ArvoSemanticVersion>;
|
|
10
|
+
serviceContracts: Record<string, VersionedArvoContract<any, any>>;
|
|
11
|
+
initEventId: string;
|
|
12
|
+
domain: string | null;
|
|
13
|
+
executionunits: number;
|
|
14
|
+
source: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const createEmittableEvent: ({ event, otelHeaders, orchestrationParentSubject, sourceEvent, selfContract, serviceContracts, initEventId, domain: _domain, executionunits, source, }: CreateEmittableEventParams, span: Span) => ArvoEvent;
|
|
17
|
+
/**
|
|
18
|
+
* Processes raw events into emittable events with domain resolution
|
|
19
|
+
*/
|
|
20
|
+
export declare const processRawEventsIntoEmittables: (params: {
|
|
21
|
+
rawEvents: EnqueueArvoEventActionParam[];
|
|
22
|
+
otelHeaders: OpenTelemetryHeaders;
|
|
23
|
+
orchestrationParentSubject: string | null;
|
|
24
|
+
sourceEvent: ArvoEvent;
|
|
25
|
+
selfContract: VersionedArvoContract<ArvoOrchestratorContract, ArvoSemanticVersion>;
|
|
26
|
+
serviceContracts: Record<string, VersionedArvoContract<any, any>>;
|
|
27
|
+
initEventId: string;
|
|
28
|
+
executionunits: number;
|
|
29
|
+
source: string;
|
|
30
|
+
}, span: Span) => ArvoEvent[];
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processRawEventsIntoEmittables = exports.createEmittableEvent = void 0;
|
|
4
|
+
var arvo_core_1 = require("arvo-core");
|
|
5
|
+
var ArvoDomain_1 = require("../ArvoDomain");
|
|
6
|
+
var errors_1 = require("../errors");
|
|
7
|
+
var createEmittableEvent = function (_a, span) {
|
|
8
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
9
|
+
var event = _a.event, otelHeaders = _a.otelHeaders, orchestrationParentSubject = _a.orchestrationParentSubject, sourceEvent = _a.sourceEvent, selfContract = _a.selfContract, serviceContracts = _a.serviceContracts, initEventId = _a.initEventId, _domain = _a.domain, executionunits = _a.executionunits, source = _a.source;
|
|
10
|
+
(0, arvo_core_1.logToSpan)({
|
|
11
|
+
level: 'INFO',
|
|
12
|
+
message: "Creating emittable event: ".concat(event.type),
|
|
13
|
+
}, span);
|
|
14
|
+
var serviceContractMap = Object.fromEntries(Object.values(serviceContracts).map(function (item) { return [
|
|
15
|
+
item.accepts.type,
|
|
16
|
+
item,
|
|
17
|
+
]; }));
|
|
18
|
+
var schema = null;
|
|
19
|
+
var contract = null;
|
|
20
|
+
var subject = sourceEvent.subject;
|
|
21
|
+
var parentId = sourceEvent.id;
|
|
22
|
+
var domain = (0, ArvoDomain_1.resolveEventDomain)({
|
|
23
|
+
domainToResolve: _domain,
|
|
24
|
+
handlerSelfContract: selfContract,
|
|
25
|
+
eventContract: null,
|
|
26
|
+
triggeringEvent: sourceEvent,
|
|
27
|
+
});
|
|
28
|
+
if (event.type === selfContract.metadata.completeEventType) {
|
|
29
|
+
(0, arvo_core_1.logToSpan)({
|
|
30
|
+
level: 'INFO',
|
|
31
|
+
message: "Creating event for workflow completion: ".concat(event.type),
|
|
32
|
+
}, span);
|
|
33
|
+
contract = selfContract;
|
|
34
|
+
schema = selfContract.emits[selfContract.metadata.completeEventType];
|
|
35
|
+
subject = orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : sourceEvent.subject;
|
|
36
|
+
parentId = initEventId;
|
|
37
|
+
domain = (0, ArvoDomain_1.resolveEventDomain)({
|
|
38
|
+
domainToResolve: _domain,
|
|
39
|
+
handlerSelfContract: selfContract,
|
|
40
|
+
eventContract: selfContract,
|
|
41
|
+
triggeringEvent: sourceEvent,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else if (serviceContractMap[event.type]) {
|
|
45
|
+
(0, arvo_core_1.logToSpan)({
|
|
46
|
+
level: 'INFO',
|
|
47
|
+
message: "Creating service event for external system: ".concat(event.type),
|
|
48
|
+
}, span);
|
|
49
|
+
contract = serviceContractMap[event.type];
|
|
50
|
+
schema = serviceContractMap[event.type].accepts.schema;
|
|
51
|
+
domain = (0, ArvoDomain_1.resolveEventDomain)({
|
|
52
|
+
domainToResolve: _domain,
|
|
53
|
+
handlerSelfContract: selfContract,
|
|
54
|
+
eventContract: contract,
|
|
55
|
+
triggeringEvent: sourceEvent,
|
|
56
|
+
});
|
|
57
|
+
if (contract.metadata.contractType === 'ArvoOrchestratorContract') {
|
|
58
|
+
if (event.data.parentSubject$$) {
|
|
59
|
+
try {
|
|
60
|
+
arvo_core_1.ArvoOrchestrationSubject.parse(event.data.parentSubject$$);
|
|
61
|
+
}
|
|
62
|
+
catch (_o) {
|
|
63
|
+
throw new errors_1.ExecutionViolation("Invalid parentSubject$$ for the event(type='".concat(event.type, "', uri='").concat((_b = event.dataschema) !== null && _b !== void 0 ? _b : 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."));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
if (event.data.parentSubject$$) {
|
|
68
|
+
subject = arvo_core_1.ArvoOrchestrationSubject.from({
|
|
69
|
+
orchestator: contract.accepts.type,
|
|
70
|
+
version: contract.version,
|
|
71
|
+
subject: event.data.parentSubject$$,
|
|
72
|
+
domain: domain !== null && domain !== void 0 ? domain : null,
|
|
73
|
+
meta: {
|
|
74
|
+
redirectto: (_c = event.redirectto) !== null && _c !== void 0 ? _c : source,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
subject = arvo_core_1.ArvoOrchestrationSubject.new({
|
|
80
|
+
version: contract.version,
|
|
81
|
+
orchestator: contract.accepts.type,
|
|
82
|
+
initiator: source,
|
|
83
|
+
domain: domain !== null && domain !== void 0 ? domain : undefined,
|
|
84
|
+
meta: {
|
|
85
|
+
redirectto: (_d = event.redirectto) !== null && _d !== void 0 ? _d : source,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new errors_1.ExecutionViolation("Orchestration subject creation failed due to invalid parameters - Event: ".concat(event.type, " - ").concat(error === null || error === void 0 ? void 0 : error.message));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
var finalDataschema = event.dataschema;
|
|
96
|
+
var finalData = event.data;
|
|
97
|
+
if (contract && schema) {
|
|
98
|
+
try {
|
|
99
|
+
finalData = schema.parse(event.data);
|
|
100
|
+
finalDataschema = arvo_core_1.EventDataschemaUtil.create(contract);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
throw new errors_1.ContractViolation("Invalid event data: Schema validation failed.\nEvent type: ".concat(event.type, "\nDetails: ").concat(error.message));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
var emittableEvent = (0, arvo_core_1.createArvoEvent)({
|
|
107
|
+
id: event.id,
|
|
108
|
+
source: source,
|
|
109
|
+
type: event.type,
|
|
110
|
+
subject: subject,
|
|
111
|
+
dataschema: finalDataschema !== null && finalDataschema !== void 0 ? finalDataschema : undefined,
|
|
112
|
+
data: finalData,
|
|
113
|
+
to: (_e = event.to) !== null && _e !== void 0 ? _e : event.type,
|
|
114
|
+
accesscontrol: (_g = (_f = event.accesscontrol) !== null && _f !== void 0 ? _f : sourceEvent.accesscontrol) !== null && _g !== void 0 ? _g : undefined,
|
|
115
|
+
redirectto: (_h = event.redirectto) !== null && _h !== void 0 ? _h : source,
|
|
116
|
+
executionunits: (_j = event.executionunits) !== null && _j !== void 0 ? _j : executionunits,
|
|
117
|
+
traceparent: (_k = otelHeaders.traceparent) !== null && _k !== void 0 ? _k : undefined,
|
|
118
|
+
tracestate: (_l = otelHeaders.tracestate) !== null && _l !== void 0 ? _l : undefined,
|
|
119
|
+
parentid: parentId,
|
|
120
|
+
domain: domain !== null && domain !== void 0 ? domain : undefined,
|
|
121
|
+
}, (_m = event.__extensions) !== null && _m !== void 0 ? _m : {});
|
|
122
|
+
(0, arvo_core_1.logToSpan)({
|
|
123
|
+
level: 'INFO',
|
|
124
|
+
message: "Event created successfully: ".concat(emittableEvent.type),
|
|
125
|
+
}, span);
|
|
126
|
+
return emittableEvent;
|
|
127
|
+
};
|
|
128
|
+
exports.createEmittableEvent = createEmittableEvent;
|
|
129
|
+
/**
|
|
130
|
+
* Processes raw events into emittable events with domain resolution
|
|
131
|
+
*/
|
|
132
|
+
var processRawEventsIntoEmittables = function (params, span) {
|
|
133
|
+
var _a;
|
|
134
|
+
var emittables = [];
|
|
135
|
+
for (var _i = 0, _b = params.rawEvents; _i < _b.length; _i++) {
|
|
136
|
+
var item = _b[_i];
|
|
137
|
+
for (var _c = 0, _d = Array.from(new Set((_a = item.domain) !== null && _a !== void 0 ? _a : [null])); _c < _d.length; _c++) {
|
|
138
|
+
var _dom = _d[_c];
|
|
139
|
+
var evt = (0, exports.createEmittableEvent)({
|
|
140
|
+
event: item,
|
|
141
|
+
otelHeaders: params.otelHeaders,
|
|
142
|
+
orchestrationParentSubject: params.orchestrationParentSubject,
|
|
143
|
+
sourceEvent: params.sourceEvent,
|
|
144
|
+
selfContract: params.selfContract,
|
|
145
|
+
serviceContracts: params.serviceContracts,
|
|
146
|
+
initEventId: params.initEventId,
|
|
147
|
+
domain: _dom,
|
|
148
|
+
executionunits: params.executionunits,
|
|
149
|
+
source: params.source,
|
|
150
|
+
}, span);
|
|
151
|
+
emittables.push(evt);
|
|
152
|
+
for (var _e = 0, _f = Object.entries(emittables[emittables.length - 1].otelAttributes); _e < _f.length; _e++) {
|
|
153
|
+
var _g = _f[_e], key = _g[0], value = _g[1];
|
|
154
|
+
span.setAttribute("to_emit.".concat(emittables.length - 1, ".").concat(key), value);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return emittables;
|
|
159
|
+
};
|
|
160
|
+
exports.processRawEventsIntoEmittables = processRawEventsIntoEmittables;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ArvoEvent, ViolationError } from 'arvo-core';
|
|
2
|
+
export declare const TransactionViolationCause: {
|
|
3
|
+
readonly READ_FAILURE: "READ_MACHINE_MEMORY_FAILURE";
|
|
4
|
+
readonly LOCK_FAILURE: "LOCK_MACHINE_MEMORY_FAILURE";
|
|
5
|
+
readonly WRITE_FAILURE: "WRITE_MACHINE_MEMORY_FAILURE";
|
|
6
|
+
readonly LOCK_UNACQUIRED: "LOCK_UNACQUIRED";
|
|
7
|
+
readonly INVALID_SUBJECT: "INVALID_SUBJECT";
|
|
8
|
+
};
|
|
9
|
+
export type TransactionViolationCauseType = (typeof TransactionViolationCause)[keyof typeof TransactionViolationCause];
|
|
10
|
+
export declare class TransactionViolation extends ViolationError<'OrchestratorTransaction'> {
|
|
11
|
+
readonly cause: TransactionViolationCauseType;
|
|
12
|
+
constructor(param: {
|
|
13
|
+
cause: TransactionViolationCauseType;
|
|
14
|
+
message: string;
|
|
15
|
+
initiatingEvent: ArvoEvent;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export declare const isTransactionViolationError: (error: unknown, cause?: TransactionViolationCauseType) => boolean;
|
|
@@ -15,16 +15,15 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
15
15
|
};
|
|
16
16
|
})();
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.TransactionViolation = exports.TransactionViolationCause = void 0;
|
|
18
|
+
exports.isTransactionViolationError = exports.TransactionViolation = exports.TransactionViolationCause = void 0;
|
|
19
19
|
var arvo_core_1 = require("arvo-core");
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
})(TransactionViolationCause || (exports.TransactionViolationCause = TransactionViolationCause = {}));
|
|
20
|
+
exports.TransactionViolationCause = {
|
|
21
|
+
READ_FAILURE: 'READ_MACHINE_MEMORY_FAILURE',
|
|
22
|
+
LOCK_FAILURE: 'LOCK_MACHINE_MEMORY_FAILURE',
|
|
23
|
+
WRITE_FAILURE: 'WRITE_MACHINE_MEMORY_FAILURE',
|
|
24
|
+
LOCK_UNACQUIRED: 'LOCK_UNACQUIRED',
|
|
25
|
+
INVALID_SUBJECT: 'INVALID_SUBJECT',
|
|
26
|
+
};
|
|
28
27
|
var TransactionViolation = /** @class */ (function (_super) {
|
|
29
28
|
__extends(TransactionViolation, _super);
|
|
30
29
|
function TransactionViolation(param) {
|
|
@@ -41,3 +40,9 @@ var TransactionViolation = /** @class */ (function (_super) {
|
|
|
41
40
|
return TransactionViolation;
|
|
42
41
|
}(arvo_core_1.ViolationError));
|
|
43
42
|
exports.TransactionViolation = TransactionViolation;
|
|
43
|
+
var isTransactionViolationError = function (error, cause) {
|
|
44
|
+
return ((0, arvo_core_1.isViolationError)(error) &&
|
|
45
|
+
error.type === 'OrchestratorTransaction' &&
|
|
46
|
+
(cause ? error.cause === cause : true));
|
|
47
|
+
};
|
|
48
|
+
exports.isTransactionViolationError = isTransactionViolationError;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Span } from '@opentelemetry/api';
|
|
2
|
+
import { type ArvoEvent, type ArvoOrchestratorContract, type ArvoSemanticVersion, type OpenTelemetryHeaders, type VersionedArvoContract, type ViolationError } from 'arvo-core';
|
|
3
|
+
import type { SyncEventResource } from '../SyncEventResource';
|
|
4
|
+
import type { OrchestrationExecutionMemoryRecord } from './orchestrationExecutionState';
|
|
5
|
+
import type { ArvoOrchestrationHandlerType } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Parameters for system error event creation
|
|
8
|
+
*/
|
|
9
|
+
export type CreateSystemErrorEventsParams = {
|
|
10
|
+
error: unknown;
|
|
11
|
+
event: ArvoEvent;
|
|
12
|
+
otelHeaders: OpenTelemetryHeaders;
|
|
13
|
+
orchestrationParentSubject: string | null;
|
|
14
|
+
initEventId: string | null;
|
|
15
|
+
selfContract: VersionedArvoContract<ArvoOrchestratorContract, ArvoSemanticVersion>;
|
|
16
|
+
systemErrorDomain?: (string | null)[];
|
|
17
|
+
executionunits: number;
|
|
18
|
+
source: string;
|
|
19
|
+
domain: string | null;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Creates system error events
|
|
23
|
+
*/
|
|
24
|
+
export declare const createSystemErrorEvents: ({ error, event, otelHeaders, orchestrationParentSubject, initEventId, selfContract, systemErrorDomain, executionunits, source, domain, }: CreateSystemErrorEventsParams & {
|
|
25
|
+
error: Error;
|
|
26
|
+
}) => ArvoEvent[];
|
|
27
|
+
export declare const handleOrchestrationErrors: (_handlerType: ArvoOrchestrationHandlerType, param: CreateSystemErrorEventsParams & {
|
|
28
|
+
syncEventResource: SyncEventResource<OrchestrationExecutionMemoryRecord<Record<string, any>>>;
|
|
29
|
+
}, span: Span) => Promise<{
|
|
30
|
+
errorToThrow: ViolationError;
|
|
31
|
+
events: null;
|
|
32
|
+
} | {
|
|
33
|
+
errorToThrow: null;
|
|
34
|
+
events: ArvoEvent[];
|
|
35
|
+
}>;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
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);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
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;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.handleOrchestrationErrors = exports.createSystemErrorEvents = void 0;
|
|
51
|
+
var api_1 = require("@opentelemetry/api");
|
|
52
|
+
var arvo_core_1 = require("arvo-core");
|
|
53
|
+
var ArvoDomain_1 = require("../ArvoDomain");
|
|
54
|
+
var errors_1 = require("../errors");
|
|
55
|
+
var utils_1 = require("../utils");
|
|
56
|
+
/**
|
|
57
|
+
* Creates system error events
|
|
58
|
+
*/
|
|
59
|
+
var createSystemErrorEvents = function (_a) {
|
|
60
|
+
var _b, _c, _d, _e;
|
|
61
|
+
var error = _a.error, event = _a.event, otelHeaders = _a.otelHeaders, orchestrationParentSubject = _a.orchestrationParentSubject, initEventId = _a.initEventId, selfContract = _a.selfContract, systemErrorDomain = _a.systemErrorDomain, executionunits = _a.executionunits, source = _a.source, domain = _a.domain;
|
|
62
|
+
// In case of none transaction errors like errors from
|
|
63
|
+
// the machine or the event creation etc, the are workflow
|
|
64
|
+
// error and shuold be handled by the workflow. Then are
|
|
65
|
+
// called system error and must be sent
|
|
66
|
+
// to the initiator. In as good of a format as possible
|
|
67
|
+
var parsedEventSubject = null;
|
|
68
|
+
try {
|
|
69
|
+
parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
(0, arvo_core_1.logToSpan)({
|
|
73
|
+
level: 'WARNING',
|
|
74
|
+
message: "Unable to parse event subject: ".concat(e.message),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
var domainSets = new Set(systemErrorDomain
|
|
78
|
+
? systemErrorDomain.map(function (item) {
|
|
79
|
+
return (0, ArvoDomain_1.resolveEventDomain)({
|
|
80
|
+
domainToResolve: item,
|
|
81
|
+
handlerSelfContract: selfContract,
|
|
82
|
+
eventContract: selfContract,
|
|
83
|
+
triggeringEvent: event,
|
|
84
|
+
});
|
|
85
|
+
})
|
|
86
|
+
: [event.domain, domain, null]);
|
|
87
|
+
var result = [];
|
|
88
|
+
for (var _i = 0, _f = Array.from(domainSets); _i < _f.length; _i++) {
|
|
89
|
+
var _dom = _f[_i];
|
|
90
|
+
result.push((0, arvo_core_1.createArvoOrchestratorEventFactory)(selfContract).systemError({
|
|
91
|
+
source: source,
|
|
92
|
+
// If the initiator of the workflow exist then match the
|
|
93
|
+
// subject so that it can incorporate it in its state. If
|
|
94
|
+
// parent does not exist then this is the root workflow so
|
|
95
|
+
// use its own subject
|
|
96
|
+
subject: orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : event.subject,
|
|
97
|
+
// The system error must always go back to
|
|
98
|
+
// the source which initiated it
|
|
99
|
+
to: (_b = parsedEventSubject === null || parsedEventSubject === void 0 ? void 0 : parsedEventSubject.execution.initiator) !== null && _b !== void 0 ? _b : event.source,
|
|
100
|
+
error: error,
|
|
101
|
+
traceparent: (_c = otelHeaders.traceparent) !== null && _c !== void 0 ? _c : undefined,
|
|
102
|
+
tracestate: (_d = otelHeaders.tracestate) !== null && _d !== void 0 ? _d : undefined,
|
|
103
|
+
accesscontrol: (_e = event.accesscontrol) !== null && _e !== void 0 ? _e : undefined,
|
|
104
|
+
executionunits: executionunits,
|
|
105
|
+
// If there is initEventID then use that.
|
|
106
|
+
// Otherwise, use event id. If the error is in init event
|
|
107
|
+
// then it will be the same as initEventId. Otherwise,
|
|
108
|
+
// we still would know what cause this error
|
|
109
|
+
parentid: initEventId !== null && initEventId !== void 0 ? initEventId : event.id,
|
|
110
|
+
domain: _dom,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
};
|
|
115
|
+
exports.createSystemErrorEvents = createSystemErrorEvents;
|
|
116
|
+
var handleOrchestrationErrors = function (_handlerType, param, span) { return __awaiter(void 0, void 0, void 0, function () {
|
|
117
|
+
var handlerType, error, errorEvents, _i, _a, _b, errEvtIdx, errEvt, _c, _d, _e, key, value;
|
|
118
|
+
return __generator(this, function (_f) {
|
|
119
|
+
switch (_f.label) {
|
|
120
|
+
case 0:
|
|
121
|
+
handlerType = {
|
|
122
|
+
orchestrator: 'ArvoOrchestrator',
|
|
123
|
+
resumable: 'ArvoResumable',
|
|
124
|
+
}[_handlerType];
|
|
125
|
+
error = (0, utils_1.isError)(param.error)
|
|
126
|
+
? param.error
|
|
127
|
+
: new errors_1.ExecutionViolation("Non-Error object thrown during machine execution: ".concat(typeof param.error, ". This indicates a serious implementation flaw."));
|
|
128
|
+
(0, arvo_core_1.exceptionToSpan)(error, span);
|
|
129
|
+
span.setStatus({
|
|
130
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
131
|
+
message: error.message,
|
|
132
|
+
});
|
|
133
|
+
// Don't persist state on a violation
|
|
134
|
+
//
|
|
135
|
+
// A violation means that there is something
|
|
136
|
+
// wrong in the state persitance or it is a
|
|
137
|
+
// error which will be handled outside the
|
|
138
|
+
// Arvo mechanism. So, it makes sense that it
|
|
139
|
+
// does not impact the state. The violations
|
|
140
|
+
// can be used to trigger retries as well
|
|
141
|
+
if ((0, arvo_core_1.isViolationError)(error)) {
|
|
142
|
+
(0, arvo_core_1.logToSpan)({
|
|
143
|
+
level: 'CRITICAL',
|
|
144
|
+
message: "".concat(handlerType || 'Arvo orchestration handler', " violation error: ").concat(error.message),
|
|
145
|
+
});
|
|
146
|
+
return [2 /*return*/, {
|
|
147
|
+
errorToThrow: error,
|
|
148
|
+
events: null,
|
|
149
|
+
}];
|
|
150
|
+
}
|
|
151
|
+
return [4 /*yield*/, param.syncEventResource
|
|
152
|
+
.persistState(param.event, {
|
|
153
|
+
executionStatus: 'failure',
|
|
154
|
+
subject: param.event.subject,
|
|
155
|
+
error: param.error,
|
|
156
|
+
}, null, span)
|
|
157
|
+
.catch(function (e) {
|
|
158
|
+
(0, arvo_core_1.logToSpan)({
|
|
159
|
+
level: 'CRITICAL',
|
|
160
|
+
message: "Error in orchestrator persisting the failure state: ".concat(e.message),
|
|
161
|
+
});
|
|
162
|
+
})];
|
|
163
|
+
case 1:
|
|
164
|
+
_f.sent();
|
|
165
|
+
(0, arvo_core_1.logToSpan)({
|
|
166
|
+
level: 'ERROR',
|
|
167
|
+
message: "".concat(handlerType || 'Arvo orchestration handler', " execution failed: ").concat(error.message),
|
|
168
|
+
});
|
|
169
|
+
errorEvents = (0, exports.createSystemErrorEvents)(__assign(__assign({}, param), { error: error }));
|
|
170
|
+
for (_i = 0, _a = Object.entries(errorEvents); _i < _a.length; _i++) {
|
|
171
|
+
_b = _a[_i], errEvtIdx = _b[0], errEvt = _b[1];
|
|
172
|
+
for (_c = 0, _d = Object.entries(errEvt.otelAttributes); _c < _d.length; _c++) {
|
|
173
|
+
_e = _d[_c], key = _e[0], value = _e[1];
|
|
174
|
+
span.setAttribute("to_emit.".concat(errEvtIdx, ".").concat(key), value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [2 /*return*/, {
|
|
178
|
+
errorToThrow: null,
|
|
179
|
+
events: errorEvents,
|
|
180
|
+
}];
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}); };
|
|
184
|
+
exports.handleOrchestrationErrors = handleOrchestrationErrors;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const OrchestrationExecutionStatus: {
|
|
2
|
+
readonly FAILURE: "failure";
|
|
3
|
+
readonly NORMAL: "normal";
|
|
4
|
+
};
|
|
5
|
+
export type OrchestrationExecutionMemoryRecord<T extends Record<string, unknown>> = (T & {
|
|
6
|
+
executionStatus: typeof OrchestrationExecutionStatus.NORMAL;
|
|
7
|
+
}) | (Partial<T> & {
|
|
8
|
+
executionStatus: typeof OrchestrationExecutionStatus.FAILURE;
|
|
9
|
+
error: Error;
|
|
10
|
+
subject: string;
|
|
11
|
+
});
|
package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/acquireLockWithValidation.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Span } from '@opentelemetry/api';
|
|
2
|
+
import { type ArvoEvent } from 'arvo-core';
|
|
3
|
+
import type { SyncEventResource } from '../../SyncEventResource';
|
|
4
|
+
import type { AcquiredLockStatusType } from '../../SyncEventResource/types';
|
|
5
|
+
/**
|
|
6
|
+
* Handles lock acquisition with proper error handling
|
|
7
|
+
*/
|
|
8
|
+
export declare const acquireLockWithValidation: (syncEventResource: SyncEventResource<Record<string, any>>, event: ArvoEvent, span: Span) => Promise<AcquiredLockStatusType>;
|
package/dist/ArvoOrchestrationUtils/orchestrationExecutionWrapper/acquireLockWithValidation.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
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);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
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;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.acquireLockWithValidation = void 0;
|
|
40
|
+
var arvo_core_1 = require("arvo-core");
|
|
41
|
+
var error_1 = require("../error");
|
|
42
|
+
/**
|
|
43
|
+
* Handles lock acquisition with proper error handling
|
|
44
|
+
*/
|
|
45
|
+
var acquireLockWithValidation = function (syncEventResource, event, span) { return __awaiter(void 0, void 0, void 0, function () {
|
|
46
|
+
var acquiredLock;
|
|
47
|
+
return __generator(this, function (_a) {
|
|
48
|
+
switch (_a.label) {
|
|
49
|
+
case 0: return [4 /*yield*/, syncEventResource.acquireLock(event, span)];
|
|
50
|
+
case 1:
|
|
51
|
+
acquiredLock = _a.sent();
|
|
52
|
+
if (acquiredLock === 'NOT_ACQUIRED') {
|
|
53
|
+
throw new error_1.TransactionViolation({
|
|
54
|
+
cause: error_1.TransactionViolationCause.LOCK_UNACQUIRED,
|
|
55
|
+
message: 'Lock acquisition denied - Unable to obtain exclusive access to event processing',
|
|
56
|
+
initiatingEvent: event,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (acquiredLock === 'ACQUIRED') {
|
|
60
|
+
(0, arvo_core_1.logToSpan)({
|
|
61
|
+
level: 'INFO',
|
|
62
|
+
message: "This execution acquired lock at resource '".concat(event.subject, "'"),
|
|
63
|
+
}, span);
|
|
64
|
+
}
|
|
65
|
+
return [2 /*return*/, acquiredLock];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}); };
|
|
69
|
+
exports.acquireLockWithValidation = acquireLockWithValidation;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type Span } from '@opentelemetry/api';
|
|
2
|
+
import { type ArvoEvent, type ArvoOrchestrationSubjectContent, type ArvoOrchestratorContract, type ArvoSemanticVersion, type OpenTelemetryHeaders, type VersionedArvoContract } from 'arvo-core';
|
|
3
|
+
import type IArvoEventHandler from '../../IArvoEventHandler';
|
|
4
|
+
import type { SyncEventResource } from '../../SyncEventResource';
|
|
5
|
+
import type { ArvoEventHandlerOpenTelemetryOptions } from '../../types';
|
|
6
|
+
import type { OrchestrationExecutionMemoryRecord } from '../orchestrationExecutionState';
|
|
7
|
+
import type { ArvoOrchestrationHandlerType } from '../types';
|
|
8
|
+
export type OrchestrationExecutionContext<TState extends OrchestrationExecutionMemoryRecord<Record<string, any>>> = {
|
|
9
|
+
event: ArvoEvent;
|
|
10
|
+
opentelemetry: ArvoEventHandlerOpenTelemetryOptions;
|
|
11
|
+
spanName: string;
|
|
12
|
+
source: string;
|
|
13
|
+
syncEventResource: SyncEventResource<TState>;
|
|
14
|
+
executionunits: number;
|
|
15
|
+
systemErrorDomain?: (string | null)[];
|
|
16
|
+
selfContract: VersionedArvoContract<ArvoOrchestratorContract, ArvoSemanticVersion>;
|
|
17
|
+
domain: string | null;
|
|
18
|
+
_handlerType: ArvoOrchestrationHandlerType;
|
|
19
|
+
};
|
|
20
|
+
export type CoreExecutionFn<TState extends OrchestrationExecutionMemoryRecord<Record<string, any>>> = (params: {
|
|
21
|
+
span: any;
|
|
22
|
+
otelHeaders: OpenTelemetryHeaders;
|
|
23
|
+
orchestrationParentSubject: string | null;
|
|
24
|
+
initEventId: string;
|
|
25
|
+
parsedEventSubject: ArvoOrchestrationSubjectContent;
|
|
26
|
+
state: TState | null;
|
|
27
|
+
_handlerType: ArvoOrchestrationHandlerType;
|
|
28
|
+
}) => Promise<{
|
|
29
|
+
emittables: ArvoEvent[];
|
|
30
|
+
newState: TState;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const returnEventsWithLogging: (param: Awaited<ReturnType<IArvoEventHandler["execute"]>>, span: Span) => Awaited<ReturnType<IArvoEventHandler["execute"]>>;
|
|
33
|
+
/**
|
|
34
|
+
* Wraps orchestration execution with common infrastructure:
|
|
35
|
+
* - OpenTelemetry span management
|
|
36
|
+
* - Lock acquisition and release
|
|
37
|
+
* - State management
|
|
38
|
+
* - Error handling and system error generation
|
|
39
|
+
*/
|
|
40
|
+
export declare const executeWithOrchestrationWrapper: <TState extends OrchestrationExecutionMemoryRecord<Record<string, any>>>({ event, opentelemetry, spanName, source, syncEventResource, executionunits, systemErrorDomain, selfContract, domain, _handlerType, }: OrchestrationExecutionContext<TState>, coreExecutionFn: CoreExecutionFn<TState>) => Promise<Awaited<ReturnType<IArvoEventHandler["execute"]>>>;
|