@weave-js/core 0.10.0 → 0.11.0

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.
Files changed (87) hide show
  1. package/lib/ExtendableError.js +33 -0
  2. package/lib/broker/context.js +12 -0
  3. package/lib/broker/{default-options.js → defaultOptions.js} +22 -4
  4. package/lib/broker/index.js +218 -192
  5. package/lib/{build-runtime.js → buildRuntime.js} +16 -16
  6. package/lib/cache/base.js +33 -28
  7. package/lib/cache/inMemory.js +140 -0
  8. package/lib/cache/index.js +1 -1
  9. package/lib/cache/lock.js +21 -4
  10. package/lib/constants.js +7 -4
  11. package/lib/{error-handler.js → errorHandler.js} +0 -0
  12. package/lib/errors.js +16 -9
  13. package/lib/helper/{define-action.js → defineAction.js} +3 -1
  14. package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +2 -0
  15. package/lib/helper/{define-service.js → defineService.js} +4 -1
  16. package/lib/index.js +13 -9
  17. package/lib/logger/format/asHumanReadable.js +4 -3
  18. package/lib/logger/index.js +4 -1
  19. package/lib/logger/levels.js +2 -1
  20. package/lib/logger/tools.js +4 -0
  21. package/lib/logger/utils/format.js +18 -4
  22. package/lib/metrics/constants.js +1 -1
  23. package/lib/metrics/types/gauge.js +1 -1
  24. package/lib/middlewares/action-hooks/index.js +59 -11
  25. package/lib/middlewares/bulkhead/index.js +2 -1
  26. package/lib/middlewares/cache/index.js +80 -0
  27. package/lib/middlewares/circuit-breaker/index.js +38 -13
  28. package/lib/middlewares/index.js +1 -0
  29. package/lib/middlewares/metrics/index.js +1 -1
  30. package/lib/middlewares/timeout/index.js +2 -2
  31. package/lib/middlewares/tracing/index.js +24 -11
  32. package/lib/middlewares/tracing/tags.js +43 -0
  33. package/lib/middlewares/validator/index.js +1 -1
  34. package/lib/registry/{action-endpoint.js → actionEndpoint.js} +0 -0
  35. package/lib/registry/collections/{action-collection.js → actionCollection.js} +1 -1
  36. package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +2 -3
  37. package/lib/registry/collections/{event-collection.js → eventCollection.js} +4 -8
  38. package/lib/registry/collections/{node-collection.js → nodeCollection.js} +0 -0
  39. package/lib/registry/collections/{service-collection.js → serviceCollection.js} +1 -1
  40. package/lib/registry/{event-endpoint.js → eventEndpoint.js} +0 -0
  41. package/lib/registry/registry.js +9 -22
  42. package/lib/registry/service/service.js +2 -2
  43. package/lib/registry/{service-item.js → serviceItem.js} +0 -0
  44. package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +1 -1
  45. package/lib/runtime/{init-cache.js → initCache.js} +0 -0
  46. package/lib/runtime/{init-context-factory.js → initContextFactory.js} +0 -0
  47. package/lib/runtime/{init-eventbus.js → initEventbus.js} +8 -7
  48. package/lib/runtime/{init-logger.js → initLogger.js} +0 -0
  49. package/lib/runtime/{init-metrics.js → initMetrics.js} +11 -10
  50. package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +0 -0
  51. package/lib/runtime/{init-registry.js → initRegistry.js} +0 -0
  52. package/lib/runtime/{init-service-manager.js → initServiceManager.js} +0 -0
  53. package/lib/runtime/{init-tracing.js → initTracing.js} +2 -1
  54. package/lib/runtime/{init-transport.js → initTransport.js} +0 -0
  55. package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +0 -0
  56. package/lib/runtime/{init-validator.js → initValidator.js} +0 -0
  57. package/lib/tracing/collectors/base.js +11 -19
  58. package/lib/tracing/collectors/event.js +2 -2
  59. package/lib/tracing/collectors/index.js +2 -2
  60. package/lib/tracing/span.js +8 -6
  61. package/lib/transport/InboundTransformStream.js +75 -0
  62. package/lib/transport/adapters/{adapter-base.js → adapteBase.js} +15 -0
  63. package/lib/transport/adapters/adapters.js +1 -1
  64. package/lib/transport/adapters/dummy/index.js +2 -2
  65. package/lib/transport/adapters/tcp/discovery/index.js +45 -31
  66. package/lib/transport/adapters/tcp/index.js +20 -13
  67. package/lib/transport/adapters/tcp/tcpReader.js +1 -0
  68. package/lib/transport/adapters/tcp/tcpWriteStream.js +1 -1
  69. package/lib/transport/adapters/tcp/tcpWriter.js +2 -2
  70. package/lib/transport/createMessage.js +11 -0
  71. package/lib/transport/createTransport.js +214 -171
  72. package/lib/transport/errorPayloadFactory.js +18 -0
  73. package/lib/transport/{message-handlers.js → messageHandlers.js} +91 -22
  74. package/lib/transport/messageTypes.js +23 -0
  75. package/lib/types.js +49 -49
  76. package/lib/utils/options.js +4 -2
  77. package/lib/utils/{restore-error.js → restoreError.js} +1 -1
  78. package/package.json +6 -12
  79. package/CHANGELOG.md +0 -1334
  80. package/lib/cache/memory.js +0 -121
  81. package/lib/middlewares/tracing/buildTags.js +0 -17
  82. package/lib/new-errors.js +0 -25
  83. package/lib/tracing/collectors/console.js +0 -34
  84. package/lib/tracing/index.js +0 -3
  85. package/lib/tracing/tracer.js +0 -64
  86. package/lib/transport/message-types.js +0 -59
  87. package/lib/transport/message.js +0 -16
