@weave-js/core 0.13.0 → 0.14.1
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/broker/context.js +29 -8
- package/lib/broker/defaultOptions.js +2 -0
- package/lib/broker/index.js +1 -39
- package/lib/buildRuntime.js +0 -2
- package/lib/cache/adapters/base.js +0 -3
- package/lib/cache/adapters/inMemory.js +0 -2
- package/lib/cache/adapters/inMemoryLru.js +0 -1
- package/lib/cache/getCacheKeyByObject.js +0 -1
- package/lib/cache/getPropertyFromDataOrMetadata.js +0 -2
- package/lib/errors.js +19 -5
- package/lib/index.js +0 -7
- package/lib/middlewares/tracing/index.js +47 -15
- package/lib/runtime/initActionInvoker.js +8 -9
- package/lib/runtime/initCache.js +0 -1
- package/lib/runtime/initContextFactory.js +6 -8
- package/lib/runtime/initEventbus.js +0 -7
- package/lib/runtime/initLogger.js +0 -3
- package/lib/runtime/initMetrics.js +0 -6
- package/lib/runtime/initServiceManager.js +0 -54
- package/lib/runtime/initTracing.js +7 -2
- package/lib/tracing/collectors/index.js +0 -1
- package/lib/tracing/span.js +9 -3
- package/lib/transport/adapters/adapteBase.js +0 -1
- package/lib/transport/createMessage.js +8 -0
- package/lib/transport/createTransport.js +11 -13
- package/lib/transport/messageHandlers.js +6 -27
- package/lib/types.js +3 -17
- package/package.json +6 -6
package/lib/broker/context.js
CHANGED
|
@@ -21,12 +21,14 @@ const { WeaveMaxCallLevelError, WeaveError } = require('../errors');
|
|
|
21
21
|
* @returns {Context} Context
|
|
22
22
|
*/
|
|
23
23
|
exports.createContext = (runtime) => {
|
|
24
|
+
const spanStack = [];
|
|
25
|
+
|
|
24
26
|
/** @type {Context} */
|
|
25
27
|
const context = {
|
|
26
28
|
id: null,
|
|
27
29
|
nodeId: runtime.nodeId || null,
|
|
30
|
+
parentId: null,
|
|
28
31
|
callerNodeId: null,
|
|
29
|
-
parentContext: null,
|
|
30
32
|
endpoint: null,
|
|
31
33
|
data: {},
|
|
32
34
|
meta: {},
|
|
@@ -42,6 +44,7 @@ exports.createContext = (runtime) => {
|
|
|
42
44
|
},
|
|
43
45
|
duration: 0,
|
|
44
46
|
stopTime: 0,
|
|
47
|
+
isCachedResult: false,
|
|
45
48
|
setData (newParams) {
|
|
46
49
|
this.data = newParams || {};
|
|
47
50
|
},
|
|
@@ -95,17 +98,33 @@ exports.createContext = (runtime) => {
|
|
|
95
98
|
sampled: this.tracing
|
|
96
99
|
}, options);
|
|
97
100
|
|
|
101
|
+
let span;
|
|
102
|
+
|
|
98
103
|
if (this.span) {
|
|
99
|
-
|
|
104
|
+
span = this.span.startChildSpan(name, options);
|
|
100
105
|
} else {
|
|
101
|
-
|
|
106
|
+
span = runtime.tracer.startSpan(name, options);
|
|
102
107
|
}
|
|
108
|
+
spanStack.push(span);
|
|
109
|
+
this.span = span;
|
|
110
|
+
|
|
103
111
|
return this.span;
|
|
104
112
|
},
|
|
105
|
-
finishSpan () {
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
finishSpan (span, time) {
|
|
114
|
+
if (span && !span.isActive()) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
span.finish(time);
|
|
119
|
+
|
|
120
|
+
const idx = spanStack.findIndex((s) => s === span);
|
|
121
|
+
|
|
122
|
+
if (idx !== -1) {
|
|
123
|
+
spanStack.splice(idx, 1);
|
|
124
|
+
this.span = spanStack[spanStack.length - 1];
|
|
125
|
+
} else {
|
|
126
|
+
/* istanbul ignore next */
|
|
127
|
+
this.service.log.warn('This span is not assigned to this context', span);
|
|
109
128
|
}
|
|
110
129
|
},
|
|
111
130
|
/**
|
|
@@ -119,14 +138,16 @@ exports.createContext = (runtime) => {
|
|
|
119
138
|
contextCopy.options = this.options;
|
|
120
139
|
contextCopy.data = this.data;
|
|
121
140
|
contextCopy.meta = this.meta;
|
|
122
|
-
contextCopy.
|
|
141
|
+
contextCopy.parentId = this.parentId;
|
|
123
142
|
contextCopy.callerNodeId = this.callerNodeId;
|
|
124
143
|
contextCopy.requestId = this.requestId;
|
|
125
144
|
contextCopy.tracing = this.tracing;
|
|
145
|
+
contextCopy.span = this.span;
|
|
126
146
|
contextCopy.level = this.level;
|
|
127
147
|
contextCopy.eventName = this.eventName;
|
|
128
148
|
contextCopy.eventType = this.eventType;
|
|
129
149
|
contextCopy.eventGroups = this.eventGroups;
|
|
150
|
+
contextCopy.isCachedResult = this.isCachedResult;
|
|
130
151
|
|
|
131
152
|
return contextCopy;
|
|
132
153
|
}
|
package/lib/broker/index.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* @typedef {import('../types.js').Transport} Transport
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
// node packages
|
|
9
8
|
const { isFunction } = require('@weave-js/utils');
|
|
10
9
|
const path = require('path');
|
|
11
10
|
const glob = require('glob');
|
|
@@ -31,26 +30,21 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
31
30
|
transport
|
|
32
31
|
} = runtime;
|
|
33
32
|
|
|
34
|
-
// Log Messages
|
|
35
33
|
log.info(`Initializing #weave node version ${version}`);
|
|
36
34
|
log.info(`Node Id: ${options.nodeId}`);
|
|
37
35
|
|
|
38
|
-
// Output namespace
|
|
39
36
|
if (options.namespace) {
|
|
40
37
|
log.info(`Namespace: ${options.namespace}`);
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
// Init metrics
|
|
44
40
|
if (runtime.metrics) {
|
|
45
41
|
runtime.metrics.init();
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
// Init cache
|
|
49
44
|
if (runtime.cache) {
|
|
50
45
|
runtime.cache.init();
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
// broker object
|
|
54
48
|
/** @type {Broker} */
|
|
55
49
|
const broker = Object.create(null);
|
|
56
50
|
|
|
@@ -131,7 +125,6 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
131
125
|
const startTime = Date.now();
|
|
132
126
|
await middlewareHandler.callHandlersAsync('starting', [runtime], true);
|
|
133
127
|
|
|
134
|
-
// If transport is used, we connect the transport adapter.
|
|
135
128
|
if (transport) {
|
|
136
129
|
await transport.connect();
|
|
137
130
|
}
|
|
@@ -146,10 +139,8 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
146
139
|
|
|
147
140
|
runtime.state.isStarted = true;
|
|
148
141
|
eventBus.broadcastLocal('$broker.started');
|
|
149
|
-
// refresh local node information
|
|
150
142
|
registry.generateLocalNodeInfo(true);
|
|
151
143
|
|
|
152
|
-
// If transport is used, we set the transport ready to inform the other nodes
|
|
153
144
|
if (transport) {
|
|
154
145
|
await transport.setReady();
|
|
155
146
|
}
|
|
@@ -174,7 +165,6 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
174
165
|
|
|
175
166
|
await middlewareHandler.callHandlersAsync('stopping', [runtime], true);
|
|
176
167
|
|
|
177
|
-
// Stop services
|
|
178
168
|
try {
|
|
179
169
|
await Promise.all(services.serviceList.map(service => service.stop()));
|
|
180
170
|
} catch (error) {
|
|
@@ -182,33 +172,27 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
182
172
|
throw error;
|
|
183
173
|
}
|
|
184
174
|
|
|
185
|
-
// Disconnect transports
|
|
186
175
|
if (transport) {
|
|
187
176
|
await transport.disconnect();
|
|
188
177
|
}
|
|
189
178
|
|
|
190
|
-
// Stop cache
|
|
191
179
|
if (runtime.cache) {
|
|
192
180
|
log.debug('Stopping caching adapters.');
|
|
193
181
|
await runtime.cache.stop();
|
|
194
182
|
}
|
|
195
183
|
|
|
196
|
-
// Stop metrics
|
|
197
184
|
if (runtime.metrics) {
|
|
198
185
|
log.debug('Stopping metrics.');
|
|
199
186
|
await runtime.metrics.stop();
|
|
200
187
|
}
|
|
201
188
|
|
|
202
|
-
// Stop tracers
|
|
203
189
|
if (runtime.tracer) {
|
|
204
190
|
log.debug('Stopping tracing adapters.');
|
|
205
191
|
await runtime.tracer.stop();
|
|
206
192
|
}
|
|
207
193
|
|
|
208
|
-
// Call "stopped" middleware method.
|
|
209
194
|
await middlewareHandler.callHandlersAsync('stopped', [runtime], true);
|
|
210
195
|
|
|
211
|
-
// Call "stopped" lifecycle hook
|
|
212
196
|
if (!runtime.state.isStarted && isFunction(options.stopped)) {
|
|
213
197
|
options.stopped.call(runtime);
|
|
214
198
|
}
|
|
@@ -229,7 +213,7 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
229
213
|
* Ping other nodes
|
|
230
214
|
* @param {string=} nodeId Node ID
|
|
231
215
|
* @param {number} timeout Timeout
|
|
232
|
-
* @returns {Object<string, number
|
|
216
|
+
* @returns {Promise<Object<string, number>>} Result
|
|
233
217
|
*/
|
|
234
218
|
broker.ping = function (nodeId, timeout = 3000) {
|
|
235
219
|
if (transport && transport.isConnected) {
|
|
@@ -250,7 +234,6 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
250
234
|
transport.sendPing(nodeId);
|
|
251
235
|
});
|
|
252
236
|
} else {
|
|
253
|
-
// handle arrays
|
|
254
237
|
const pongs = {};
|
|
255
238
|
|
|
256
239
|
const nodes = registry.nodeCollection.list({})
|
|
@@ -289,7 +272,6 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
289
272
|
return Promise.resolve(nodeId ? null : {});
|
|
290
273
|
};
|
|
291
274
|
|
|
292
|
-
// Register internal broker events
|
|
293
275
|
broker.bus.on('$node.disconnected', ({ nodeId }) => {
|
|
294
276
|
runtime.transport.removePendingRequestsByNodeId(nodeId);
|
|
295
277
|
services.serviceChanged(false);
|
|
@@ -301,101 +283,81 @@ exports.createBrokerInstance = (runtime) => {
|
|
|
301
283
|
* @returns {void}
|
|
302
284
|
*/
|
|
303
285
|
const registerMiddlewares = (customMiddlewares) => {
|
|
304
|
-
// Register custom middlewares
|
|
305
286
|
if (Array.isArray(customMiddlewares) && customMiddlewares.length > 0) {
|
|
306
287
|
customMiddlewares.forEach(middleware => middlewareHandler.add(middleware));
|
|
307
288
|
}
|
|
308
289
|
|
|
309
|
-
// Add the built-in middlewares. (The order is important)
|
|
310
290
|
if (options.loadInternalMiddlewares) {
|
|
311
291
|
middlewareHandler.add(Middlewares.ActionHooks);
|
|
312
292
|
|
|
313
|
-
// Validator middleware
|
|
314
293
|
if (options.validateActionParams && validator) {
|
|
315
294
|
middlewareHandler.add(Middlewares.Validator);
|
|
316
295
|
}
|
|
317
296
|
|
|
318
|
-
// Bulkhead
|
|
319
297
|
if (options.bulkhead.enabled) {
|
|
320
298
|
middlewareHandler.add(Middlewares.Bulkhead);
|
|
321
299
|
}
|
|
322
300
|
|
|
323
|
-
// Cache
|
|
324
301
|
if (runtime.cache) {
|
|
325
302
|
middlewareHandler.add(Middlewares.Cache);
|
|
326
303
|
}
|
|
327
304
|
|
|
328
|
-
// Context tracking
|
|
329
305
|
if (options.contextTracking.enabled) {
|
|
330
306
|
middlewareHandler.add(Middlewares.ContextTracker);
|
|
331
307
|
}
|
|
332
308
|
|
|
333
|
-
// Circuit breaker
|
|
334
309
|
if (options.circuitBreaker.enabled) {
|
|
335
310
|
middlewareHandler.add(Middlewares.CircuitBreaker);
|
|
336
311
|
}
|
|
337
312
|
|
|
338
|
-
// timeout middleware
|
|
339
313
|
middlewareHandler.add(Middlewares.Timeout);
|
|
340
314
|
|
|
341
|
-
// Retry policy
|
|
342
315
|
if (options.retryPolicy.enabled) {
|
|
343
316
|
middlewareHandler.add(Middlewares.Retry);
|
|
344
317
|
}
|
|
345
318
|
|
|
346
|
-
// Error handler
|
|
347
319
|
middlewareHandler.add(Middlewares.ErrorHandler);
|
|
348
320
|
|
|
349
|
-
// Tracing
|
|
350
321
|
if (options.tracing.enabled) {
|
|
351
322
|
middlewareHandler.add(Middlewares.Tracing);
|
|
352
323
|
}
|
|
353
324
|
|
|
354
|
-
// Metrics
|
|
355
325
|
if (options.metrics.enabled) {
|
|
356
326
|
middlewareHandler.add(Middlewares.Metrics);
|
|
357
327
|
}
|
|
358
328
|
}
|
|
359
329
|
|
|
360
|
-
// Wrap runtime and broker methods for middlewares
|
|
361
330
|
runtime.actionInvoker.call = middlewareHandler.wrapMethod('call', runtime.actionInvoker.call);
|
|
362
331
|
runtime.actionInvoker.multiCall = middlewareHandler.wrapMethod('multiCall', broker.multiCall);
|
|
363
332
|
runtime.eventBus.emit = middlewareHandler.wrapMethod('emit', runtime.eventBus.emit);
|
|
364
333
|
runtime.eventBus.broadcast = middlewareHandler.wrapMethod('broadcast', runtime.eventBus.broadcast);
|
|
365
334
|
runtime.eventBus.broadcastLocal = middlewareHandler.wrapMethod('broadcastLocal', runtime.eventBus.broadcastLocal);
|
|
366
335
|
|
|
367
|
-
// Wrap broker methods
|
|
368
336
|
broker.createService = middlewareHandler.wrapMethod('createService', broker.createService);
|
|
369
337
|
broker.loadService = middlewareHandler.wrapMethod('loadService', broker.loadService);
|
|
370
338
|
broker.loadServices = middlewareHandler.wrapMethod('loadServices', broker.loadServices);
|
|
371
339
|
broker.ping = middlewareHandler.wrapMethod('ping', broker.ping);
|
|
372
340
|
};
|
|
373
341
|
|
|
374
|
-
// Run "beforeRegisterMiddlewares" hook
|
|
375
342
|
if (isFunction(options.beforeRegisterMiddlewares)) {
|
|
376
343
|
options.beforeRegisterMiddlewares.call(broker, { broker, runtime });
|
|
377
344
|
}
|
|
378
345
|
|
|
379
|
-
// Register middlewares
|
|
380
346
|
registerMiddlewares(options.middlewares);
|
|
381
347
|
|
|
382
|
-
// Stop the broker greaceful
|
|
383
348
|
/* istanbul ignore next */
|
|
384
349
|
const onClose = () => broker.stop()
|
|
385
350
|
.catch(error => broker.log.error(error))
|
|
386
351
|
.then(() => process.exit(0));
|
|
387
352
|
|
|
388
|
-
// SIGTERM listener
|
|
389
353
|
process.setMaxListeners(0);
|
|
390
354
|
process.on('beforeExit', onClose);
|
|
391
355
|
process.on('exit', onClose);
|
|
392
356
|
process.on('SIGINT', onClose);
|
|
393
357
|
process.on('SIGTERM', onClose);
|
|
394
358
|
|
|
395
|
-
// Add broker reference to runtime
|
|
396
359
|
Object.assign(runtime, { broker });
|
|
397
360
|
|
|
398
|
-
// Call middleware hook for broker created.
|
|
399
361
|
middlewareHandler.callHandlersSync('created', [runtime]);
|
|
400
362
|
|
|
401
363
|
return broker;
|
package/lib/buildRuntime.js
CHANGED
|
@@ -37,7 +37,6 @@ exports.initRuntime = (options) => {
|
|
|
37
37
|
maxListeners: 1000
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
// Create base runtime object
|
|
41
40
|
const runtime = {
|
|
42
41
|
nodeId: options.nodeId,
|
|
43
42
|
version,
|
|
@@ -51,7 +50,6 @@ exports.initRuntime = (options) => {
|
|
|
51
50
|
fatalError: (message, error, killProcess) => fatalErrorHandler(runtime, message, error, killProcess)
|
|
52
51
|
};
|
|
53
52
|
|
|
54
|
-
// Init modules
|
|
55
53
|
initLogger(runtime);
|
|
56
54
|
initUUIDFactory(runtime);
|
|
57
55
|
initMiddlewareHandler(runtime);
|
|
@@ -39,7 +39,6 @@ const createCacheBase = (name, runtime, adapterOptions, options) => {
|
|
|
39
39
|
ttl: null
|
|
40
40
|
}, options),
|
|
41
41
|
init () {
|
|
42
|
-
// register metrics
|
|
43
42
|
if (runtime.metrics) {
|
|
44
43
|
this.metrics = runtime.metrics;
|
|
45
44
|
registerCacheMetrics(runtime.metrics);
|
|
@@ -79,7 +78,6 @@ const createCacheBase = (name, runtime, adapterOptions, options) => {
|
|
|
79
78
|
const prefix = actionName + '.';
|
|
80
79
|
|
|
81
80
|
if (keys) {
|
|
82
|
-
// fast path for single keys
|
|
83
81
|
if (keys.length === 1) {
|
|
84
82
|
const cacheKeyData = getPropertyFromDataOrMetadata(data, metadata, keys[0]);
|
|
85
83
|
const key = getCacheKeyByObject(cacheKeyData);
|
|
@@ -87,7 +85,6 @@ const createCacheBase = (name, runtime, adapterOptions, options) => {
|
|
|
87
85
|
return prefix + generateHash(value);
|
|
88
86
|
}
|
|
89
87
|
|
|
90
|
-
// Handle data cache keys
|
|
91
88
|
if (keys.length > 0) {
|
|
92
89
|
const valueString = keys.reduce((pre, property, index) => {
|
|
93
90
|
let value = getPropertyFromDataOrMetadata(data, metadata, property);
|
|
@@ -36,7 +36,6 @@ const createInMemoryCache = (adapterOptions = {}) => (runtime, options = {}) =>
|
|
|
36
36
|
|
|
37
37
|
ttlTimerHandle.unref();
|
|
38
38
|
|
|
39
|
-
// if a new broker gets connected, we need to clear the cache
|
|
40
39
|
runtime.bus.on('$transport.connected', () => {
|
|
41
40
|
base.log.debug('Transport adapter connected. Cache will be cleared.');
|
|
42
41
|
cache.clear();
|
|
@@ -95,7 +94,6 @@ const createInMemoryCache = (adapterOptions = {}) => (runtime, options = {}) =>
|
|
|
95
94
|
base.metrics.increment(Constants.CACHE_SET_TOTAL);
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
// if ttl is not set in action cache settings, use options ttl
|
|
99
97
|
if (ttl == null) {
|
|
100
98
|
ttl = options.ttl;
|
|
101
99
|
}
|
|
@@ -22,7 +22,6 @@ const createInMemoryLruCache = (adapterOptions) => (runtime, options = {}) => {
|
|
|
22
22
|
|
|
23
23
|
timer.unref();
|
|
24
24
|
|
|
25
|
-
// if a new broker gets connected, we need to clear the cache
|
|
26
25
|
runtime.bus.on('$transport.connected', () => {
|
|
27
26
|
base.log.debug('Transport adapter connected. Cache will be cleared.');
|
|
28
27
|
cache.clear();
|
|
@@ -9,7 +9,6 @@ const getCacheKeyByObject = (value) => {
|
|
|
9
9
|
if (Array.isArray(value)) {
|
|
10
10
|
return '[' + value.map(object => getCacheKeyByObject(object)).join(',') + ']';
|
|
11
11
|
} else if (isObject(value)) {
|
|
12
|
-
// Handle date objects
|
|
13
12
|
if (value instanceof Date) {
|
|
14
13
|
return value.toISOString();
|
|
15
14
|
}
|
|
@@ -8,9 +8,7 @@ const { dotGet } = require('@weave-js/utils');
|
|
|
8
8
|
* @returns {any} Result
|
|
9
9
|
*/
|
|
10
10
|
const getPropertyFromDataOrMetadata = (data, metadata, key) => {
|
|
11
|
-
// if a key starts with ":", the property is picked from metadata
|
|
12
11
|
if (key.startsWith(':')) {
|
|
13
|
-
// remove ':' from key.
|
|
14
12
|
key = key.replace(':', '');
|
|
15
13
|
return dotGet(metadata, key);
|
|
16
14
|
}
|
package/lib/errors.js
CHANGED
|
@@ -7,8 +7,21 @@
|
|
|
7
7
|
const { defaultsDeep } = require('@weave-js/utils');
|
|
8
8
|
const { ExtendableError } = require('./ExtendableError');
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} ErrorOptions
|
|
12
|
+
* @property {string} code Error code
|
|
13
|
+
* @property {boolean} retryable Retryable error
|
|
14
|
+
* @property {*} data Error data
|
|
15
|
+
* @property {string} name Error name
|
|
16
|
+
*/
|
|
17
|
+
|
|
10
18
|
class WeaveError extends ExtendableError {
|
|
11
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Create a new WeaveRetryableError
|
|
21
|
+
* @param {string} message Error message
|
|
22
|
+
* @param {ErrorOptions} options? Error options
|
|
23
|
+
*/
|
|
24
|
+
constructor (message, options = {}) {
|
|
12
25
|
options = defaultsDeep(
|
|
13
26
|
options,
|
|
14
27
|
{
|
|
@@ -22,14 +35,15 @@ class WeaveError extends ExtendableError {
|
|
|
22
35
|
this.code = options.code || 'WEAVE_ERROR';
|
|
23
36
|
this.data = options.data;
|
|
24
37
|
this.retryable = false;
|
|
25
|
-
|
|
26
|
-
if (options.statusCode) {
|
|
27
|
-
this.statusCode = options.statusCode;
|
|
28
|
-
}
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
class WeaveRetryableError extends WeaveError {
|
|
42
|
+
/**
|
|
43
|
+
* Create a new WeaveRetryableError
|
|
44
|
+
* @param {string} message Error message
|
|
45
|
+
* @param {ErrorOptions} options Error options
|
|
46
|
+
*/
|
|
33
47
|
constructor (message, options = { code: 'WEAVE_RETRYABLE_ERROR', retryable: true }) {
|
|
34
48
|
super(message, options);
|
|
35
49
|
this.retryable = true;
|
package/lib/index.js
CHANGED
|
@@ -20,16 +20,12 @@ exports.defaultOptions = getDefaultOptions();
|
|
|
20
20
|
* @return {Broker} Broker instance
|
|
21
21
|
*/
|
|
22
22
|
exports.createBroker = (options) => {
|
|
23
|
-
// get default options
|
|
24
23
|
const defaultOptions = getDefaultOptions();
|
|
25
24
|
|
|
26
|
-
// merge options with default options
|
|
27
25
|
options = defaultsDeep(options, defaultOptions);
|
|
28
26
|
|
|
29
|
-
// Init runtime
|
|
30
27
|
const runtime = initRuntime(options);
|
|
31
28
|
|
|
32
|
-
// Create broker instance
|
|
33
29
|
return createBrokerInstance(runtime);
|
|
34
30
|
};
|
|
35
31
|
|
|
@@ -40,12 +36,10 @@ exports.createBroker = (options) => {
|
|
|
40
36
|
*/
|
|
41
37
|
exports.Weave = exports.createBroker;
|
|
42
38
|
|
|
43
|
-
// Errors
|
|
44
39
|
exports.Errors = require('./errors');
|
|
45
40
|
|
|
46
41
|
exports.Constants = require('./constants');
|
|
47
42
|
|
|
48
|
-
// Caching
|
|
49
43
|
exports.Cache = require('./cache/adapters');
|
|
50
44
|
|
|
51
45
|
/**
|
|
@@ -56,7 +50,6 @@ exports.TransportAdapters = require('./transport/adapters');
|
|
|
56
50
|
exports.TracingAdapters = require('./tracing/collectors');
|
|
57
51
|
exports.CacheAdapters = require('./cache/adapters');
|
|
58
52
|
|
|
59
|
-
// Helper
|
|
60
53
|
exports.defineBrokerOptions = require('./helper/defineBrokerOptions');
|
|
61
54
|
exports.defineService = require('./helper/defineService');
|
|
62
55
|
exports.defineAction = require('./helper/defineAction');
|
|
@@ -4,22 +4,56 @@
|
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const { isPlainObject } = require('@weave-js/utils');
|
|
7
|
+
const { isPlainObject, isFunction, isObject, dotGet } = require('@weave-js/utils');
|
|
8
8
|
const { buildActionTags, buildEventTags } = require('./tags');
|
|
9
9
|
|
|
10
|
-
const wrapTracingLocalActionMiddleware = function (handler) {
|
|
10
|
+
const wrapTracingLocalActionMiddleware = function (handler, action) {
|
|
11
11
|
const broker = this;
|
|
12
12
|
const tracingOptions = broker.options.tracing || {};
|
|
13
|
+
const actionTracingOptions = action.tracing || {};
|
|
13
14
|
|
|
14
15
|
if (tracingOptions.enabled) {
|
|
15
16
|
return function metricsLocalMiddleware (context, serviceInjections) {
|
|
16
17
|
const tags = buildActionTags(context, tracingOptions);
|
|
17
18
|
|
|
18
|
-
if (tracingOptions) {
|
|
19
|
+
if (tracingOptions.actions.data) {
|
|
19
20
|
tags.data = context.data !== null && isPlainObject(context.data) ? Object.assign({}, context.data) : context.data;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
const
|
|
23
|
+
const globalActionTags = tracingOptions.actions.tags;
|
|
24
|
+
let actionTags;
|
|
25
|
+
// local action tags take precedence
|
|
26
|
+
if (isFunction(actionTracingOptions.tags)) {
|
|
27
|
+
actionTags = actionTracingOptions.tags;
|
|
28
|
+
} else if (!actionTracingOptions.tags && isFunction(globalActionTags)) {
|
|
29
|
+
actionTags = globalActionTags;
|
|
30
|
+
} else {
|
|
31
|
+
// By default all params are captured. This can be overridden globally and locally
|
|
32
|
+
actionTags = { ...{ data: true }, ...globalActionTags, ...actionTracingOptions.tags };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (isObject(actionTracingOptions.tags)) {
|
|
36
|
+
if (Array.isArray(actionTags.data)) {
|
|
37
|
+
tags.data = actionTags.data.reduce((acc, current) => {
|
|
38
|
+
acc[current] = dotGet(context.data, current);
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Span name
|
|
45
|
+
let spanName = `action "${context.action.name}"`;
|
|
46
|
+
|
|
47
|
+
if (actionTracingOptions.spanName) {
|
|
48
|
+
switch (typeof actionTracingOptions.spanName) {
|
|
49
|
+
case 'string':
|
|
50
|
+
spanName = actionTracingOptions.spanName;
|
|
51
|
+
break;
|
|
52
|
+
case 'function':
|
|
53
|
+
spanName = actionTracingOptions.spanName.call(context.service, context);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
23
57
|
|
|
24
58
|
const span = context.startSpan(spanName, {
|
|
25
59
|
id: context.id,
|
|
@@ -31,7 +65,7 @@ const wrapTracingLocalActionMiddleware = function (handler) {
|
|
|
31
65
|
sampled: context.tracing
|
|
32
66
|
});
|
|
33
67
|
|
|
34
|
-
context.
|
|
68
|
+
context.tracing = span.sampled;
|
|
35
69
|
|
|
36
70
|
return handler(context, serviceInjections)
|
|
37
71
|
.then(result => {
|
|
@@ -39,18 +73,17 @@ const wrapTracingLocalActionMiddleware = function (handler) {
|
|
|
39
73
|
isCachedResult: context.isCachedResult
|
|
40
74
|
};
|
|
41
75
|
|
|
42
|
-
if (tracingOptions) {
|
|
76
|
+
if (tracingOptions.actions.response) {
|
|
43
77
|
tags.response = result !== null && isPlainObject(result) ? Object.assign({}, result) : result;
|
|
44
78
|
}
|
|
45
79
|
|
|
46
80
|
span.addTags(tags);
|
|
47
|
-
|
|
81
|
+
context.finishSpan(span);
|
|
48
82
|
return result;
|
|
49
83
|
})
|
|
50
84
|
.catch(error => {
|
|
51
|
-
span
|
|
52
|
-
|
|
53
|
-
.finish();
|
|
85
|
+
span.setError(error);
|
|
86
|
+
context.finishSpan(span);
|
|
54
87
|
return Promise.reject(error);
|
|
55
88
|
});
|
|
56
89
|
};
|
|
@@ -77,17 +110,16 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
|
|
|
77
110
|
sampled: context.tracing
|
|
78
111
|
});
|
|
79
112
|
|
|
80
|
-
context.
|
|
113
|
+
context.tracing = span.sampled;
|
|
81
114
|
|
|
82
115
|
return handler(context)
|
|
83
116
|
.then(result => {
|
|
84
|
-
|
|
117
|
+
context.finishSpan(span);
|
|
85
118
|
return result;
|
|
86
119
|
})
|
|
87
120
|
.catch(error => {
|
|
88
|
-
span
|
|
89
|
-
|
|
90
|
-
.finish();
|
|
121
|
+
span.setError(error);
|
|
122
|
+
context.finishSpan(span);
|
|
91
123
|
return Promise.reject(error);
|
|
92
124
|
});
|
|
93
125
|
};
|
|
@@ -20,24 +20,23 @@ exports.initActionInvoker = (runtime) => {
|
|
|
20
20
|
|
|
21
21
|
const action = endpoint.action;
|
|
22
22
|
const nodeId = endpoint.node.id;
|
|
23
|
-
let
|
|
23
|
+
let contextToUse;
|
|
24
24
|
|
|
25
|
-
// If a context is passed, we use this
|
|
26
25
|
if (opts.context !== undefined) {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
contextToUse = opts.context;
|
|
27
|
+
contextToUse.nodeId = nodeId;
|
|
29
28
|
} else {
|
|
30
|
-
|
|
29
|
+
contextToUse = contextFactory.create(endpoint, data, opts);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
if (endpoint.isLocal) {
|
|
34
|
-
log.debug({ action:
|
|
33
|
+
log.debug({ action: contextToUse.action.name, requestId: contextToUse.requestId }, 'Call action local.');
|
|
35
34
|
} else {
|
|
36
|
-
log.debug({ action:
|
|
35
|
+
log.debug({ action: contextToUse.action.name, nodeId, requestId: contextToUse.requestId }, 'Call action on remote node.');
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
const p = action.handler(
|
|
40
|
-
p.context =
|
|
38
|
+
const p = action.handler(contextToUse, { service: contextToUse.action.service, runtime, errors });
|
|
39
|
+
p.context = contextToUse;
|
|
41
40
|
|
|
42
41
|
return p;
|
|
43
42
|
};
|
package/lib/runtime/initCache.js
CHANGED