@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.
@@ -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 (endpoint) {
76
- context.setEndpoint(endpoint);
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
 
@@ -1,7 +1,6 @@
1
1
  const { isFunction } = require('@weave-js/utils');
2
2
 
3
3
  const collectors = {
4
- // Console: require('./console'),
5
4
  Event: require('./event'),
6
5
  BaseCollector: require('./base')
7
6
  };
@@ -27,7 +27,9 @@ exports.createSpan = (tracer, name, options) => {
27
27
 
28
28
  span.start = (time) => {
29
29
  span.startTime = time || hrTime();
30
- tracer.invokeCollectorMethod('startedSpan', [span]);
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;
45
- tracer.log.debug('Span finished');
46
- tracer.invokeCollectorMethod('finishedSpan', [span]);
47
+
48
+ tracer.log.debug(`Span "${span.id}" finished`);
49
+
50
+ if (span.sampled) {
51
+ tracer.invokeCollectorMethod('finishedSpan', [span]);
52
+ }
47
53
 
48
54
  return span;
49
55
  };
@@ -81,7 +81,6 @@ const createTransportBase = () => {
81
81
  },
82
82
  serialize (packet) {
83
83
  try {
84
- // Add the sender to each outgoing message
85
84
  packet.payload.sender = this.broker.nodeId;
86
85
  return Buffer.from(JSON.stringify(packet));
87
86
  } catch (error) {
@@ -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
- // If the queue size is set, check the queue size and reject the job when the limit is reached.
241
- if (runtime.options.transport.maxQueueSize && runtime.options.transport.maxQueueSize < pending.requests.size) {
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({}).forEach(node => {
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
- // Get available endpoints
36
- const endpointList = registry.getActionEndpoints(actionName);
35
+ const availableEndpointList = registry.getActionEndpoints(actionName);
37
36
 
38
- // Reject the request if no local endpoint can be found.
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
- // From all available local endpoints - get one.
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
  };