@weave-js/core 0.14.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 +5 -4
- package/lib/broker/defaultOptions.js +1 -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 -1
- package/lib/index.js +0 -7
- package/lib/middlewares/tracing/index.js +2 -2
- 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 +8 -2
- 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 +2 -2
package/lib/broker/context.js
CHANGED
|
@@ -27,8 +27,8 @@ exports.createContext = (runtime) => {
|
|
|
27
27
|
const context = {
|
|
28
28
|
id: null,
|
|
29
29
|
nodeId: runtime.nodeId || null,
|
|
30
|
+
parentId: null,
|
|
30
31
|
callerNodeId: null,
|
|
31
|
-
parentContext: null,
|
|
32
32
|
endpoint: null,
|
|
33
33
|
data: {},
|
|
34
34
|
meta: {},
|
|
@@ -44,6 +44,7 @@ exports.createContext = (runtime) => {
|
|
|
44
44
|
},
|
|
45
45
|
duration: 0,
|
|
46
46
|
stopTime: 0,
|
|
47
|
+
isCachedResult: false,
|
|
47
48
|
setData (newParams) {
|
|
48
49
|
this.data = newParams || {};
|
|
49
50
|
},
|
|
@@ -137,21 +138,21 @@ exports.createContext = (runtime) => {
|
|
|
137
138
|
contextCopy.options = this.options;
|
|
138
139
|
contextCopy.data = this.data;
|
|
139
140
|
contextCopy.meta = this.meta;
|
|
140
|
-
contextCopy.
|
|
141
|
+
contextCopy.parentId = this.parentId;
|
|
141
142
|
contextCopy.callerNodeId = this.callerNodeId;
|
|
142
143
|
contextCopy.requestId = this.requestId;
|
|
143
144
|
contextCopy.tracing = this.tracing;
|
|
145
|
+
contextCopy.span = this.span;
|
|
144
146
|
contextCopy.level = this.level;
|
|
145
147
|
contextCopy.eventName = this.eventName;
|
|
146
148
|
contextCopy.eventType = this.eventType;
|
|
147
149
|
contextCopy.eventGroups = this.eventGroups;
|
|
150
|
+
contextCopy.isCachedResult = this.isCachedResult;
|
|
148
151
|
|
|
149
152
|
return contextCopy;
|
|
150
153
|
}
|
|
151
154
|
};
|
|
152
155
|
|
|
153
|
-
|
|
154
|
-
|
|
155
156
|
// Generate context Id
|
|
156
157
|
if (!context.id) {
|
|
157
158
|
// Use UUID factory from broker options
|
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
|
{
|
|
@@ -26,6 +39,11 @@ class WeaveError extends ExtendableError {
|
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
class WeaveRetryableError extends WeaveError {
|
|
42
|
+
/**
|
|
43
|
+
* Create a new WeaveRetryableError
|
|
44
|
+
* @param {string} message Error message
|
|
45
|
+
* @param {ErrorOptions} options Error options
|
|
46
|
+
*/
|
|
29
47
|
constructor (message, options = { code: 'WEAVE_RETRYABLE_ERROR', retryable: true }) {
|
|
30
48
|
super(message, options);
|
|
31
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');
|
|
@@ -65,7 +65,7 @@ const wrapTracingLocalActionMiddleware = function (handler, action) {
|
|
|
65
65
|
sampled: context.tracing
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
context.
|
|
68
|
+
context.tracing = span.sampled;
|
|
69
69
|
|
|
70
70
|
return handler(context, serviceInjections)
|
|
71
71
|
.then(result => {
|
|
@@ -110,7 +110,7 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
|
|
|
110
110
|
sampled: context.tracing
|
|
111
111
|
});
|
|
112
112
|
|
|
113
|
-
context.
|
|
113
|
+
context.tracing = span.sampled;
|
|
114
114
|
|
|
115
115
|
return handler(context)
|
|
116
116
|
.then(result => {
|
|
@@ -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
|
@@ -32,27 +32,28 @@ exports.initContextFactory = (runtime) => {
|
|
|
32
32
|
create (endpoint, data, opts) {
|
|
33
33
|
const context = createContext(runtime);
|
|
34
34
|
|
|
35
|
+
if (endpoint) {
|
|
36
|
+
context.setEndpoint(endpoint);
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
opts = opts || {};
|
|
36
40
|
context.setData(data);
|
|
37
41
|
// context.timeout = opts.timeout || 0
|
|
38
42
|
context.retryCount = opts.retryCount;
|
|
39
43
|
context.options = opts;
|
|
40
44
|
|
|
41
|
-
// get external request id from options
|
|
42
45
|
if (opts.requestId) {
|
|
43
46
|
context.requestId = opts.requestId;
|
|
44
47
|
} else if (opts.parentContext && opts.parentContext.requestId) {
|
|
45
48
|
context.requestId = opts.parentContext.requestId;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
// meta data
|
|
49
51
|
if (opts.parentContext && opts.parentContext.meta !== null) {
|
|
50
52
|
context.meta = Object.assign({}, opts.parentContext.meta, opts.meta);
|
|
51
53
|
} else if (opts.meta) {
|
|
52
54
|
context.meta = opts.meta;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
// Parent context
|
|
56
57
|
if (opts.parentContext != null) {
|
|
57
58
|
context.parentId = opts.parentContext.id;
|
|
58
59
|
context.level = opts.parentContext.level + 1;
|
|
@@ -60,22 +61,19 @@ exports.initContextFactory = (runtime) => {
|
|
|
60
61
|
context.span = opts.parentContext.span;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
// handle local streams
|
|
64
64
|
if (opts.stream) {
|
|
65
65
|
context.setStream(opts.stream);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
// set request ID for metrics
|
|
69
68
|
if (context.metrics || context.nodeId !== runtime.nodeId) {
|
|
70
69
|
if (!context.requestId) {
|
|
71
70
|
context.requestId = context.id;
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
if (
|
|
76
|
-
context.
|
|
74
|
+
if (opts.parentSpan) {
|
|
75
|
+
context.tracing = opts.parentSpan.sampled;
|
|
77
76
|
}
|
|
78
|
-
|
|
79
77
|
return context;
|
|
80
78
|
}
|
|
81
79
|
}
|
|
@@ -15,7 +15,6 @@ exports.initEventbus = (runtime) => {
|
|
|
15
15
|
options = {};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// Emit local events
|
|
19
18
|
if (/^\$/.test(eventName)) {
|
|
20
19
|
bus.emit(eventName, payload);
|
|
21
20
|
}
|
|
@@ -34,7 +33,6 @@ exports.initEventbus = (runtime) => {
|
|
|
34
33
|
endpoints.map(([endpoint, groupName]) => {
|
|
35
34
|
if (endpoint) {
|
|
36
35
|
if (endpoint.node.id === brokerOptions.nodeId) {
|
|
37
|
-
// Local event. Call handler
|
|
38
36
|
context.setEndpoint(endpoint);
|
|
39
37
|
promises.push(endpoint.action.handler(context));
|
|
40
38
|
} else {
|
|
@@ -51,7 +49,6 @@ exports.initEventbus = (runtime) => {
|
|
|
51
49
|
}
|
|
52
50
|
});
|
|
53
51
|
|
|
54
|
-
// Send remote events
|
|
55
52
|
if (runtime.transport) {
|
|
56
53
|
Object.values(groupedEndpoints)
|
|
57
54
|
.forEach(groupedEndpoint => {
|
|
@@ -73,7 +70,6 @@ exports.initEventbus = (runtime) => {
|
|
|
73
70
|
* @returns {Promise<any>} Promise
|
|
74
71
|
*/
|
|
75
72
|
const broadcastLocal = (eventName, payload, options) => {
|
|
76
|
-
// If the given group is no array - wrap it.
|
|
77
73
|
if (Array.isArray(options)) {
|
|
78
74
|
options = { groups: options };
|
|
79
75
|
} else if (options == null) {
|
|
@@ -84,7 +80,6 @@ exports.initEventbus = (runtime) => {
|
|
|
84
80
|
context.eventType = 'broadcastLocal';
|
|
85
81
|
context.eventName = eventName;
|
|
86
82
|
|
|
87
|
-
// Emit the event on the internal event bus
|
|
88
83
|
if (/^\$/.test(eventName)) {
|
|
89
84
|
bus.emit(eventName, payload);
|
|
90
85
|
}
|
|
@@ -109,14 +104,12 @@ exports.initEventbus = (runtime) => {
|
|
|
109
104
|
const promises = [];
|
|
110
105
|
|
|
111
106
|
if (runtime.transport) {
|
|
112
|
-
// create context
|
|
113
107
|
// todo: create an event context object
|
|
114
108
|
const context = contextFactory.create(null, payload, options);
|
|
115
109
|
context.eventType = 'broadcast';
|
|
116
110
|
context.eventName = eventName;
|
|
117
111
|
context.eventGroups = options.groups;
|
|
118
112
|
|
|
119
|
-
// Avoid to broadcast internal events.
|
|
120
113
|
if (!/^\$/.test(eventName)) {
|
|
121
114
|
const endpoints = registry.eventCollection.getAllEndpointsUniqueNodes(eventName, options.groups);
|
|
122
115
|
|
|
@@ -20,12 +20,10 @@ exports.initLogger = (runtime) => {
|
|
|
20
20
|
...additional
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
// custom logger generator function.
|
|
24
23
|
if (typeof runtime.options.logger === 'function') {
|
|
25
24
|
return runtime.options.logger(bindings, runtime.options.logger.level);
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
// merge log options
|
|
29
27
|
const loggerOptions = defaultsDeep({
|
|
30
28
|
base: {
|
|
31
29
|
...bindings
|
|
@@ -37,7 +35,6 @@ exports.initLogger = (runtime) => {
|
|
|
37
35
|
|
|
38
36
|
const createLogger = (moduleName, service) => loggerFactory(runtime, moduleName, service);
|
|
39
37
|
|
|
40
|
-
// create weave default logger
|
|
41
38
|
const log = createLogger('WEAVE');
|
|
42
39
|
|
|
43
40
|
Object.assign(runtime, {
|
|
@@ -30,7 +30,6 @@ exports.initMetrics = (runtime) => {
|
|
|
30
30
|
storage,
|
|
31
31
|
log,
|
|
32
32
|
init () {
|
|
33
|
-
// Load adapters
|
|
34
33
|
if (metricOptions.adapters) {
|
|
35
34
|
if (!Array.isArray(metricOptions.adapters)) {
|
|
36
35
|
runtime.handleError(new WeaveError('Metic adapter needs to be an Array.'));
|
|
@@ -128,11 +127,6 @@ exports.initMetrics = (runtime) => {
|
|
|
128
127
|
}
|
|
129
128
|
return duration;
|
|
130
129
|
};
|
|
131
|
-
// const item = this.storage.get(name)
|
|
132
|
-
// if (item) {
|
|
133
|
-
|
|
134
|
-
// }
|
|
135
|
-
// item.observe(labels, value, timestamp)
|
|
136
130
|
},
|
|
137
131
|
getMetric (name) {
|
|
138
132
|
const item = this.storage.get(name);
|
|
@@ -8,45 +8,13 @@ exports.initServiceManager = (runtime) => {
|
|
|
8
8
|
const serviceList = [];
|
|
9
9
|
|
|
10
10
|
const serviceChanged = (isLocalService = false) => {
|
|
11
|
-
// Send local notification.
|
|
12
11
|
eventBus.broadcastLocal('$services.changed', { isLocalService });
|
|
13
12
|
|
|
14
|
-
// If the service is a local service - send current node information to other nodes
|
|
15
13
|
if (state.isStarted && isLocalService && transport) {
|
|
16
14
|
transport.sendNodeInfo();
|
|
17
15
|
}
|
|
18
16
|
};
|
|
19
17
|
|
|
20
|
-
// const destroyService = (service) => Promise.resolve()
|
|
21
|
-
// .then(() => service.stop())
|
|
22
|
-
// .then(() => log.info(`Service "${service.name}" was stopped.`))
|
|
23
|
-
// .then(() => {
|
|
24
|
-
// registry.deregisterService(service.name, service.version)
|
|
25
|
-
// log.info(`Service "${service.name}" was deregistered.`)
|
|
26
|
-
// // Remove service from service store.
|
|
27
|
-
// serviceList.splice(serviceList.indexOf(service), 1)
|
|
28
|
-
// // Fire services changed event
|
|
29
|
-
// serviceChanged(true)
|
|
30
|
-
// return Promise.resolve()
|
|
31
|
-
// })
|
|
32
|
-
// .catch(error => log.error(error, `Unable to stop service "${service.name}"`))
|
|
33
|
-
|
|
34
|
-
// `onServiceFileChanged` only triggered by the file watcher
|
|
35
|
-
// const onServiceFileChanged = async (service) => {
|
|
36
|
-
// const filename = service.filename;
|
|
37
|
-
|
|
38
|
-
// // Clear the require cache
|
|
39
|
-
// Object.keys(require.cache).forEach(key => {
|
|
40
|
-
// if (key === filename) {
|
|
41
|
-
// delete require.cache[key];
|
|
42
|
-
// }
|
|
43
|
-
// });
|
|
44
|
-
|
|
45
|
-
// // Service has changed - 1. destroy the service, then reload it
|
|
46
|
-
// await destroyService(service);
|
|
47
|
-
// await runtime.broker.loadService(filename);
|
|
48
|
-
// };
|
|
49
|
-
|
|
50
18
|
Object.defineProperty(runtime, 'services', {
|
|
51
19
|
value: {
|
|
52
20
|
serviceList,
|
|
@@ -55,7 +23,6 @@ exports.initServiceManager = (runtime) => {
|
|
|
55
23
|
try {
|
|
56
24
|
const newService = createServiceFromSchema(runtime, schema);
|
|
57
25
|
|
|
58
|
-
// if the broker is already started, we need to start the service.
|
|
59
26
|
if (runtime.state.isStarted) {
|
|
60
27
|
newService.start().catch(error => log.error(`Unable to start service ${newService.name}: ${error}`));
|
|
61
28
|
}
|
|
@@ -114,11 +81,8 @@ exports.initServiceManager = (runtime) => {
|
|
|
114
81
|
*/
|
|
115
82
|
async destroyService (service) {
|
|
116
83
|
try {
|
|
117
|
-
// Stop the service
|
|
118
84
|
await service.stop();
|
|
119
|
-
log.info(`Service "${service.name}" was stopped.`);
|
|
120
85
|
|
|
121
|
-
// Deregister the service and remove it from the service list
|
|
122
86
|
registry.deregisterService(service.name, service.version);
|
|
123
87
|
serviceList.splice(serviceList.indexOf(service), 1);
|
|
124
88
|
log.info(`Service "${service.name}" was deregistered.`);
|
|
@@ -127,24 +91,6 @@ exports.initServiceManager = (runtime) => {
|
|
|
127
91
|
log.error(error, `Unable to stop service "${service.name}"`);
|
|
128
92
|
}
|
|
129
93
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Watch a Service object for changes.
|
|
132
|
-
* @param {Service} service Service object
|
|
133
|
-
* @return {void}
|
|
134
|
-
*/
|
|
135
|
-
// watchService: (service) => {
|
|
136
|
-
// if (service.filename && onServiceFileChanged) {
|
|
137
|
-
// // Create debounced service changed reference
|
|
138
|
-
// const debouncedOnServiceChange = debounce(onServiceFileChanged, 500);
|
|
139
|
-
|
|
140
|
-
// // Watch file changes
|
|
141
|
-
// const watcher = fs.watch(service.filename, (eventType, filename) => {
|
|
142
|
-
// log.info(`The Service ${service.name} has been changed. (${eventType}, ${filename})`);
|
|
143
|
-
// watcher.close();
|
|
144
|
-
// debouncedOnServiceChange(service);
|
|
145
|
-
// });
|
|
146
|
-
// }
|
|
147
|
-
// }
|
|
148
94
|
}
|
|
149
95
|
});
|
|
150
96
|
};
|
|
@@ -4,6 +4,7 @@ const { createSpan } = require('../tracing/span');
|
|
|
4
4
|
exports.initTracer = (runtime) => {
|
|
5
5
|
const options = runtime.options.tracing;
|
|
6
6
|
const log = runtime.createLogger('TRACER');
|
|
7
|
+
|
|
7
8
|
let collectors = [];
|
|
8
9
|
let samplingCounter = 0;
|
|
9
10
|
|
|
@@ -18,7 +19,6 @@ exports.initTracer = (runtime) => {
|
|
|
18
19
|
}
|
|
19
20
|
},
|
|
20
21
|
shouldSample (span) {
|
|
21
|
-
// check span priority
|
|
22
22
|
if (options.samplingRate === 0) {
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
@@ -38,6 +38,12 @@ exports.initTracer = (runtime) => {
|
|
|
38
38
|
collectors.map(collector => collector[method].apply(collector, args));
|
|
39
39
|
},
|
|
40
40
|
startSpan (name, options) {
|
|
41
|
+
const parentOptions = {};
|
|
42
|
+
if (options.parentSpan) {
|
|
43
|
+
parentOptions.traceId = options.parentSpan.traceId;
|
|
44
|
+
parentOptions.parentId = options.parentSpan.id;
|
|
45
|
+
parentOptions.sampled = options.parentSpan.sampled;
|
|
46
|
+
}
|
|
41
47
|
const span = createSpan(this, name, Object.assign({
|
|
42
48
|
type: 'custom'
|
|
43
49
|
}, options));
|
|
@@ -49,7 +55,6 @@ exports.initTracer = (runtime) => {
|
|
|
49
55
|
}
|
|
50
56
|
});
|
|
51
57
|
|
|
52
|
-
// Init collectors
|
|
53
58
|
if (options.enabled) {
|
|
54
59
|
log.info('Tracer initialized.');
|
|
55
60
|
|
package/lib/tracing/span.js
CHANGED
|
@@ -27,7 +27,9 @@ exports.createSpan = (tracer, name, options) => {
|
|
|
27
27
|
|
|
28
28
|
span.start = (time) => {
|
|
29
29
|
span.startTime = time || hrTime();
|
|
30
|
-
|
|
30
|
+
if (span.sampled) {
|
|
31
|
+
tracer.invokeCollectorMethod('startedSpan', [span]);
|
|
32
|
+
}
|
|
31
33
|
return span;
|
|
32
34
|
};
|
|
33
35
|
|
|
@@ -42,8 +44,12 @@ exports.createSpan = (tracer, name, options) => {
|
|
|
42
44
|
span.finish = (time) => {
|
|
43
45
|
span.finishTime = time || hrTime();
|
|
44
46
|
span.duration = span.finishTime - span.startTime;
|
|
47
|
+
|
|
45
48
|
tracer.log.debug(`Span "${span.id}" finished`);
|
|
46
|
-
|
|
49
|
+
|
|
50
|
+
if (span.sampled) {
|
|
51
|
+
tracer.invokeCollectorMethod('finishedSpan', [span]);
|
|
52
|
+
}
|
|
47
53
|
|
|
48
54
|
return span;
|
|
49
55
|
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
const MessageTypes = require('./messageTypes');
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Create a message object
|
|
5
|
+
*
|
|
6
|
+
* @param {string} type - The message type
|
|
7
|
+
* @param {string} targetNodeId - The target node id
|
|
8
|
+
* @param {object} payload - The message payload
|
|
9
|
+
* @returns {object} - The message object
|
|
10
|
+
*/
|
|
3
11
|
const createMessage = (type, targetNodeId, payload) => {
|
|
4
12
|
return {
|
|
5
13
|
type: type || MessageTypes.MESSAGE_UNKNOWN,
|
|
@@ -70,7 +70,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
70
70
|
|
|
71
71
|
const doConnect = (isTryReconnect) => {
|
|
72
72
|
const errorHandler = (error) => {
|
|
73
|
-
// Skip reconnect, if the adapter is disconnecting or an reconnect is in progress.
|
|
74
73
|
if (transport.isDisconnecting || transport.reconnectInProgress) {
|
|
75
74
|
return;
|
|
76
75
|
}
|
|
@@ -132,7 +131,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
132
131
|
return Promise.resolve();
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
// Collect own node info and send it to remote nodes
|
|
136
134
|
const info = runtime.registry.getLocalNodeInfo();
|
|
137
135
|
const message = createMessage(MessageTypes.MESSAGE_INFO, sender, {
|
|
138
136
|
...info,
|
|
@@ -194,6 +192,8 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
194
192
|
metrics: context.metrics,
|
|
195
193
|
requestId: context.requestId,
|
|
196
194
|
parentId: context.parentId,
|
|
195
|
+
callerNodeId: context.callerNodeId,
|
|
196
|
+
tracing: context.tracing,
|
|
197
197
|
isBroadcast
|
|
198
198
|
};
|
|
199
199
|
|
|
@@ -237,8 +237,10 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
237
237
|
};
|
|
238
238
|
|
|
239
239
|
transport.sendRequest = (context) => {
|
|
240
|
-
|
|
241
|
-
|
|
240
|
+
const maxQueueSizeExceeded = runtime.options.transport.maxQueueSize &&
|
|
241
|
+
runtime.options.transport.maxQueueSize < pending.requests.size;
|
|
242
|
+
|
|
243
|
+
if (maxQueueSizeExceeded) {
|
|
242
244
|
return Promise.reject(new WeaveQueueSizeExceededError({
|
|
243
245
|
action: context.action.name,
|
|
244
246
|
limit: runtime.options.transport.maxQueueSize,
|
|
@@ -273,6 +275,8 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
273
275
|
metrics: context.metrics,
|
|
274
276
|
requestId: context.requestId,
|
|
275
277
|
parentId: context.parentId,
|
|
278
|
+
callerNodeId: context.callerNodeId,
|
|
279
|
+
tracing: context.tracing,
|
|
276
280
|
isStream
|
|
277
281
|
};
|
|
278
282
|
|
|
@@ -383,10 +387,8 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
383
387
|
* @returns {Promise<void>} - Promise
|
|
384
388
|
*/
|
|
385
389
|
transport.sendResponse = (target, contextId, data, meta, error) => {
|
|
386
|
-
// Check if data is a stream
|
|
387
390
|
const isStream = utils.isStream(data);
|
|
388
391
|
|
|
389
|
-
// Build response payload
|
|
390
392
|
const payload = {
|
|
391
393
|
id: contextId,
|
|
392
394
|
meta,
|
|
@@ -394,7 +396,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
394
396
|
success: error == null
|
|
395
397
|
};
|
|
396
398
|
|
|
397
|
-
// If an error is occurs, we attach the an error object to the payload.
|
|
398
399
|
if (error) {
|
|
399
400
|
payload.error = getErrorPayload(error);
|
|
400
401
|
}
|
|
@@ -422,7 +423,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
422
423
|
stream.pause();
|
|
423
424
|
const chunks = [];
|
|
424
425
|
|
|
425
|
-
// chunk is larger than maxBufferSize
|
|
426
426
|
if (data instanceof Buffer && runtime.options.transport.maxChunkSize > 0 && data.length > runtime.options.transport.maxChunkSize) {
|
|
427
427
|
const length = data.length;
|
|
428
428
|
let i = 0;
|
|
@@ -433,7 +433,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
433
433
|
chunks.push(data);
|
|
434
434
|
}
|
|
435
435
|
|
|
436
|
-
// Send chunks from chunk buffer
|
|
437
436
|
for (const chunk of chunks) {
|
|
438
437
|
const payloadCopy = Object.assign({}, payload);
|
|
439
438
|
payloadCopy.sequence = ++payload.sequence;
|
|
@@ -445,7 +444,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
445
444
|
transport.send(message);
|
|
446
445
|
}
|
|
447
446
|
|
|
448
|
-
// resume stream
|
|
449
447
|
stream.resume();
|
|
450
448
|
return;
|
|
451
449
|
});
|
|
@@ -541,7 +539,6 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
541
539
|
|
|
542
540
|
let messageHandler = createMessageHandler(runtime, transport);
|
|
543
541
|
|
|
544
|
-
// Wrap message handler for middlewares
|
|
545
542
|
messageHandler = middlewareHandler.wrapMethod('transportMessageHandler', messageHandler, transport);
|
|
546
543
|
|
|
547
544
|
adapter.init(runtime, transport)
|
|
@@ -635,10 +632,11 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
635
632
|
});
|
|
636
633
|
}
|
|
637
634
|
|
|
638
|
-
// Removes the node after a given time from the registry.
|
|
639
635
|
function checkOfflineNodes () {
|
|
640
636
|
const now = Date.now();
|
|
641
|
-
runtime.registry.nodeCollection.list({})
|
|
637
|
+
const nodeList = runtime.registry.nodeCollection.list({});
|
|
638
|
+
|
|
639
|
+
nodeList.forEach(node => {
|
|
642
640
|
if (node.isLocal || node.isAvailable) {
|
|
643
641
|
return;
|
|
644
642
|
}
|
|
@@ -32,25 +32,20 @@ module.exports = (runtime, transport) => {
|
|
|
32
32
|
const localRequestProxy = (context) => {
|
|
33
33
|
const actionName = context.action.name;
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
const endpointList = registry.getActionEndpoints(actionName);
|
|
35
|
+
const availableEndpointList = registry.getActionEndpoints(actionName);
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
if (endpointList == null || !endpointList.hasLocal()) {
|
|
37
|
+
if (availableEndpointList == null || !availableEndpointList.hasLocal()) {
|
|
40
38
|
transport.log.warn(`Service ${actionName} not found localy.`);
|
|
41
39
|
return Promise.reject('Service not found');
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
const endpoint = endpointList.getNextLocalEndpoint();
|
|
42
|
+
const endpoint = availableEndpointList.getNextLocalEndpoint();
|
|
46
43
|
|
|
47
|
-
// if there is no endpoint, reject
|
|
48
44
|
if (!endpoint) {
|
|
49
45
|
transport.log.warn(`Service ${actionName} is not available localy.`);
|
|
50
46
|
return Promise.reject('Service not found');
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
// Call the local action handler with context
|
|
54
49
|
const promise = endpoint.action.handler(context);
|
|
55
50
|
promise.context = context;
|
|
56
51
|
|
|
@@ -58,7 +53,6 @@ module.exports = (runtime, transport) => {
|
|
|
58
53
|
};
|
|
59
54
|
|
|
60
55
|
const handleIncomingRequestStream = (payload) => {
|
|
61
|
-
// check for open stream.
|
|
62
56
|
let stream = transport.pending.requestStreams.get(payload.id);
|
|
63
57
|
let isNew = false;
|
|
64
58
|
|
|
@@ -75,7 +69,6 @@ module.exports = (runtime, transport) => {
|
|
|
75
69
|
}
|
|
76
70
|
);
|
|
77
71
|
|
|
78
|
-
// handle backpressure
|
|
79
72
|
if (runtime.options.transport.streams.handleBackpressure) {
|
|
80
73
|
stream.on('backpressure', async ({ sender, requestId }) => {
|
|
81
74
|
const message = createMessage(MessageTypes.MESSAGE_REQUEST_STREAM_BACKPRESSURE, sender, { id: requestId });
|
|
@@ -107,7 +100,6 @@ module.exports = (runtime, transport) => {
|
|
|
107
100
|
|
|
108
101
|
// Todo: Handle errors
|
|
109
102
|
|
|
110
|
-
// end of stream
|
|
111
103
|
stream.end();
|
|
112
104
|
transport.pending.requestStreams.delete(payload.id);
|
|
113
105
|
return null;
|
|
@@ -147,7 +139,6 @@ module.exports = (runtime, transport) => {
|
|
|
147
139
|
}
|
|
148
140
|
);
|
|
149
141
|
|
|
150
|
-
// handle backpressure
|
|
151
142
|
if (runtime.options.transport.streams.handleBackpressure) {
|
|
152
143
|
stream.on('backpressure', async ({ sender, requestId }) => {
|
|
153
144
|
const message = createMessage(MessageTypes.MESSAGE_RESPONSE_STREAM_BACKPRESSURE, sender, { id: requestId });
|
|
@@ -182,7 +173,6 @@ module.exports = (runtime, transport) => {
|
|
|
182
173
|
|
|
183
174
|
// Todo: Handle errors
|
|
184
175
|
|
|
185
|
-
// end of stream
|
|
186
176
|
stream.end();
|
|
187
177
|
transport.pending.responseStreams.delete(payload.id);
|
|
188
178
|
return null;
|
|
@@ -229,9 +219,7 @@ module.exports = (runtime, transport) => {
|
|
|
229
219
|
try {
|
|
230
220
|
let stream;
|
|
231
221
|
|
|
232
|
-
// Handle incomming stream
|
|
233
222
|
if (payload.isStream !== undefined) {
|
|
234
|
-
// check for open stream.
|
|
235
223
|
stream = handleIncomingRequestStream(payload);
|
|
236
224
|
if (!stream) {
|
|
237
225
|
return Promise.resolve();
|
|
@@ -250,9 +238,9 @@ module.exports = (runtime, transport) => {
|
|
|
250
238
|
context.metrics = payload.metrics;
|
|
251
239
|
context.level = payload.level;
|
|
252
240
|
context.callerNodeId = payload.sender;
|
|
241
|
+
context.tracing = payload.tracing;
|
|
253
242
|
context.options.timeout = getRequestTimeout(payload);
|
|
254
243
|
|
|
255
|
-
// If payload is a stream, attach stream to context
|
|
256
244
|
if (payload.isStream) {
|
|
257
245
|
context.stream = stream;
|
|
258
246
|
}
|
|
@@ -278,10 +266,8 @@ module.exports = (runtime, transport) => {
|
|
|
278
266
|
return Promise.resolve();
|
|
279
267
|
}
|
|
280
268
|
|
|
281
|
-
// Merge meta data from response
|
|
282
269
|
Object.assign(request.context.meta, payload.meta);
|
|
283
270
|
|
|
284
|
-
// Handle streams
|
|
285
271
|
if (payload.isStream != null) {
|
|
286
272
|
if (handleIncomingResponseStream(payload, request)) {
|
|
287
273
|
return;
|
|
@@ -290,7 +276,6 @@ module.exports = (runtime, transport) => {
|
|
|
290
276
|
|
|
291
277
|
transport.pending.requests.delete(payload.id);
|
|
292
278
|
|
|
293
|
-
// Response is an error
|
|
294
279
|
if (!payload.success) {
|
|
295
280
|
const error = restoreError(payload.error);
|
|
296
281
|
|
|
@@ -357,12 +342,12 @@ module.exports = (runtime, transport) => {
|
|
|
357
342
|
context.metrics = payload.metrics;
|
|
358
343
|
context.level = payload.level;
|
|
359
344
|
context.callerNodeId = payload.sender;
|
|
345
|
+
context.tracing = !!payload.tracing;
|
|
360
346
|
|
|
361
347
|
if (payload.timeout) {
|
|
362
348
|
context.options.timeout = payload.timeout;
|
|
363
349
|
}
|
|
364
350
|
|
|
365
|
-
// add event infos
|
|
366
351
|
context.eventName = payload.eventName;
|
|
367
352
|
context.eventType = payload.isBroadcast ? 'broadcast' : 'emit';
|
|
368
353
|
|
|
@@ -387,17 +372,14 @@ module.exports = (runtime, transport) => {
|
|
|
387
372
|
transport.log.verbose(`Heartbeat from ${payload.sender}`);
|
|
388
373
|
const node = registry.nodeCollection.get(payload.sender);
|
|
389
374
|
|
|
390
|
-
// if node is unknown then request a node info message.
|
|
391
375
|
if (node) {
|
|
392
376
|
if (!node.isAvailable) {
|
|
393
377
|
transport.log.debug('Known node. Propably reconnected.');
|
|
394
|
-
// unknown node. request info message.
|
|
395
378
|
transport.discoverNode(payload.sender);
|
|
396
379
|
} else {
|
|
397
380
|
node.heartbeat(payload);
|
|
398
381
|
}
|
|
399
382
|
} else {
|
|
400
|
-
// unknown node. request info message.
|
|
401
383
|
transport.discoverNode(payload.sender);
|
|
402
384
|
}
|
|
403
385
|
};
|
|
@@ -500,10 +482,7 @@ module.exports = (runtime, transport) => {
|
|
|
500
482
|
return true;
|
|
501
483
|
} catch (error) {
|
|
502
484
|
transport.log.error(error, type, data);
|
|
503
|
-
|
|
504
|
-
runtime.eventBus.broadcastLocal('$transport.error', {
|
|
505
|
-
error
|
|
506
|
-
});
|
|
485
|
+
runtime.eventBus.broadcastLocal('$transport.error', { error });
|
|
507
486
|
}
|
|
508
487
|
return false;
|
|
509
488
|
};
|
package/lib/types.js
CHANGED
|
@@ -6,8 +6,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
6
6
|
* @typedef {import('stream').Writable} WritableStream
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
// Broker
|
|
10
|
-
|
|
11
9
|
/**
|
|
12
10
|
* @typedef {object} ActionOptions - Action options
|
|
13
11
|
* @property {Context} [context] - Assign a existing context instead of creating a new one.
|
|
@@ -86,7 +84,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
86
84
|
* @property {ServiceManager} [services] - Service manager
|
|
87
85
|
* @property {ContextFactory} [contextFactory] - contextFactory
|
|
88
86
|
* @property {Logger} log - Logger instance
|
|
89
|
-
* @property {function(string, any):Logger} [createLogger] - Create a new logger
|
|
87
|
+
* @property {function(string, any):Logger} [createLogger] - Create a new logger instance.
|
|
90
88
|
* @property {Cache} [cache] - Cache
|
|
91
89
|
* @property {string} [getUUID] - Create a new from the UUID factory.
|
|
92
90
|
* @property {Registry} registry - Service registry reference
|
|
@@ -169,6 +167,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
169
167
|
* @property {Boolean} enabled - Enable tracing middleware. (default = false)
|
|
170
168
|
* @property {Number} samplingRate - Rate of traced actions. (default = 1.0)
|
|
171
169
|
* @property {Array<String|Object>} collectors - Array of tracing collectors.
|
|
170
|
+
* @property {Array<String>} defaultTags - Default tags for spans.
|
|
172
171
|
* @property {TracingErrorOptions} [errors] - Settings for tracing errors.
|
|
173
172
|
*/
|
|
174
173
|
|
|
@@ -323,6 +322,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
323
322
|
* @property {number} [retryCount] retryCount
|
|
324
323
|
* @property {Object} tracing tracing
|
|
325
324
|
* @property {Object} span span
|
|
325
|
+
* @property {boolean} [isCachedResult] eventType
|
|
326
326
|
* @property {Service} service service
|
|
327
327
|
* @property {ServiceAction} [action] action
|
|
328
328
|
* @property {number} [startHighResolutionTime] - High resolution start timestamp.
|
|
@@ -361,8 +361,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
361
361
|
* @property {function():Promise<any>} stop stop
|
|
362
362
|
*/
|
|
363
363
|
|
|
364
|
-
// Transport
|
|
365
|
-
|
|
366
364
|
/**
|
|
367
365
|
* Transport interface
|
|
368
366
|
* @export
|
|
@@ -449,8 +447,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
449
447
|
* @property {void} close close
|
|
450
448
|
*/
|
|
451
449
|
|
|
452
|
-
// Registry
|
|
453
|
-
|
|
454
450
|
/**
|
|
455
451
|
* Registry init function
|
|
456
452
|
* @typedef {function} RegistryInitFunctionDef
|
|
@@ -498,7 +494,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
498
494
|
|
|
499
495
|
/**
|
|
500
496
|
* Endpoint collection
|
|
501
|
-
*
|
|
502
497
|
* @typedef EndpointCollection
|
|
503
498
|
* @property {string} name name
|
|
504
499
|
* @property {string} groupName groupName
|
|
@@ -705,7 +700,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
705
700
|
* @property {function():Promise<any>} stop stop
|
|
706
701
|
*/
|
|
707
702
|
|
|
708
|
-
// Health handler
|
|
709
703
|
/**
|
|
710
704
|
* Health handler
|
|
711
705
|
* @typedef HealthHandler
|
|
@@ -719,8 +713,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
719
713
|
* @property {any} getNodeHealthInfo getNodeHealthInfo
|
|
720
714
|
*/
|
|
721
715
|
|
|
722
|
-
// Metrics
|
|
723
|
-
|
|
724
716
|
/**
|
|
725
717
|
* Metric registry
|
|
726
718
|
* @typedef MetricRegistry
|
|
@@ -737,8 +729,6 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
737
729
|
* @property {function():Promise<any>} stop list
|
|
738
730
|
*/
|
|
739
731
|
|
|
740
|
-
// Midlewares
|
|
741
|
-
|
|
742
732
|
/**
|
|
743
733
|
* Middleware handler
|
|
744
734
|
* @export
|
|
@@ -779,15 +769,11 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2');
|
|
|
779
769
|
* @property {function(Broker):void} [transportMessageHandler] stopped
|
|
780
770
|
*/
|
|
781
771
|
|
|
782
|
-
// Validator
|
|
783
|
-
|
|
784
772
|
/**
|
|
785
773
|
* Validator
|
|
786
774
|
* @typedef {Object} Validator
|
|
787
775
|
*/
|
|
788
776
|
|
|
789
|
-
// Tracer
|
|
790
|
-
|
|
791
777
|
/**
|
|
792
778
|
* Tracer instance
|
|
793
779
|
* @typedef Tracer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weave-js/core",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "The core package of weave",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Weave",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"lib": "lib",
|
|
50
50
|
"test": "test"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "84fd5e4af3af96e8c004bcfba40bb3cb35f23fa7"
|
|
53
53
|
}
|