@live-change/framework 0.9.171 → 0.9.173
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/lib/App.js +328 -239
- package/lib/processes/commandExecutor.js +126 -56
- package/lib/processes/eventListener.js +32 -7
- package/lib/processes/triggerExecutor.js +28 -1
- package/lib/runtime/Action.js +63 -34
- package/lib/runtime/TriggerHandler.js +130 -55
- package/lib/utils.js +55 -0
- package/package.json +4 -4
- package/tsconfig.json +3 -2
- package/LICENSE.md +0 -11
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import KeyBasedExecutionQueues from '../utils/KeyBasedExecutionQueues.js'
|
|
2
|
-
import CommandQueue from '../utils/CommandQueue.js'
|
|
3
|
-
import SingleEmitQueue from '../utils/SingleEmitQueue.js'
|
|
4
|
-
import SplitEmitQueue from '../utils/SplitEmitQueue.js'
|
|
1
|
+
import KeyBasedExecutionQueues from '../utils/KeyBasedExecutionQueues.js'
|
|
2
|
+
import CommandQueue from '../utils/CommandQueue.js'
|
|
3
|
+
import SingleEmitQueue from '../utils/SingleEmitQueue.js'
|
|
4
|
+
import SplitEmitQueue from '../utils/SplitEmitQueue.js'
|
|
5
|
+
|
|
6
|
+
import { context, propagation, trace } from '@opentelemetry/api'
|
|
7
|
+
import { SpanKind } from '@opentelemetry/api'
|
|
8
|
+
const tracer = trace.getTracer('live-change:commandExecutor')
|
|
9
|
+
|
|
10
|
+
import { expandObjectAttributes } from '../utils.js'
|
|
11
|
+
|
|
12
|
+
function spanAttributes(command, service, action) {
|
|
13
|
+
return {
|
|
14
|
+
service: service.name,
|
|
15
|
+
action_name: action.definition.name,
|
|
16
|
+
action_waitForEvents: action.definition.waitForEvents,
|
|
17
|
+
action_timeout: action.definition.timeout,
|
|
18
|
+
action_requestTimeout: action.definition.requestTimeout,
|
|
19
|
+
...expandObjectAttributes(command, 'command'),
|
|
20
|
+
}
|
|
21
|
+
}
|
|
5
22
|
|
|
6
23
|
async function startCommandExecutor(service, config) {
|
|
7
24
|
if(!config.runCommands) return
|
|
@@ -21,71 +38,124 @@ async function startCommandExecutor(service, config) {
|
|
|
21
38
|
Array.isArray(queuedBy) ? (c) => JSON.stringify(queuedBy.map(k => c[k])) :
|
|
22
39
|
(c) => JSON.stringify(c[queuedBy]))
|
|
23
40
|
service.commandQueue.addCommandHandler(actionName, async (command) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
if(command._trace) {
|
|
42
|
+
propagation.extract(context.active(), command._trace)
|
|
43
|
+
}
|
|
44
|
+
return tracer.startActiveSpan('queueCommand:'+command.service+'.'+command.type, {
|
|
45
|
+
root: !command._trace,
|
|
46
|
+
attributes: spanAttributes(command, service, action)
|
|
47
|
+
}, async (queueSpan) => {
|
|
48
|
+
console.log("COMMAND TRACE", command._trace)
|
|
49
|
+
|
|
50
|
+
const queueContext = context.active()
|
|
51
|
+
|
|
52
|
+
const profileOp = await service.profileLog.begin({
|
|
53
|
+
operation: 'queueCommand', commandType: actionName,
|
|
54
|
+
commandId: command.id, client: command.client
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const routine = () => service.profileLog.profile({
|
|
58
|
+
operation: 'runCommand', commandType: actionName,
|
|
59
|
+
commandId: command.id, client: command.client
|
|
60
|
+
}, async () => {
|
|
61
|
+
return tracer.startActiveSpan('handleCommand:'+command.service+'.'+command.type, {
|
|
62
|
+
kind: SpanKind.INTERNAL,
|
|
63
|
+
attributes: spanAttributes(command, service, action)
|
|
64
|
+
}, queueContext, async (handleSpan) => {
|
|
65
|
+
|
|
66
|
+
const _trace = {}
|
|
67
|
+
propagation.inject(context.active(), _trace)
|
|
68
|
+
const reportFinished = action.definition.waitForEvents ? 'command_' + command.id : undefined
|
|
69
|
+
const flags = { commandId: command.id, reportFinished, _trace }
|
|
70
|
+
const emit = (!service.app.splitEvents || this.shortEvents)
|
|
71
|
+
? new SingleEmitQueue(service, flags)
|
|
72
|
+
: new SplitEmitQueue(service, flags)
|
|
73
|
+
|
|
74
|
+
const result = await service.app.assertTime('command ' + action.definition.name,
|
|
75
|
+
action.definition.timeout || 10000,
|
|
76
|
+
async () => action.runCommand(command, (...args) => emit.emit(...args)), command)
|
|
77
|
+
|
|
78
|
+
return tracer.startActiveSpan('handleEvents', {
|
|
79
|
+
kind: SpanKind.INTERNAL,
|
|
80
|
+
attributes: spanAttributes(command, service, action)
|
|
81
|
+
}, queueContext, async (handleEventsSpan) => {
|
|
82
|
+
|
|
83
|
+
if(service.app.shortEvents) {
|
|
84
|
+
const bucket = {}
|
|
85
|
+
const eventsPromise = Promise.all(emit.emittedEvents.map(event => {
|
|
86
|
+
const handlerService = service.app.startedServices[event.service]
|
|
87
|
+
const handler = handlerService.events[event.type]
|
|
88
|
+
handlerService.exentQueue.queue(() => handler.execute(event, bucket))
|
|
89
|
+
}))
|
|
90
|
+
if (action.definition.waitForEvents) await eventsPromise
|
|
91
|
+
} else {
|
|
92
|
+
const events = await emit.commit()
|
|
93
|
+
if (action.definition.waitForEvents)
|
|
94
|
+
await service.app.waitForEvents(reportFinished, events, action.definition.waitForEvents)
|
|
95
|
+
}
|
|
96
|
+
handleEventsSpan.end()
|
|
97
|
+
handleSpan.end()
|
|
98
|
+
queueSpan.end()
|
|
99
|
+
return result
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
routine.key = keyFunction(command)
|
|
104
|
+
const promise = service.keyBasedExecutionQueues.queue(routine)
|
|
105
|
+
await service.profileLog.endPromise(profileOp, promise)
|
|
106
|
+
return promise
|
|
27
107
|
})
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
: new SplitEmitQueue(service, flags)
|
|
33
|
-
const routine = () => service.profileLog.profile({
|
|
108
|
+
})
|
|
109
|
+
} else {
|
|
110
|
+
service.commandQueue.addCommandHandler(actionName,
|
|
111
|
+
(command) => service.profileLog.profile({
|
|
34
112
|
operation: 'runCommand', commandType: actionName,
|
|
35
113
|
commandId: command.id, client: command.client
|
|
36
114
|
}, async () => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
() => action.runCommand(command, (...args) => emit.emit(...args)), command)
|
|
40
|
-
if(service.app.shortEvents) {
|
|
41
|
-
const bucket = {}
|
|
42
|
-
const eventsPromise = Promise.all(emit.emittedEvents.map(event => {
|
|
43
|
-
const handlerService = service.app.startedServices[event.service]
|
|
44
|
-
const handler = handlerService.events[event.type]
|
|
45
|
-
handlerService.exentQueue.queue(() => handler.execute(event, bucket))
|
|
46
|
-
}))
|
|
47
|
-
if (action.definition.waitForEvents) await eventsPromise
|
|
48
|
-
} else {
|
|
49
|
-
const events = await emit.commit()
|
|
50
|
-
if (action.definition.waitForEvents)
|
|
51
|
-
await service.app.waitForEvents(reportFinished, events, action.definition.waitForEvents)
|
|
115
|
+
if(command._trace) {
|
|
116
|
+
propagation.extract(context.active(), command._trace)
|
|
52
117
|
}
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
(command) => service.profileLog.profile({
|
|
63
|
-
operation: 'runCommand', commandType: actionName,
|
|
64
|
-
commandId: command.id, client: command.client
|
|
65
|
-
}, async () => {
|
|
118
|
+
return tracer.startActiveSpan('handleCommand:'+command.service+'.'+command.type, {
|
|
119
|
+
kind: SpanKind.INTERNAL,
|
|
120
|
+
attributes: spanAttributes(command, service, action)
|
|
121
|
+
}, async (handleSpan) => {
|
|
122
|
+
|
|
123
|
+
const handleContext = context.active()
|
|
124
|
+
|
|
125
|
+
const _trace = {}
|
|
126
|
+
propagation.inject(context.active(), _trace)
|
|
66
127
|
const reportFinished = action.definition.waitForEvents ? 'command_' + command.id : undefined
|
|
67
|
-
const flags = {commandId: command.id, reportFinished}
|
|
128
|
+
const flags = { commandId: command.id, reportFinished, _trace }
|
|
68
129
|
const emit = (!service.app.splitEvents || this.shortEvents)
|
|
69
130
|
? new SingleEmitQueue(service, flags)
|
|
70
131
|
: new SplitEmitQueue(service, flags)
|
|
71
132
|
const result = await service.app.assertTime('command ' + action.definition.name,
|
|
72
133
|
action.definition.timeout || 10000,
|
|
73
134
|
() => action.runCommand(command, (...args) => emit.emit(...args)), command)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
135
|
+
|
|
136
|
+
return tracer.startActiveSpan('emitEvents', {
|
|
137
|
+
kind: SpanKind.INTERNAL,
|
|
138
|
+
attributes: spanAttributes(command, service, action)
|
|
139
|
+
}, handleContext, async (handleEventsSpan) => {
|
|
140
|
+
if(service.app.shortEvents) {
|
|
141
|
+
const bucket = {}
|
|
142
|
+
const eventsPromise = Promise.all(emit.emittedEvents.map(event => {
|
|
143
|
+
const handlerService = service.app.startedServices[event.service]
|
|
144
|
+
const handler = handlerService.events[event.type]
|
|
145
|
+
handlerService.exentQueue.queue(() => handler.execute(event, bucket))
|
|
146
|
+
}))
|
|
147
|
+
if (action.definition.waitForEvents) await eventsPromise
|
|
148
|
+
} else {
|
|
149
|
+
const events = await emit.commit()
|
|
150
|
+
if (action.definition.waitForEvents)
|
|
151
|
+
await service.app.waitForEvents(reportFinished, events, action.definition.waitForEvents)
|
|
152
|
+
}
|
|
153
|
+
handleEventsSpan.end()
|
|
154
|
+
handleSpan.end()
|
|
155
|
+
return result
|
|
156
|
+
})
|
|
88
157
|
})
|
|
158
|
+
})
|
|
89
159
|
)
|
|
90
160
|
|
|
91
161
|
}
|
|
@@ -3,6 +3,19 @@ import EventSourcing from '../utils/EventSourcing.js'
|
|
|
3
3
|
import Debug from 'debug'
|
|
4
4
|
const debug = Debug("framework:eventListener")
|
|
5
5
|
|
|
6
|
+
import { context, propagation, trace } from '@opentelemetry/api'
|
|
7
|
+
import { SpanKind } from '@opentelemetry/api'
|
|
8
|
+
const tracer = trace.getTracer('live-change:eventListener')
|
|
9
|
+
|
|
10
|
+
import { expandObjectAttributes } from '../utils.js'
|
|
11
|
+
|
|
12
|
+
async function spanAttributes(ev, service) {
|
|
13
|
+
return {
|
|
14
|
+
...expandObjectAttributes(ev, 'event'),
|
|
15
|
+
service: service.name
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
6
19
|
async function startEventListener(service, config) {
|
|
7
20
|
if(!config.handleEvents) return
|
|
8
21
|
|
|
@@ -19,13 +32,25 @@ async function startEventListener(service, config) {
|
|
|
19
32
|
for (let eventName in service.events) {
|
|
20
33
|
const event = service.events[eventName]
|
|
21
34
|
service.eventSourcing.addEventHandler(eventName, async (ev, bucket) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
35
|
+
if(ev._trace) {
|
|
36
|
+
propagation.extract(context.active(), ev._trace)
|
|
37
|
+
}
|
|
38
|
+
return tracer.startActiveSpan('handleEvent:'+service.name+'.'+eventName, {
|
|
39
|
+
kind: SpanKind.INTERNAL,
|
|
40
|
+
attributes: spanAttributes(ev, service)
|
|
41
|
+
}, async (handleSpan) => {
|
|
42
|
+
try {
|
|
43
|
+
return await service.profileLog.profile({ operation: "handleEvent", eventName, id: ev.id,
|
|
44
|
+
bucketId: bucket.id, triggerId: bucket.triggerId, commandId: bucket.commandId },
|
|
45
|
+
() => {
|
|
46
|
+
debug("EXECUTING EVENT", ev)
|
|
47
|
+
return event.execute(ev, bucket)
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
} finally {
|
|
51
|
+
handleSpan.end()
|
|
52
|
+
}
|
|
53
|
+
})
|
|
29
54
|
})
|
|
30
55
|
service.eventSourcing.onBucketEnd = async (bucket, handledEvents) => {
|
|
31
56
|
if(bucket.reportFinished && handledEvents.length > 0) {
|
|
@@ -3,6 +3,19 @@ import CommandQueue from '../utils/CommandQueue.js'
|
|
|
3
3
|
import SingleEmitQueue from '../utils/SingleEmitQueue.js'
|
|
4
4
|
import SplitEmitQueue from '../utils/SplitEmitQueue.js'
|
|
5
5
|
|
|
6
|
+
import { context, propagation, trace } from '@opentelemetry/api'
|
|
7
|
+
import { SpanKind } from '@opentelemetry/api'
|
|
8
|
+
const tracer = trace.getTracer('live-change:triggerExecutor')
|
|
9
|
+
|
|
10
|
+
import { expandObjectAttributes } from '../utils.js'
|
|
11
|
+
|
|
12
|
+
async function spanAttributes(trig, service) {
|
|
13
|
+
return {
|
|
14
|
+
...expandObjectAttributes(trig, 'trigger'),
|
|
15
|
+
service: service.name
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
6
19
|
async function startTriggerExecutor(service, config) {
|
|
7
20
|
if(!config.runCommands) return
|
|
8
21
|
|
|
@@ -27,7 +40,21 @@ async function startTriggerExecutor(service, config) {
|
|
|
27
40
|
await service.dao.request(['database', 'put'], service.databaseName, 'triggerRoutes',
|
|
28
41
|
{ id: triggerName + '=>' + service.name, trigger: triggerName, service: service.name })
|
|
29
42
|
service.triggerQueue.addCommandHandler(triggerName,
|
|
30
|
-
(trig) =>
|
|
43
|
+
async (trig) => {
|
|
44
|
+
if(trig._trace) {
|
|
45
|
+
propagation.extract(context.active(), trig._trace)
|
|
46
|
+
}
|
|
47
|
+
return tracer.startActiveSpan('handleTriggerCall:'+service.name+'.'+triggerName, {
|
|
48
|
+
kind: SpanKind.INTERNAL,
|
|
49
|
+
attributes: spanAttributes(trig, service)
|
|
50
|
+
}, async (triggerSpan) => {
|
|
51
|
+
try {
|
|
52
|
+
return await Promise.all(triggers.map( trigger => trigger.execute(trig, service) ))
|
|
53
|
+
} finally {
|
|
54
|
+
triggerSpan.end()
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}
|
|
31
58
|
)
|
|
32
59
|
}
|
|
33
60
|
|
package/lib/runtime/Action.js
CHANGED
|
@@ -1,57 +1,86 @@
|
|
|
1
1
|
import { prepareParameters, processReturn, preFilterParameters } from "./params.js"
|
|
2
2
|
|
|
3
|
+
import { context, propagation, trace } from '@opentelemetry/api'
|
|
4
|
+
import { loggingHelpers } from '../utils.js'
|
|
5
|
+
import { SpanKind } from '@opentelemetry/api'
|
|
6
|
+
const tracer = trace.getTracer('live-change:action')
|
|
7
|
+
|
|
8
|
+
import { expandObjectAttributes } from '../utils.js'
|
|
9
|
+
|
|
3
10
|
class Action {
|
|
4
11
|
|
|
5
12
|
constructor(definition, service) {
|
|
6
13
|
this.definition = definition
|
|
7
14
|
this.service = service
|
|
15
|
+
this.loggingHelpers = loggingHelpers(this.service.name, this.service.app.config.clientConfig.version, {
|
|
16
|
+
action: this.definition.name,
|
|
17
|
+
})
|
|
8
18
|
}
|
|
9
19
|
|
|
10
|
-
async runCommand(command, emit) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
command
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
async runCommand(command, emit, traceContext) {
|
|
21
|
+
return tracer.startActiveSpan('runCommand:'+this.service.name+'.'+this.definition.name, {
|
|
22
|
+
kind: SpanKind.SERVER,
|
|
23
|
+
attributes: {
|
|
24
|
+
...expandObjectAttributes(command, 'command'),
|
|
25
|
+
service: this.service.name,
|
|
26
|
+
action_name: this.definition.name,
|
|
27
|
+
action_waitForEvents: this.definition.waitForEvents,
|
|
28
|
+
action_timeout: this.definition.timeout,
|
|
29
|
+
action_requestTimeout: this.definition.requestTimeout,
|
|
30
|
+
}
|
|
31
|
+
}, traceContext, async (runSpan) => {
|
|
32
|
+
|
|
33
|
+
let parameters = command.parameters
|
|
34
|
+
//console.log("PARAMETERS", JSON.stringify(parameters), "DEFN", this.definition.properties)
|
|
35
|
+
let preparedParams = await prepareParameters(parameters, this.definition.properties, this.service)
|
|
36
|
+
//console.log("PREP PARAMS", preparedParams)
|
|
37
|
+
|
|
38
|
+
let resultPromise = (async () => this.definition.execute({
|
|
39
|
+
...parameters,
|
|
40
|
+
...preparedParams
|
|
41
|
+
}, {
|
|
42
|
+
action: this,
|
|
43
|
+
service: this.service,
|
|
33
44
|
client: command.client,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
command,
|
|
46
|
+
trigger: (trigger, data) => this.service.trigger({
|
|
47
|
+
causeType: 'action',
|
|
48
|
+
cause: command.id,
|
|
49
|
+
client: command.client,
|
|
50
|
+
...trigger
|
|
51
|
+
}, data),
|
|
52
|
+
triggerService: (trigger, data, returnArray = false) => this.service.triggerService({
|
|
53
|
+
causeType: 'action',
|
|
54
|
+
cause: command.id,
|
|
55
|
+
client: command.client,
|
|
56
|
+
...trigger
|
|
57
|
+
}, data, returnArray),
|
|
58
|
+
...this.loggingHelpers
|
|
59
|
+
}, emit))()
|
|
37
60
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
61
|
+
resultPromise = resultPromise.then(async result => {
|
|
62
|
+
let processedResult = await processReturn(result, this.definition.returns, this.service)
|
|
63
|
+
runSpan.end()
|
|
64
|
+
return processedResult
|
|
65
|
+
})
|
|
66
|
+
resultPromise.catch(error => {
|
|
67
|
+
this.loggingHelpers.error(`Action ${this.definition.name} error `, error.stack || error)
|
|
68
|
+
runSpan.end()
|
|
69
|
+
})
|
|
70
|
+
return resultPromise
|
|
44
71
|
})
|
|
45
|
-
return resultPromise
|
|
46
72
|
}
|
|
47
73
|
|
|
48
74
|
async callCommand(parameters, clientData) {
|
|
49
75
|
// if(!clientData.roles) throw new Error("no roles") - roles are not required in frontend
|
|
76
|
+
const _trace = {}
|
|
77
|
+
propagation.inject(context.active(), _trace)
|
|
50
78
|
const command = {
|
|
51
79
|
type: this.definition.name,
|
|
52
80
|
service: this.service.name,
|
|
53
81
|
client: clientData,
|
|
54
|
-
parameters: await preFilterParameters(parameters, this.definition.properties)
|
|
82
|
+
parameters: await preFilterParameters(parameters, this.definition.properties),
|
|
83
|
+
_trace
|
|
55
84
|
}
|
|
56
85
|
if(parameters._commandId) command.id = parameters._commandId
|
|
57
86
|
//console.log("CALL COMMAND", JSON.stringify(command, null, " "))
|
|
@@ -2,6 +2,21 @@ import { prepareParameters, processReturn } from "./params.js"
|
|
|
2
2
|
import SplitEmitQueue from "../utils/SplitEmitQueue.js"
|
|
3
3
|
import SingleEmitQueue from "../utils/SingleEmitQueue.js"
|
|
4
4
|
|
|
5
|
+
import { context, propagation, trace } from '@opentelemetry/api'
|
|
6
|
+
import { SpanKind } from '@opentelemetry/api'
|
|
7
|
+
const tracer = trace.getTracer('live-change:triggerHandler')
|
|
8
|
+
|
|
9
|
+
import { expandObjectAttributes } from '../utils.js'
|
|
10
|
+
|
|
11
|
+
async function spanAttributes(trig, service) {
|
|
12
|
+
return {
|
|
13
|
+
...expandObjectAttributes(trig, 'trigger'),
|
|
14
|
+
service: service.name
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
import { loggingHelpers } from '../utils.js'
|
|
19
|
+
|
|
5
20
|
class TriggerHandler {
|
|
6
21
|
|
|
7
22
|
constructor(definition, service) {
|
|
@@ -14,6 +29,10 @@ class TriggerHandler {
|
|
|
14
29
|
Array.isArray(queuedBy) ? (c) => JSON.stringify(queuedBy.map(k=>c[k])) :
|
|
15
30
|
(c) => JSON.stringify(c[queuedBy]) )
|
|
16
31
|
}
|
|
32
|
+
|
|
33
|
+
this.loggingHelpers = loggingHelpers(service.name, service.app.config.clientConfig.version, {
|
|
34
|
+
triggerType: definition.name,
|
|
35
|
+
})
|
|
17
36
|
}
|
|
18
37
|
|
|
19
38
|
async doExecute(trig, emit) {
|
|
@@ -42,7 +61,8 @@ class TriggerHandler {
|
|
|
42
61
|
cause: trig.id,
|
|
43
62
|
client: trig.client,
|
|
44
63
|
...trigger
|
|
45
|
-
}, data, returnArray)
|
|
64
|
+
}, data, returnArray),
|
|
65
|
+
...this.loggingHelpers
|
|
46
66
|
}, emit))
|
|
47
67
|
//console.log("RESULT PROMISE", resultPromise, resultPromise.then)
|
|
48
68
|
resultPromise = resultPromise.then(async result => {
|
|
@@ -50,75 +70,130 @@ class TriggerHandler {
|
|
|
50
70
|
return processedResult
|
|
51
71
|
})
|
|
52
72
|
resultPromise.catch(error => {
|
|
53
|
-
|
|
73
|
+
this.loggingHelpers.error(`Trigger ${this.definition.name} error `, error)
|
|
54
74
|
})
|
|
55
75
|
return resultPromise
|
|
56
76
|
}
|
|
57
77
|
|
|
58
78
|
async execute(trig, service) {
|
|
59
|
-
console.log("EXECUTE", trig, this.queueKeyFunction)
|
|
79
|
+
//console.log("EXECUTE", trig, this.queueKeyFunction)
|
|
60
80
|
const profileOp = await service.profileLog.begin({
|
|
61
81
|
operation: 'queueTrigger', triggerType: this.definition.name,
|
|
62
82
|
triggerId: trig.id, by: trig.by
|
|
63
83
|
})
|
|
64
84
|
if(this.queueKeyFunction) {
|
|
65
|
-
console.log("QUEUED TRIGGER STARTED", trig)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}, async () => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
//console.log("QUEUED TRIGGER STARTED", trig)
|
|
86
|
+
return tracer.startActiveSpan('queueTrigger:'+service.name+'.'+this.definition.name, {
|
|
87
|
+
kind: SpanKind.INTERNAL,
|
|
88
|
+
attributes: spanAttributes(trig, service)
|
|
89
|
+
}, async (queueSpan) => {
|
|
90
|
+
const queueContext = context.active()
|
|
91
|
+
|
|
92
|
+
const routine = () => service.profileLog.profile({
|
|
93
|
+
operation: 'runTrigger', triggerType: this.definition.name,
|
|
94
|
+
commandId: trig.id, by: trig.by
|
|
95
|
+
}, async () => {
|
|
96
|
+
return tracer.startActiveSpan('handleTrigger:'+service.name+'.'+this.definition.name, {
|
|
97
|
+
kind: SpanKind.INTERNAL,
|
|
98
|
+
attributes: spanAttributes(trig, service)
|
|
99
|
+
}, queueContext, async (handleSpan) => {
|
|
100
|
+
let result
|
|
101
|
+
const reportFinished = this.definition.waitForEvents ? 'trigger_' + trig.id : undefined
|
|
102
|
+
const _trace = {}
|
|
103
|
+
propagation.inject(context.active(), _trace)
|
|
104
|
+
const flags = {triggerId: trig.id, reportFinished, _trace }
|
|
105
|
+
const emit = service.app.splitEvents
|
|
106
|
+
? new SplitEmitQueue(service, flags)
|
|
107
|
+
: new SingleEmitQueue(service, flags)
|
|
108
|
+
|
|
109
|
+
await tracer.startActiveSpan('runTrigger', {
|
|
110
|
+
kind: SpanKind.SERVER,
|
|
111
|
+
attributes: spanAttributes(trig, service)
|
|
112
|
+
}, queueContext, async (runSpan) => {
|
|
113
|
+
try {
|
|
114
|
+
//console.log("TRIGGER RUNNING!", trig)
|
|
115
|
+
|
|
116
|
+
result = await service.app.assertTime('trigger ' + this.definition.name,
|
|
117
|
+
this.definition.timeout || 10000,
|
|
118
|
+
() => this.doExecute(trig, (...args) => emit.emit(...args)))
|
|
119
|
+
} catch (e) {
|
|
120
|
+
this.loggingHelpers.error(`Trigger ${this.definition.name} error `, e.stack)
|
|
121
|
+
runSpan.end()
|
|
122
|
+
handleSpan.end()
|
|
123
|
+
queueSpan.end()
|
|
124
|
+
throw e
|
|
125
|
+
}
|
|
126
|
+
runSpan.end()
|
|
127
|
+
return result
|
|
128
|
+
})
|
|
129
|
+
return await tracer.startActiveSpan('emitEvents', {
|
|
130
|
+
kind: SpanKind.INTERNAL,
|
|
131
|
+
attributes: spanAttributes(trig, service)
|
|
132
|
+
}, queueContext, async (emitEventsSpan) => {
|
|
133
|
+
const events = await emit.commit()
|
|
134
|
+
if (this.definition.waitForEvents)
|
|
135
|
+
await service.app.waitForEvents(reportFinished, events, this.definition.waitForEvents)
|
|
136
|
+
emitEventsSpan.end()
|
|
137
|
+
handleSpan.end()
|
|
138
|
+
queueSpan.end()
|
|
139
|
+
return result
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
|
76
143
|
try {
|
|
77
|
-
|
|
78
|
-
result = await service.app.assertTime('trigger ' + this.definition.name,
|
|
79
|
-
this.definition.timeout || 10000,
|
|
80
|
-
() => this.doExecute(trig, (...args) => emit.emit(...args)))
|
|
81
|
-
console.log("TRIGGER DONE!", trig)
|
|
144
|
+
routine.key = this.queueKeyFunction(trig)
|
|
82
145
|
} catch (e) {
|
|
83
|
-
|
|
84
|
-
throw e
|
|
146
|
+
this.loggingHelpers.error("Queue key function error ", e)
|
|
85
147
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
148
|
+
this.loggingHelpers.log("Trigger queue key", routine.key)
|
|
149
|
+
const promise = service.keyBasedExecutionQueues.queue(routine)
|
|
150
|
+
await service.profileLog.endPromise(profileOp, promise)
|
|
151
|
+
return promise
|
|
90
152
|
})
|
|
91
|
-
try {
|
|
92
|
-
routine.key = this.queueKeyFunction(trig)
|
|
93
|
-
} catch (e) {
|
|
94
|
-
console.error("QUEUE KEY FUNCTION ERROR", e)
|
|
95
|
-
}
|
|
96
|
-
console.log("TRIGGER QUEUE KEY", routine.key)
|
|
97
|
-
const promise = service.keyBasedExecutionQueues.queue(routine)
|
|
98
|
-
await service.profileLog.endPromise(profileOp, promise)
|
|
99
|
-
return promise
|
|
100
153
|
} else {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
154
|
+
return tracer.startActiveSpan('handleTrigger:'+service.name+'.'+this.definition.name, {
|
|
155
|
+
kind: SpanKind.INTERNAL,
|
|
156
|
+
attributes: spanAttributes(trig, service)
|
|
157
|
+
}, async (handleSpan) => {
|
|
158
|
+
this.loggingHelpers.log("Not queued trigger started", trig)
|
|
159
|
+
const reportFinished = this.definition.waitForEvents ? 'trigger_'+trig.id : undefined
|
|
160
|
+
const _trace = {}
|
|
161
|
+
propagation.inject(context.active(), _trace)
|
|
162
|
+
const flags = { triggerId: trig.id, reportFinished, _trace }
|
|
163
|
+
const emit = service.app.splitEvents
|
|
164
|
+
? new SplitEmitQueue(service, flags)
|
|
165
|
+
: new SingleEmitQueue(service, flags)
|
|
166
|
+
let result
|
|
167
|
+
await tracer.startActiveSpan('runTrigger:'+service.name+'.'+this.definition.name, {
|
|
168
|
+
kind: SpanKind.SERVER,
|
|
169
|
+
attributes: spanAttributes(trig, service)
|
|
170
|
+
}, async (runSpan) => {
|
|
171
|
+
try {
|
|
172
|
+
result = await service.app.assertTime('trigger '+this.definition.name,
|
|
173
|
+
this.definition.timeout || 10000,
|
|
174
|
+
() => this.doExecute(trig, (...args) => emit.emit(...args)))
|
|
175
|
+
runSpan.end()
|
|
176
|
+
this.loggingHelpers.log("Trigger done", trig)
|
|
177
|
+
} catch (e) {
|
|
178
|
+
this.loggingHelpers.error(`Trigger ${this.definition.name} error `, e.stack)
|
|
179
|
+
runSpan.end()
|
|
180
|
+
handleSpan.end()
|
|
181
|
+
throw e
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
return tracer.startActiveSpan('emitEvents', {
|
|
185
|
+
kind: SpanKind.INTERNAL,
|
|
186
|
+
attributes: spanAttributes(trig, service)
|
|
187
|
+
}, async (emitEventsSpan) => {
|
|
188
|
+
const events = await emit.commit()
|
|
189
|
+
if(this.definition.waitForEvents)
|
|
190
|
+
await service.app.waitForEvents(reportFinished, events, this.definition.waitForEvents)
|
|
191
|
+
emitEventsSpan.end()
|
|
192
|
+
handleSpan.end()
|
|
193
|
+
await service.profileLog.end(profileOp)
|
|
194
|
+
return result
|
|
195
|
+
})
|
|
196
|
+
})
|
|
122
197
|
}
|
|
123
198
|
}
|
|
124
199
|
|