@@ -9,7 +9,7 @@ const { WeaveError } = require('../../errors')
9
9
  const { parseAction } = require('./parseAction')
10
10
  const { parseEvent } = require('./parseEvent')
11
11
  const { reduceMixins } = require('./reduceMixins')
12
- const { createEventEndpoint } = require('../event-endpoint')
12
+ const { createEventEndpoint } = require('../eventEndpoint')
13
13
  /**
14
14
  * Service factory
15
15
  * @param {Runtime} runtime Broker instance
@@ -133,7 +133,7 @@ exports.createServiceFromSchema = (runtime, schema) => {
133
133
  context = runtime.contextFactory.create(endpoint, data, options || {})
134
134
  }
135
135
 
136
- return wrappedAction(context, { service, runtime, errors: {} })
136
+ return wrappedAction(context, { service, runtime, errors: {}})
137
137
  }
138
138
  })
139
139
  }
File without changes
@@ -36,7 +36,7 @@ exports.initActionInvoker = (runtime) => {
36
36
  log.debug({ action: context.action.name, nodeId, requestId: context.requestId }, 'Call action on remote node.')
37
37
  }
38
38
 
39
- const p = action.handler(context, { service: endpoint.service, runtime, errors })
39
+ const p = action.handler(context, { service: context.action.service, runtime, errors })
40
40
  p.context = context
41
41
 
42
42
  return p
File without changes
@@ -15,7 +15,11 @@ exports.initEventbus = (runtime) => {
15
15
  options = {}
16
16
  }
17
17
 
18
- const promises = []
18
+ // Emit local events
19
+ if (/^\$/.test(eventName)) {
20
+ bus.emit(eventName, payload)
21
+ }
22
+
19
23
  // todo: create an event context object
20
24
  const context = contextFactory.create(null, payload, options)
21
25
 
@@ -23,18 +27,15 @@ exports.initEventbus = (runtime) => {
23
27
  context.eventName = eventName
24
28
  context.eventGroups = options.groups
25
29
 
26
- // Emit system events
27
- if (/^\$/.test(eventName)) {
28
- bus.emit(eventName, payload)
29
- }
30
-
31
30
  const endpoints = registry.eventCollection.getBalancedEndpoints(eventName, options.groups)
32
31
  const groupedEndpoints = {}
32
+ const promises = []
33
33
 
34
34
  endpoints.map(([endpoint, groupName]) => {
35
35
  if (endpoint) {
36
36
  if (endpoint.node.id === brokerOptions.nodeId) {
37
37
  // Local event. Call handler
38
+ context.setEndpoint(endpoint)
38
39
  promises.push(endpoint.action.handler(context))
39
40
  } else {
40
41
  const e = groupedEndpoints[endpoint.node.id]
@@ -50,7 +51,7 @@ exports.initEventbus = (runtime) => {
50
51
  }
51
52
  })
52
53
 
53
- // send remote events
54
+ // Send remote events
54
55
  if (runtime.transport) {
55
56
  Object.values(groupedEndpoints)
56
57
  .forEach(groupedEndpoint => {
File without changes
@@ -1,4 +1,5 @@
1
1
  const { isPlainObject, isFunction } = require('@weave-js/utils')
2
+ const { WeaveError } = require('../errors')
2
3
  const { registerCommonMetrics, updateCommonMetrics } = require('../metrics/common')
3
4
  const MetricTypes = require('../metrics/types')
4
5
 
@@ -32,7 +33,7 @@ exports.initMetrics = (runtime) => {
32
33
  // Load adapters
33
34
  if (metricOptions.adapters) {
34
35
  if (!Array.isArray(metricOptions.adapters)) {
35
- runtime.handleError(new Error('Metic adapter needs to be an Array'))
36
+ runtime.handleError(new WeaveError('Metic adapter needs to be an Array.'))
36
37
  }
37
38
 
38
39
  this.adapters = metricOptions.adapters.map(adapter => {
@@ -50,21 +51,21 @@ exports.initMetrics = (runtime) => {
50
51
  },
51
52
  register (obj) {
52
53
  if (!isPlainObject(obj)) {
53
- runtime.handleError(new Error('Param needs to be an object.'))
54
+ runtime.handleError(new WeaveError('Param needs to be an object.'))
54
55
  }
55
56
 
56
57
  if (!obj.type) {
57
- runtime.handleError(new Error('Type is missing.'))
58
+ runtime.handleError(new WeaveError('Type is missing.'))
58
59
  }
59
60
 
60
61
  if (!obj.name) {
61
- runtime.handleError(new Error('Name is missing.'))
62
+ runtime.handleError(new WeaveError('Name is missing.'))
62
63
  }
63
64
 
64
65
  const createMetricType = MetricTypes.resolve(obj.type)
65
66
 
66
67
  if (!createMetricType) {
67
- runtime.handleError(new Error('Unknown metric type.'))
68
+ runtime.handleError(new WeaveError('Unknown metric type.'))
68
69
  }
69
70
 
70
71
  const type = createMetricType(this, obj)
@@ -81,7 +82,7 @@ exports.initMetrics = (runtime) => {
81
82
  const item = this.storage.get(name)
82
83
 
83
84
  if (!item) {
84
- runtime.handleError(new Error('Item not found.'))
85
+ runtime.handleError(new WeaveError('Item not found.'))
85
86
  }
86
87
 
87
88
  item.increment(labels, value, timestamp)
@@ -94,7 +95,7 @@ exports.initMetrics = (runtime) => {
94
95
  const item = this.storage.get(name)
95
96
 
96
97
  if (!item) {
97
- runtime.handleError(new Error('Item not found.'))
98
+ runtime.handleError(new WeaveError('Item not found.'))
98
99
  }
99
100
 
100
101
  item.decrement(labels, value, timestamp)
@@ -107,7 +108,7 @@ exports.initMetrics = (runtime) => {
107
108
  const item = this.storage.get(name)
108
109
 
109
110
  if (!isFunction(item.set)) {
110
- runtime.handleError(new Error('Invalid metric type'))
111
+ runtime.handleError(new WeaveError('Invalid metric type'))
111
112
  }
112
113
 
113
114
  item.set(value, labels, timestamp)
@@ -137,12 +138,12 @@ exports.initMetrics = (runtime) => {
137
138
  const item = this.storage.get(name)
138
139
 
139
140
  if (!item) {
140
- runtime.handleError(new Error('Item not found.'))
141
+ runtime.handleError(new WeaveError('Item not found.'))
141
142
  }
142
143
 
143
144
  return item
144
145
  },
145
- list (options = {}) {
146
+ list (/* options = {} */) {
146
147
  const results = []
147
148
 
148
149
  this.storage.forEach(metric => {
@@ -9,6 +9,8 @@ exports.initTracer = (runtime) => {
9
9
 
10
10
  Object.defineProperty(runtime, 'tracer', {
11
11
  value: {
12
+ runtime,
13
+ options,
12
14
  log,
13
15
  async stop () {
14
16
  if (collectors.length > 0) {
@@ -55,7 +57,6 @@ exports.initTracer = (runtime) => {
55
57
  collectors = options.collectors
56
58
  .map(entry => {
57
59
  const initCollector = resolveCollector(runtime, entry, this)
58
- // collector.init(this)
59
60
  initCollector.init(runtime)
60
61
  return initCollector
61
62
  })
@@ -1,26 +1,25 @@
1
- const { isObject } = require('@weave-js/utils')
2
- const { WeaveError } = require('../../errors')
1
+ const { isObject, pick } = require('@weave-js/utils')
3
2
 
4
- exports.createBaseTracingCollector = (options) => {
3
+ exports.createBaseTracingCollector = (runtime) => {
5
4
  const baseTracingCollector = Object.create(null)
6
5
 
7
- baseTracingCollector.options = options
6
+ baseTracingCollector.options = runtime.tracer.options
8
7
 
9
- baseTracingCollector.init = (runtime, tracer) => {
8
+ baseTracingCollector.init = (runtime) => {
10
9
  baseTracingCollector.runtime = runtime
11
- baseTracingCollector.tracer = tracer
10
+ baseTracingCollector.tracer = runtime.tracer
12
11
  }
13
12
 
14
13
  baseTracingCollector.startedSpan = () => {
15
- throw new WeaveError('not implemented.')
14
+ // throw new WeaveError('not implemented.')
16
15
  }
17
16
 
18
17
  baseTracingCollector.finishedSpan = () => {
19
- throw new WeaveError('not implemented.')
18
+ // throw new WeaveError('not implemented.')
20
19
  }
21
20
 
22
21
  baseTracingCollector.stop = () => {
23
- throw new WeaveError('not implemented.')
22
+ // throw new WeaveError('not implemented.')
24
23
  }
25
24
 
26
25
  baseTracingCollector.flattenTags = (obj, convertToString = false, path = '') => {
@@ -42,18 +41,11 @@ exports.createBaseTracingCollector = (options) => {
42
41
  }, {})
43
42
  }
44
43
 
45
- baseTracingCollector.getErrorFields = (error, ...fields) => {
46
- if (!error) {
44
+ baseTracingCollector.getErrorFields = (err, fields) => {
45
+ if (!err) {
47
46
  return null
48
47
  }
49
-
50
- const picked = {}
51
-
52
- for (const field of fields) {
53
- picked[field] = error[field]
54
- }
55
-
56
- return picked
48
+ return pick(err, fields)
57
49
  }
58
50
 
59
51
  return baseTracingCollector
@@ -13,7 +13,7 @@ const mergeDefaultOptions = (options) => {
13
13
  module.exports = (options) => (runtime, tracer) => {
14
14
  options = mergeDefaultOptions(options)
15
15
 
16
- const exporter = createBaseTracingCollector(options)
16
+ const exporter = createBaseTracingCollector(runtime)
17
17
 
18
18
  exporter.init(runtime, tracer)
19
19
 
@@ -28,7 +28,7 @@ module.exports = (options) => (runtime, tracer) => {
28
28
  const newSpan = Object.assign({}, span)
29
29
 
30
30
  if (newSpan.error) {
31
- newSpan.error = exporter.getErrorFields(newSpan.error)
31
+ newSpan.error = exporter.getErrorFields(newSpan.error, exporter.options.errors.fields)
32
32
  }
33
33
 
34
34
  return newSpan
@@ -11,14 +11,14 @@ const getByName = name => {
11
11
  return collectors[n]
12
12
  }
13
13
 
14
- exports.resolveCollector = (runtime, collector, tracer) => {
14
+ exports.resolveCollector = (runtime, collector) => {
15
15
  let CollectorClass
16
16
  if (typeof collector === 'string') {
17
17
  CollectorClass = getByName(collector)
18
18
  }
19
19
 
20
20
  if (isFunction(collector)) {
21
- return collector(runtime, tracer)
21
+ return collector(runtime)
22
22
  }
23
23
 
24
24
  if (typeof collector === 'object') {
@@ -3,8 +3,8 @@ const hrTime = require('./time')
3
3
  exports.createSpan = (tracer, name, options) => {
4
4
  const span = Object.assign({}, {
5
5
  name,
6
- id: options.id || tracer.broker.getUUID(),
7
- traceId: options.traceId || tracer.broker.getUUID(),
6
+ id: options.id || tracer.runtime.generateUUID(),
7
+ traceId: options.traceId || tracer.runtime.generateUUID(),
8
8
  parentId: options.parentId,
9
9
  type: options.type,
10
10
  sampled: options.sampled || tracer.shouldSample(),
@@ -12,10 +12,12 @@ exports.createSpan = (tracer, name, options) => {
12
12
  tags: {}
13
13
  })
14
14
 
15
- span.service = {
16
- name: options.service.name,
17
- version: options.service.version,
18
- fullyQualifiedName: options.service.fullyQualifiedName
15
+ if (options.service) {
16
+ span.service = {
17
+ name: options.service.name,
18
+ version: options.service.version,
19
+ fullyQualifiedName: options.service.fullyQualifiedName
20
+ }
19
21
  }
20
22
 
21
23
  span.addTags = (tags) => {
@@ -0,0 +1,75 @@
1
+ const { Transform } = require('stream')
2
+
3
+ const pushWithBackpressure = (stream, chunks, encoding, callback = null, $index = 0) => {
4
+ if (!(stream instanceof Transform)) {
5
+ throw new TypeError('Argument "stream" must be an instance of Duplex')
6
+ }
7
+
8
+ chunks = [].concat(chunks).filter(x => x !== undefined)
9
+
10
+ if (typeof encoding === 'function') {
11
+ callback = encoding
12
+ encoding = undefined
13
+ }
14
+
15
+ if ($index >= chunks.length) {
16
+ if (typeof callback === 'function') {
17
+ callback()
18
+ }
19
+ return stream
20
+ } else if (!stream.push(chunks[$index], ...([encoding].filter(Boolean)))) {
21
+ stream.emit('backpressure', {
22
+ sender: stream.sender,
23
+ requestId: stream.requestId
24
+ })
25
+
26
+ const pipedStreams = [].concat(
27
+ (stream._readableState || {}).pipes || stream
28
+ ).filter(Boolean)
29
+
30
+ let listenerCalled = false
31
+
32
+ const drainListener = () => {
33
+ stream.emit('resume_backpressure', {
34
+ sender: stream.sender,
35
+ requestId: stream.requestId
36
+ })
37
+
38
+ if (listenerCalled) {
39
+ return
40
+ }
41
+
42
+ listenerCalled = true
43
+
44
+ for (const stream of pipedStreams) {
45
+ stream.removeListener('drain', drainListener)
46
+ }
47
+
48
+ pushWithBackpressure(stream, chunks, encoding, callback, $index + 1)
49
+ }
50
+
51
+ for (const stream of pipedStreams) {
52
+ stream.once('drain', drainListener)
53
+ }
54
+
55
+ return stream
56
+ }
57
+ return pushWithBackpressure(stream, chunks, encoding, callback, $index + 1)
58
+ }
59
+ class InboundTransformStream extends Transform {
60
+ constructor (sender, requestId, options) {
61
+ super(options)
62
+ this.sender = sender
63
+ this.requestId = requestId
64
+ }
65
+
66
+ _transform (chunk, encoding, callback) {
67
+ pushWithBackpressure(this, chunk, encoding, callback)
68
+ }
69
+
70
+ _flush (callback) {
71
+ return callback()
72
+ }
73
+ }
74
+
75
+ module.exports = { InboundTransformStream }
@@ -6,6 +6,21 @@
6
6
 
7
7
  const EventEmitter = require('events').EventEmitter
8
8
 
9
+ /**
10
+ * @typedef {Object} AdapterBase
11
+ * @property {string} name Name
12
+ * @property {EventEmitter} bus Event bus.
13
+ * @property {function():Promise<any>} afterInit After init callback.
14
+ * @property {boolean} isConnected Is connected state.
15
+ * @property {number} interruptCounter Interruption counter.
16
+ * @property {number} repeatAttemptCounter Repeat attempt counter
17
+ * @property {function(Object, Object, Object):Promise<any>} init Repeat attempt counter
18
+ */
19
+
20
+ /**
21
+ * Create a adapter base object.
22
+ * @returns {AdapterBase} Adapter base object
23
+ */
9
24
  const createTransportBase = () => {
10
25
  let prefix = 'weave'
11
26
 
@@ -4,6 +4,6 @@
4
4
  * Copyright 2019 Fachwerk
5
5
  */
6
6
 
7
- exports.BaseAdapter = require('./adapter-base')
7
+ exports.BaseAdapter = require('./adapteBase')
8
8
  exports.Dummy = require('./dummy')
9
9
  exports.TCP = require('./tcp')
@@ -4,7 +4,7 @@
4
4
  * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
- const TransportBase = require('../adapter-base')
7
+ const TransportBase = require('../adapteBase')
8
8
  const EventEmitter = require('eventemitter2').EventEmitter2
9
9
 
10
10
  // create a global eventbus to pass messages between weave service brokers.
@@ -18,7 +18,7 @@ const DummyTransportAdapter = (adapterOptions) => {
18
18
 
19
19
  return Object.assign(TransportBase(adapterOptions), {
20
20
  name: 'Dummy',
21
- connect (isTryReconnect = false) {
21
+ connect () {
22
22
  this.bus.emit('$adapter.connected', false)
23
23
  this.log.info('Dummy transport client connected.')
24
24
  return Promise.resolve()
@@ -12,7 +12,7 @@ const createDiscoveryService = (adapter, options) => {
12
12
  const codec = Codec(options)
13
13
  const bus = new EventEmitter()
14
14
  const ips = getIpList(false)
15
- const MESSAGE_TYPE_LENGHT = 1
15
+ const MESSAGE_TYPE_LENGTH = 1
16
16
 
17
17
  let servers = []
18
18
  let discoverTimer
@@ -20,32 +20,29 @@ const createDiscoveryService = (adapter, options) => {
20
20
  const startServer = (host, port, multicastAddress) => {
21
21
  return new Promise((resolve, reject) => {
22
22
  try {
23
- const socket = dgram.createSocket({ type: options.discovery.type, reuseAddr: options.discovery.udpReuseAddress })
24
-
25
- socket.on('message', (message, info) => {
26
- const messageType = Buffer.prototype.readUInt8.call(message, 0)
27
- const payload = message.slice(MESSAGE_TYPE_LENGHT)
28
-
29
- switch (messageType) {
30
- case messageTypes.HELLO:
31
- onMessage(payload, info)
32
- break
33
- default:
34
- onUnknown(payload, info)
35
- }
23
+ const socket = dgram.createSocket({
24
+ type: options.discovery.type,
25
+ reuseAddr: options.discovery.udpReuseAddress
36
26
  })
37
27
 
38
- socket.bind({ port, host, exclusive: true }, () => {
28
+ socket.on('message', onMessage)
29
+
30
+ socket.bind({ port, exclusive: true }, () => {
39
31
  try {
40
32
  if (multicastAddress) {
41
33
  socket.setMulticastInterface(host)
42
34
  socket.addMembership(multicastAddress, host)
43
35
  socket.setMulticastTTL(1)
44
- socket.destinations = [multicastAddress]
36
+ // Add destination to socket object
37
+ Object.defineProperty(socket, 'destinations', {
38
+ value: [multicastAddress]
39
+ })
45
40
  adapter.log.info(`UDP Server is listening on ${host}:${port}. Membership: ${multicastAddress}`)
46
41
  } else {
47
42
  socket.setBroadcast(true)
48
- socket.destinations = getBroadcastAddresses()
43
+ Object.defineProperty(socket, 'destinations', {
44
+ value: getBroadcastAddresses()
45
+ })
49
46
  }
50
47
  } catch (error) {
51
48
  adapter.log.info(`UDP Multicast membership error: ${error.message}`)
@@ -62,20 +59,25 @@ const createDiscoveryService = (adapter, options) => {
62
59
  }
63
60
 
64
61
  const onMessage = (buffer, info) => {
65
- const message = codec.decode(buffer)
66
- message.host = info.address
62
+ const messageType = Buffer.prototype.readUInt8.call(buffer, 0)
63
+ const payload = buffer.slice(MESSAGE_TYPE_LENGTH)
67
64
 
68
- if (message.namespace === namespace) {
69
- bus.emit('message', message)
70
- }
71
- }
65
+ switch (messageType) {
66
+ case messageTypes.HELLO:
67
+ const message = codec.decode(payload)
68
+ message.host = info.address
72
69
 
73
- const onUnknown = (message, info) => {
74
- adapter.log.debug(`Received an unknown data package from host "${info.address}"`)
70
+ if (message.namespace === namespace) {
71
+ bus.emit('message', message)
72
+ }
73
+ break
74
+ default:
75
+ adapter.log.debug(`Received an unknown data package from host "${info.address}"`)
76
+ }
75
77
  }
76
78
 
77
79
  function sendMessage (payload) {
78
- const header = Buffer.alloc(MESSAGE_TYPE_LENGHT)
80
+ const header = Buffer.alloc(MESSAGE_TYPE_LENGTH)
79
81
  Buffer.prototype.writeUInt8.call(header, messageTypes.HELLO, 0)
80
82
 
81
83
  const message = Buffer.concat([header, codec.encode(payload)])
@@ -101,7 +103,6 @@ const createDiscoveryService = (adapter, options) => {
101
103
 
102
104
  function startDiscovering (port) {
103
105
  discoverTimer = setInterval(() => sendDiscoveryPackage(port), 2000)
104
-
105
106
  discoverTimer.unref()
106
107
  }
107
108
 
@@ -115,14 +116,27 @@ const createDiscoveryService = (adapter, options) => {
115
116
 
116
117
  return {
117
118
  bus,
118
- init (port) {
119
+ async start (port) {
119
120
  if (!options.discovery.enabled) {
120
121
  return Promise.resolve()
121
122
  }
122
123
 
123
- return Promise.all(ips.map(ip => startServer(ip, options.discovery.port, options.discovery.multicastAddress)))
124
- .then(() => setTimeout(() => sendDiscoveryPackage(port), Math.floor(Math.random() * 500) + 1))
125
- .then(() => startDiscovering(port))
124
+ // UDP Multicast
125
+ if (options.discovery.udpMulticast) {
126
+ if (options.discovery.multicastAddress) {
127
+ await Promise.all(ips.map(ip => startServer(ip, options.discovery.port, options.discovery.multicastAddress)))
128
+ }
129
+ }
130
+
131
+ // UDP Broadcast
132
+ if (options.discovery.udpBroadcast) {
133
+ await startServer(options.discovery.udpBindAddress, options.discovery.port, options.discovery.multicastAddress)
134
+ }
135
+
136
+ // send the first dis
137
+ const timeout = Math.floor(Math.random() * 500) + 500
138
+ setTimeout(() => sendDiscoveryPackage(port), timeout)
139
+ startDiscovering(port)
126
140
  },
127
141
  close () {
128
142
  stopDiscovery()
@@ -1,10 +1,12 @@
1
1
 
2
2
  const { defaultsDeep } = require('@weave-js/utils')
3
- const TransportBase = require('../adapter-base')
3
+ const TransportBase = require('../adapteBase')
4
4
  const Swim = require('./discovery/index')
5
- const MessageTypes = require('../../message-types')
5
+ const MessageTypes = require('../../messageTypes')
6
6
  const TCPReader = require('./tcpReader')
7
7
  const TCPWriter = require('./tcpWriter')
8
+ const { createMessage } = require('../../createMessage')
9
+
8
10
  // const TCPMessageTypeHelper = require('./tcp-messagetypes')
9
11
 
10
12
  const defaultOptions = {
@@ -12,6 +14,7 @@ const defaultOptions = {
12
14
  discovery: {
13
15
  enabled: true,
14
16
  type: 'udp4',
17
+ udpMulticast: true,
15
18
  multicastAddress: '239.0.0.0',
16
19
  port: 54355,
17
20
  udpReuseAddress: true
@@ -59,7 +62,11 @@ module.exports = function SwimTransport (adapterOptions) {
59
62
  MessageTypes.MESSAGE_RESPONSE,
60
63
  MessageTypes.MESSAGE_GOSSIP_HELLO,
61
64
  MessageTypes.MESSAGE_GOSSIP_REQUEST,
62
- MessageTypes.MESSAGE_GOSSIP_RESPONSE
65
+ MessageTypes.MESSAGE_GOSSIP_RESPONSE,
66
+ MessageTypes.MESSAGE_RESPONSE_STREAM_BACKPRESSURE,
67
+ MessageTypes.MESSAGE_RESPONSE_STREAM_RESUME,
68
+ MessageTypes.MESSAGE_REQUEST_STREAM_BACKPRESSURE,
69
+ MessageTypes.MESSAGE_REQUEST_STREAM_RESUME
63
70
  ].includes(message.type)) {
64
71
  if (message.type === MessageTypes.MESSAGE_DISCONNECT) {
65
72
  // send a disconnect message to all connected nodes
@@ -81,7 +88,7 @@ module.exports = function SwimTransport (adapterOptions) {
81
88
 
82
89
  const localNode = self.broker.registry.nodeCollection.localNode
83
90
 
84
- const message = self.transport.createMessage(MessageTypes.MESSAGE_GOSSIP_HELLO, nodeId, {
91
+ const message = createMessage(MessageTypes.MESSAGE_GOSSIP_HELLO, nodeId, {
85
92
  host: localNode.IPList[0],
86
93
  port: localNode.port
87
94
  })
@@ -165,7 +172,7 @@ module.exports = function SwimTransport (adapterOptions) {
165
172
  }
166
173
  })
167
174
 
168
- self.swim.init(port)
175
+ self.swim.start(port)
169
176
  }
170
177
 
171
178
  function startTCPServer () {
@@ -174,19 +181,19 @@ module.exports = function SwimTransport (adapterOptions) {
174
181
 
175
182
  tcpReader.on('message', onMessage)
176
183
 
177
- tcpWriter.on('error', (error, nodeID) => {
184
+ tcpWriter.on('error', (error, nodeId) => {
178
185
  self.log.debug('TCP client error on ', error)
179
- self.broker.registry.nodeDisconnected(nodeID, false)
186
+ self.broker.registry.nodeDisconnected(nodeId, false)
180
187
  })
181
188
 
182
- tcpWriter.on('end', nodeID => {
189
+ tcpWriter.on('end', nodeId => {
183
190
  self.log.debug('TCP connection ended with')
184
- self.broker.registry.nodeDisconnected(nodeID, false)
191
+ self.broker.registry.nodeDisconnected(nodeId, false)
185
192
  })
186
193
 
187
- // tcpWriter.on('error', (_, nodeID) => {
194
+ // tcpWriter.on('error', (_, nodeId) => {
188
195
  // self.log.debug('TCP server error on ')
189
- // // this.nodes.disconnected(nodeID, false)
196
+ // // this.nodes.disconnected(nodeId, false)
190
197
  // })
191
198
 
192
199
  return tcpReader.listen()
@@ -250,7 +257,7 @@ module.exports = function SwimTransport (adapterOptions) {
250
257
 
251
258
  const destinationNode = nodes[Math.floor(Math.random() * nodes.length)]
252
259
  if (destinationNode) {
253
- const message = self.transport.createMessage(MessageTypes.MESSAGE_GOSSIP_REQUEST, destinationNode.id, payload)
260
+ const message = createMessage(MessageTypes.MESSAGE_GOSSIP_REQUEST, destinationNode.id, payload)
254
261
 
255
262
  self.send(message).catch(() => {
256
263
  self.log.debug(`Unable to send gossip response to ${destinationNode.id}`)
@@ -357,7 +364,7 @@ module.exports = function SwimTransport (adapterOptions) {
357
364
 
358
365
  if (response.online || response.offline) {
359
366
  const destinationNode = self.broker.registry.nodeCollection.get(payload.sender)
360
- const message = self.transport.createMessage(MessageTypes.MESSAGE_GOSSIP_RESPONSE, destinationNode.id, response)
367
+ const message = createMessage(MessageTypes.MESSAGE_GOSSIP_RESPONSE, destinationNode.id, response)
361
368
  self.send(message).catch(() => {})
362
369
  }
363
370
  } catch (error) {