@weave-js/core 0.9.4 → 0.11.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/ExtendableError.js +33 -0
- package/lib/broker/context.js +25 -13
- package/lib/broker/{default-options.js → defaultOptions.js} +25 -6
- package/lib/broker/index.js +224 -194
- package/lib/buildRuntime.js +70 -0
- package/lib/cache/adapters/base.js +143 -0
- package/lib/cache/adapters/inMemory.js +154 -0
- package/lib/cache/adapters/inMemoryLru.js +140 -0
- package/lib/cache/adapters/index.js +46 -0
- package/lib/cache/base.js +49 -44
- package/lib/cache/lock.js +21 -4
- package/lib/constants.js +8 -5
- package/lib/errorHandler.js +19 -0
- package/lib/errors.js +17 -10
- package/lib/helper/{define-action.js → defineAction.js} +3 -1
- package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +2 -0
- package/lib/helper/{define-service.js → defineService.js} +4 -1
- package/lib/index.js +17 -92
- package/lib/logger/format/asHumanReadable.js +4 -3
- package/lib/logger/index.js +7 -1
- package/lib/logger/levels.js +8 -7
- package/lib/logger/tools.js +4 -0
- package/lib/logger/utils/format.js +18 -4
- package/lib/metrics/constants.js +8 -6
- package/lib/metrics/types/gauge.js +1 -1
- package/lib/middlewares/action-hooks/index.js +62 -14
- package/lib/middlewares/bulkhead/index.js +5 -4
- package/lib/middlewares/cache/index.js +106 -0
- package/lib/middlewares/circuit-breaker/index.js +41 -16
- package/lib/middlewares/context-tracker/index.js +3 -3
- package/lib/middlewares/error-handler/index.js +3 -3
- package/lib/middlewares/index.js +2 -1
- package/lib/middlewares/metrics/getMiddlewareWrapper.js +2 -2
- package/lib/middlewares/metrics/index.js +2 -2
- package/lib/middlewares/retry/index.js +11 -10
- package/lib/middlewares/timeout/index.js +5 -5
- package/lib/middlewares/tracing/index.js +27 -14
- package/lib/middlewares/tracing/tags.js +43 -0
- package/lib/middlewares/validator/index.js +6 -6
- package/lib/registry/{action-endpoint.js → actionEndpoint.js} +0 -0
- package/lib/registry/collections/{action-collection.js → actionCollection.js} +2 -2
- package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +19 -3
- package/lib/registry/collections/{event-collection.js → eventCollection.js} +15 -9
- package/lib/registry/collections/{node-collection.js → nodeCollection.js} +1 -1
- package/lib/registry/collections/{service-collection.js → serviceCollection.js} +2 -2
- package/lib/registry/{event-endpoint.js → eventEndpoint.js} +1 -1
- package/lib/registry/node.js +1 -1
- package/lib/registry/registry.js +19 -38
- package/lib/registry/service/service.js +2 -2
- package/lib/registry/{service-item.js → serviceItem.js} +1 -1
- package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +3 -3
- package/lib/runtime/initCache.js +19 -0
- package/lib/runtime/{init-context-factory.js → initContextFactory.js} +2 -2
- package/lib/runtime/{init-eventbus.js → initEventbus.js} +11 -10
- package/lib/runtime/{init-logger.js → initLogger.js} +0 -0
- package/lib/runtime/{init-metrics.js → initMetrics.js} +11 -10
- package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +1 -1
- package/lib/runtime/{init-registry.js → initRegistry.js} +1 -1
- package/lib/runtime/{init-service-manager.js → initServiceManager.js} +0 -0
- package/lib/runtime/{init-tracing.js → initTracing.js} +2 -1
- package/lib/runtime/{init-transport.js → initTransport.js} +0 -0
- package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +0 -0
- package/lib/runtime/{init-validator.js → initValidator.js} +1 -1
- package/lib/tracing/collectors/base.js +11 -19
- package/lib/tracing/collectors/event.js +2 -2
- package/lib/tracing/collectors/index.js +2 -2
- package/lib/tracing/span.js +8 -6
- package/lib/transport/InboundTransformStream.js +75 -0
- package/lib/transport/adapters/{adapter-base.js → adapteBase.js} +16 -1
- package/lib/transport/adapters/adapters.js +1 -1
- package/lib/transport/adapters/dummy/index.js +3 -3
- package/lib/transport/adapters/index.js +1 -1
- package/lib/transport/adapters/tcp/discovery/index.js +45 -31
- package/lib/transport/adapters/tcp/index.js +20 -13
- package/lib/transport/adapters/tcp/tcpReader.js +1 -0
- package/lib/transport/adapters/tcp/tcpWriteStream.js +1 -1
- package/lib/transport/adapters/tcp/tcpWriter.js +2 -2
- package/lib/transport/createMessage.js +11 -0
- package/lib/transport/createTransport.js +215 -172
- package/lib/transport/errorPayloadFactory.js +18 -0
- package/lib/transport/{message-handlers.js → messageHandlers.js} +92 -23
- package/lib/transport/messageTypes.js +23 -0
- package/lib/types.js +86 -75
- package/lib/utils/index.js +1 -1
- package/lib/utils/options.js +4 -2
- package/lib/utils/{restore-error.js → restoreError.js} +1 -1
- package/package.json +6 -12
- package/CHANGELOG.md +0 -1317
- package/lib/cache/index.js +0 -48
- package/lib/cache/memory.js +0 -91
- package/lib/middlewares/tracing/buildTags.js +0 -17
- package/lib/new-errors.js +0 -25
- package/lib/runtime/init-cache.js +0 -10
- package/lib/tracing/collectors/console.js +0 -34
- package/lib/tracing/index.js +0 -3
- package/lib/tracing/tracer.js +0 -64
- package/lib/transport/message-types.js +0 -59
- package/lib/transport/message.js +0 -16
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Author: Kevin Ries (kevin@fachw3rk.de)
|
|
3
3
|
* -----
|
|
4
|
-
* Copyright
|
|
4
|
+
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
* @typedef {import('../types.js').TransportAdapter} TransportAdapter
|
|
10
10
|
* @typedef {import('../types.js').Transport} Transport
|
|
11
11
|
* @typedef {import('../types').TransportMessage} TransportMessage
|
|
12
|
+
* @typedef {import('../types').Context} Context
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
// Own packages
|
|
15
16
|
const { WeaveError, WeaveQueueSizeExceededError } = require('../errors')
|
|
16
|
-
const
|
|
17
|
+
const { createMessage } = require('./createMessage')
|
|
18
|
+
const MessageTypes = require('./messageTypes')
|
|
17
19
|
const utils = require('@weave-js/utils')
|
|
18
|
-
const createMessageHandler = require('./
|
|
20
|
+
const createMessageHandler = require('./messageHandlers')
|
|
21
|
+
const { errorPayloadFactory } = require('./errorPayloadFactory')
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* Create a Transport adapter
|
|
@@ -25,133 +28,24 @@ const createMessageHandler = require('./message-handlers')
|
|
|
25
28
|
*/
|
|
26
29
|
exports.createTransport = (runtime, adapter) => {
|
|
27
30
|
const transport = Object.create(null)
|
|
28
|
-
const { nodeId, middlewareHandler } = runtime
|
|
31
|
+
const { nodeId, middlewareHandler, createLogger } = runtime
|
|
29
32
|
|
|
30
33
|
let heartbeatTimer
|
|
31
34
|
let checkNodesTimer
|
|
32
35
|
let checkOfflineNodesTimer
|
|
33
36
|
let updateLocalNodeTimer
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
// Pending action store
|
|
37
39
|
const pending = {
|
|
38
40
|
requests: new Map(),
|
|
39
41
|
requestStreams: new Map(),
|
|
40
|
-
responseStreams: new Map()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// Outgoing request
|
|
44
|
-
const doRequest = (context, resolve, reject) => {
|
|
45
|
-
const isStream = utils.isStream(context.options.stream)
|
|
46
|
-
|
|
47
|
-
const request = {
|
|
48
|
-
targetNodeId: context.nodeId,
|
|
49
|
-
action: context.action.name,
|
|
50
|
-
context,
|
|
51
|
-
resolve,
|
|
52
|
-
reject,
|
|
53
|
-
isStream
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
log.debug(`Send request for ${request.action} to node ${request.targetNodeId}.`)
|
|
57
|
-
|
|
58
|
-
pending.requests.set(context.id, request)
|
|
59
|
-
|
|
60
|
-
const payload = {
|
|
61
|
-
id: context.id,
|
|
62
|
-
action: context.action.name,
|
|
63
|
-
data: context.data,
|
|
64
|
-
timeout: context.options.timeout,
|
|
65
|
-
meta: context.meta,
|
|
66
|
-
level: context.level,
|
|
67
|
-
metrics: context.metrics,
|
|
68
|
-
requestId: context.requestId,
|
|
69
|
-
parentId: context.parentId,
|
|
70
|
-
isStream
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Handle object mode streams
|
|
74
|
-
if (isStream) {
|
|
75
|
-
if (utils.isStreamObjectMode(context.options.stream)) {
|
|
76
|
-
payload.meta = payload.meta || {}
|
|
77
|
-
payload.meta.$isObjectModeStream = true
|
|
78
|
-
}
|
|
79
|
-
payload.sequence = 0
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const message = transport.createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payload)
|
|
83
|
-
|
|
84
|
-
return transport.send(message)
|
|
85
|
-
.then(() => {
|
|
86
|
-
// send stream
|
|
87
|
-
if (isStream) {
|
|
88
|
-
const stream = context.options.stream
|
|
89
|
-
payload.meta = {}
|
|
90
|
-
|
|
91
|
-
if (utils.isStreamObjectMode(context.options.stream)) {
|
|
92
|
-
payload.meta.$isObjectModeStream = true
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
stream.on('data', data => {
|
|
96
|
-
stream.pause()
|
|
97
|
-
const chunks = []
|
|
98
|
-
|
|
99
|
-
// The chunk is larger than maxBufferSize
|
|
100
|
-
if (data instanceof Buffer && runtime.options.transport.maxChunkSize > 0 && data.length > runtime.options.transport.maxChunkSize) {
|
|
101
|
-
const length = data.length
|
|
102
|
-
let i = 0
|
|
103
|
-
while (i < length) {
|
|
104
|
-
chunks.push(data.slice(i, i += runtime.options.transport.maxChunkSize))
|
|
105
|
-
}
|
|
106
|
-
} else {
|
|
107
|
-
chunks.push(data)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Send chunks from chunk buffer
|
|
111
|
-
for (const chunk of chunks) {
|
|
112
|
-
const payloadCopy = Object.assign({}, payload)
|
|
113
|
-
payloadCopy.sequence = ++payload.sequence
|
|
114
|
-
payloadCopy.chunk = chunk
|
|
115
|
-
payloadCopy.isStream = true
|
|
116
|
-
payload.data = null
|
|
117
|
-
|
|
118
|
-
const message = transport.createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
119
|
-
transport.send(message)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// resume stream
|
|
123
|
-
stream.resume()
|
|
124
|
-
return
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
stream.on('end', () => {
|
|
128
|
-
const payloadCopy = Object.assign({}, payload)
|
|
129
|
-
payloadCopy.sequence = ++payload.sequence
|
|
130
|
-
payloadCopy.chunk = null
|
|
131
|
-
payloadCopy.isStream = false
|
|
132
|
-
const message = transport.createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
133
|
-
return transport.send(message)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
stream.on('error', (_) => {
|
|
137
|
-
const payloadCopy = Object.assign({}, payload)
|
|
138
|
-
payloadCopy.sequence = ++payload.sequence
|
|
139
|
-
payloadCopy.chunk = null
|
|
140
|
-
payloadCopy.isStream = false
|
|
141
|
-
|
|
142
|
-
// todo: Attach error on payload
|
|
143
|
-
|
|
144
|
-
const message = transport.createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
145
|
-
return transport.send(message)
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
.catch((error) => {
|
|
150
|
-
reject(error)
|
|
151
|
-
})
|
|
42
|
+
responseStreams: new Map(),
|
|
43
|
+
outboundResponseStreams: new Map(),
|
|
44
|
+
outboundRequestStreams: new Map()
|
|
152
45
|
}
|
|
153
46
|
|
|
154
|
-
transport.log =
|
|
47
|
+
transport.log = createLogger('TRANSPORT')
|
|
48
|
+
transport.reconnectInProgress = false
|
|
155
49
|
transport.isConnected = false
|
|
156
50
|
transport.isDisconnecting = false
|
|
157
51
|
transport.isReady = false
|
|
@@ -167,24 +61,24 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
167
61
|
}
|
|
168
62
|
}
|
|
169
63
|
|
|
64
|
+
const getErrorPayload = errorPayloadFactory(runtime)
|
|
65
|
+
|
|
170
66
|
transport.connect = () => {
|
|
171
67
|
return new Promise(resolve => {
|
|
172
68
|
transport.resolveConnect = resolve
|
|
173
69
|
transport.log.info('Connecting to transport adapter...')
|
|
174
70
|
|
|
175
71
|
const doConnect = (isTryReconnect) => {
|
|
176
|
-
let reconnectInProgress = false
|
|
177
|
-
|
|
178
72
|
const errorHandler = (error) => {
|
|
179
73
|
// Skip reconnect, if the adapter is disconnecting or an reconnect is in progress.
|
|
180
|
-
if (transport.isDisconnecting || reconnectInProgress) {
|
|
74
|
+
if (transport.isDisconnecting || transport.reconnectInProgress) {
|
|
181
75
|
return
|
|
182
76
|
}
|
|
183
77
|
|
|
184
78
|
transport.log.warn('Connection failed')
|
|
185
79
|
transport.log.debug(error)
|
|
186
80
|
|
|
187
|
-
reconnectInProgress = true
|
|
81
|
+
transport.reconnectInProgress = true
|
|
188
82
|
|
|
189
83
|
if (!error.skipRetry) {
|
|
190
84
|
setTimeout(() => {
|
|
@@ -207,11 +101,11 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
207
101
|
transport.isConnected = false
|
|
208
102
|
transport.isReady = false
|
|
209
103
|
|
|
210
|
-
runtime.eventBus.broadcastLocal('$transporter.disconnected', {
|
|
104
|
+
runtime.eventBus.broadcastLocal('$transporter.disconnected', { isGraceful: true })
|
|
211
105
|
|
|
212
106
|
stopTimers()
|
|
213
107
|
|
|
214
|
-
const message =
|
|
108
|
+
const message = createMessage(MessageTypes.MESSAGE_DISCONNECT)
|
|
215
109
|
return transport.send(message)
|
|
216
110
|
.then(() => {
|
|
217
111
|
adapter.close()
|
|
@@ -221,10 +115,10 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
221
115
|
})
|
|
222
116
|
}
|
|
223
117
|
|
|
224
|
-
transport.setReady = () => {
|
|
118
|
+
transport.setReady = async () => {
|
|
225
119
|
if (transport.isConnected) {
|
|
226
120
|
transport.isReady = true
|
|
227
|
-
transport.sendNodeInfo()
|
|
121
|
+
await transport.sendNodeInfo()
|
|
228
122
|
}
|
|
229
123
|
}
|
|
230
124
|
|
|
@@ -233,16 +127,18 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
233
127
|
* @param {*} sender sender node ID.
|
|
234
128
|
* @returns {Promise} Promise
|
|
235
129
|
*/
|
|
236
|
-
transport.sendNodeInfo = (sender) => {
|
|
130
|
+
transport.sendNodeInfo = async (sender) => {
|
|
237
131
|
if (!transport.isConnected || !transport.isReady) {
|
|
238
132
|
return Promise.resolve()
|
|
239
133
|
}
|
|
240
134
|
|
|
135
|
+
// Collect own node info and send it to remote nodes
|
|
241
136
|
const info = runtime.registry.getLocalNodeInfo()
|
|
242
|
-
const message =
|
|
137
|
+
const message = createMessage(MessageTypes.MESSAGE_INFO, sender, {
|
|
243
138
|
...info,
|
|
244
139
|
instanceId: runtime.state.instanceId
|
|
245
140
|
})
|
|
141
|
+
|
|
246
142
|
return transport.send(message)
|
|
247
143
|
}
|
|
248
144
|
|
|
@@ -251,28 +147,42 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
251
147
|
* @param {TransportMessage} message Message to send
|
|
252
148
|
* @returns {Promise} Promise
|
|
253
149
|
*/
|
|
254
|
-
transport.send = (message) => {
|
|
150
|
+
transport.send = async (message) => {
|
|
255
151
|
transport.statistics.sent.packages = transport.statistics.sent.packages + 1
|
|
256
|
-
log.verbose(`Send ${message.type.toUpperCase()} packet to ${message.targetNodeId || 'all nodes'}`)
|
|
152
|
+
transport.log.verbose(`Send ${message.type.toUpperCase()} packet to ${message.targetNodeId || 'all nodes'}`)
|
|
257
153
|
return adapter.preSend(message)
|
|
258
154
|
}
|
|
259
155
|
|
|
260
156
|
transport.sendPing = (nodeId) => {
|
|
261
|
-
const pingMessage =
|
|
157
|
+
const pingMessage = createMessage(MessageTypes.MESSAGE_PING, nodeId, { dispatchTime: Date.now() })
|
|
262
158
|
return transport.send(pingMessage)
|
|
263
159
|
}
|
|
264
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Send discovery message to all nodes.
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
265
165
|
transport.discoverNodes = () => {
|
|
266
|
-
const discoveryMessage =
|
|
166
|
+
const discoveryMessage = createMessage(MessageTypes.MESSAGE_DISCOVERY)
|
|
267
167
|
transport.send(discoveryMessage)
|
|
268
168
|
}
|
|
269
169
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Send discovery message to all nodes.
|
|
172
|
+
* @param{string} target - Target node ID
|
|
173
|
+
* @returns {Promise<void>} - Promise
|
|
174
|
+
*/
|
|
175
|
+
transport.discoverNode = async (target) => {
|
|
176
|
+
const discoveryMessage = createMessage(MessageTypes.MESSAGE_DISCOVERY, target)
|
|
177
|
+
return transport.send(discoveryMessage)
|
|
273
178
|
}
|
|
274
179
|
|
|
275
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Send an event
|
|
182
|
+
* @param {Context} context - Context
|
|
183
|
+
* @returns {Promise<void>} - Promise
|
|
184
|
+
*/
|
|
185
|
+
transport.sendEvent = async (context) => {
|
|
276
186
|
const isBroadcast = context.eventType === 'broadcast'
|
|
277
187
|
|
|
278
188
|
const payload = {
|
|
@@ -287,12 +197,12 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
287
197
|
isBroadcast
|
|
288
198
|
}
|
|
289
199
|
|
|
290
|
-
const message =
|
|
200
|
+
const message = createMessage(MessageTypes.MESSAGE_EVENT, context.endpoint ? context.nodeId : null, payload)
|
|
291
201
|
return transport.send(message)
|
|
292
202
|
}
|
|
293
203
|
|
|
294
204
|
transport.sendBroadcastEvent = (nodeId, eventName, data, groups) => {
|
|
295
|
-
log.verbose(`Send ${eventName} to ${nodeId}`)
|
|
205
|
+
transport.log.verbose(`Send ${eventName} to ${nodeId}`)
|
|
296
206
|
|
|
297
207
|
const payload = {
|
|
298
208
|
data,
|
|
@@ -301,18 +211,20 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
301
211
|
isBroadcast: true
|
|
302
212
|
}
|
|
303
213
|
|
|
304
|
-
const message =
|
|
305
|
-
transport.send(message)
|
|
214
|
+
const message = createMessage(MessageTypes.MESSAGE_EVENT, nodeId, payload)
|
|
215
|
+
return transport.send(message)
|
|
306
216
|
}
|
|
307
217
|
|
|
308
218
|
transport.removePendingRequestsById = (requestId) => {
|
|
309
219
|
pending.requests.delete(requestId)
|
|
310
220
|
pending.requestStreams.delete(requestId)
|
|
311
221
|
pending.responseStreams.delete(requestId)
|
|
222
|
+
pending.outboundResponseStreams.delete(requestId)
|
|
223
|
+
pending.outboundRequestStreams.delete(requestId)
|
|
312
224
|
}
|
|
313
225
|
|
|
314
226
|
transport.removePendingRequestsByNodeId = (nodeId) => {
|
|
315
|
-
log.debug(`Remove pending requests for node ${nodeId}.`)
|
|
227
|
+
transport.log.debug(`Remove pending requests for node ${nodeId}.`)
|
|
316
228
|
pending.requests.forEach((request, requestId) => {
|
|
317
229
|
if (request.nodeId === nodeId) {
|
|
318
230
|
pending.requests.delete(requestId)
|
|
@@ -324,15 +236,7 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
324
236
|
})
|
|
325
237
|
}
|
|
326
238
|
|
|
327
|
-
transport.
|
|
328
|
-
return {
|
|
329
|
-
type: type || MessageTypes.MESSAGE_UNKNOWN,
|
|
330
|
-
targetNodeId,
|
|
331
|
-
payload: payload || {}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
transport.request = (context) => {
|
|
239
|
+
transport.sendRequest = (context) => {
|
|
336
240
|
// If the queue size is set, check the queue size and reject the job when the limit is reached.
|
|
337
241
|
if (runtime.options.transport.maxQueueSize && runtime.options.transport.maxQueueSize < pending.requests.size) {
|
|
338
242
|
return Promise.reject(new WeaveQueueSizeExceededError({
|
|
@@ -343,10 +247,142 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
343
247
|
}))
|
|
344
248
|
}
|
|
345
249
|
|
|
346
|
-
return new Promise((resolve, reject) =>
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
const isStream = utils.isStream(context.options.stream)
|
|
252
|
+
|
|
253
|
+
const request = {
|
|
254
|
+
targetNodeId: context.nodeId,
|
|
255
|
+
action: context.action.name,
|
|
256
|
+
context,
|
|
257
|
+
resolve,
|
|
258
|
+
reject,
|
|
259
|
+
isStream
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
transport.log.debug(`Send request for ${request.action} to node ${request.targetNodeId}.`)
|
|
263
|
+
|
|
264
|
+
pending.requests.set(context.id, request)
|
|
265
|
+
|
|
266
|
+
const payload = {
|
|
267
|
+
id: context.id,
|
|
268
|
+
action: context.action.name,
|
|
269
|
+
data: context.data,
|
|
270
|
+
timeout: context.options.timeout,
|
|
271
|
+
meta: context.meta,
|
|
272
|
+
level: context.level,
|
|
273
|
+
metrics: context.metrics,
|
|
274
|
+
requestId: context.requestId,
|
|
275
|
+
parentId: context.parentId,
|
|
276
|
+
isStream
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Handle object mode streams
|
|
280
|
+
if (isStream) {
|
|
281
|
+
const stream = context.options.stream
|
|
282
|
+
|
|
283
|
+
if (!pending.outboundRequestStreams.has(payload.id)) {
|
|
284
|
+
pending.outboundRequestStreams.set(payload.id, stream)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (utils.isStreamObjectMode(stream)) {
|
|
288
|
+
payload.meta = payload.meta || {}
|
|
289
|
+
payload.meta.$isObjectModeStream = true
|
|
290
|
+
}
|
|
291
|
+
payload.sequence = 0
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const message = createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payload)
|
|
295
|
+
|
|
296
|
+
return transport.send(message)
|
|
297
|
+
.then(() => {
|
|
298
|
+
// send stream
|
|
299
|
+
if (isStream) {
|
|
300
|
+
const stream = context.options.stream
|
|
301
|
+
payload.meta = {}
|
|
302
|
+
|
|
303
|
+
if (utils.isStreamObjectMode(context.options.stream)) {
|
|
304
|
+
payload.meta.$isObjectModeStream = true
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
stream.on('data', data => {
|
|
308
|
+
stream.pause()
|
|
309
|
+
const chunks = []
|
|
310
|
+
|
|
311
|
+
// The chunk is larger than maxBufferSize
|
|
312
|
+
if (data instanceof Buffer && runtime.options.transport.maxChunkSize > 0 && data.length > runtime.options.transport.maxChunkSize) {
|
|
313
|
+
const length = data.length
|
|
314
|
+
let i = 0
|
|
315
|
+
while (i < length) {
|
|
316
|
+
chunks.push(data.slice(i, i += runtime.options.transport.maxChunkSize))
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
chunks.push(data)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Send chunks from chunk buffer
|
|
323
|
+
for (const chunk of chunks) {
|
|
324
|
+
const payloadCopy = Object.assign({}, payload)
|
|
325
|
+
payloadCopy.sequence = ++payload.sequence
|
|
326
|
+
payloadCopy.chunk = chunk
|
|
327
|
+
payloadCopy.isStream = true
|
|
328
|
+
payload.data = null
|
|
329
|
+
|
|
330
|
+
const message = createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
331
|
+
transport.send(message)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// resume stream
|
|
335
|
+
stream.resume()
|
|
336
|
+
return
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
stream.on('end', () => {
|
|
340
|
+
const payloadCopy = Object.assign({}, payload)
|
|
341
|
+
|
|
342
|
+
payloadCopy.sequence = ++payload.sequence
|
|
343
|
+
payloadCopy.chunk = null
|
|
344
|
+
payloadCopy.isStream = false
|
|
345
|
+
|
|
346
|
+
pending.outboundRequestStreams.delete(payload.id)
|
|
347
|
+
|
|
348
|
+
const message = createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
349
|
+
return transport.send(message)
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
stream.on('error', (error) => {
|
|
353
|
+
const payloadCopy = Object.assign({}, payload)
|
|
354
|
+
payloadCopy.sequence = ++payload.sequence
|
|
355
|
+
payloadCopy.chunk = null
|
|
356
|
+
payloadCopy.isStream = false
|
|
357
|
+
|
|
358
|
+
if (error) {
|
|
359
|
+
payloadCopy.success = false
|
|
360
|
+
payloadCopy.error = getErrorPayload(error)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
pending.outboundRequestStreams.delete(payload.id)
|
|
364
|
+
|
|
365
|
+
const message = createMessage(MessageTypes.MESSAGE_REQUEST, context.nodeId, payloadCopy)
|
|
366
|
+
return transport.send(message)
|
|
367
|
+
})
|
|
368
|
+
}
|
|
369
|
+
})
|
|
370
|
+
.catch((error) => {
|
|
371
|
+
reject(error)
|
|
372
|
+
})
|
|
373
|
+
})
|
|
347
374
|
}
|
|
348
375
|
|
|
349
|
-
|
|
376
|
+
/**
|
|
377
|
+
* Send response for an open request.
|
|
378
|
+
* @param {string} target - Target node ID
|
|
379
|
+
* @param {string} contextId - Context ID
|
|
380
|
+
* @param {any} data - Data
|
|
381
|
+
* @param {Object} meta - Meta data
|
|
382
|
+
* @param {WeaveError=} error - Error
|
|
383
|
+
* @returns {Promise<void>} - Promise
|
|
384
|
+
*/
|
|
385
|
+
transport.sendResponse = (target, contextId, data, meta, error) => {
|
|
350
386
|
// Check if data is a stream
|
|
351
387
|
const isStream = utils.isStream(data)
|
|
352
388
|
|
|
@@ -360,19 +396,16 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
360
396
|
|
|
361
397
|
// If an error is occurs, we attach the an error object to the payload.
|
|
362
398
|
if (error) {
|
|
363
|
-
payload.error =
|
|
364
|
-
name: error.name,
|
|
365
|
-
message: error.message,
|
|
366
|
-
nodeId: error.nodeId || nodeId,
|
|
367
|
-
code: error.code,
|
|
368
|
-
type: error.type,
|
|
369
|
-
stack: error.stack,
|
|
370
|
-
data: error.data
|
|
371
|
-
}
|
|
399
|
+
payload.error = getErrorPayload(error)
|
|
372
400
|
}
|
|
373
401
|
|
|
374
402
|
if (isStream) {
|
|
375
403
|
const stream = data
|
|
404
|
+
|
|
405
|
+
if (!pending.outboundResponseStreams.has(payload.id)) {
|
|
406
|
+
pending.outboundResponseStreams.set(payload.id, stream)
|
|
407
|
+
}
|
|
408
|
+
|
|
376
409
|
payload.data = null
|
|
377
410
|
payload.sequence = 0
|
|
378
411
|
payload.isStream = true
|
|
@@ -406,9 +439,9 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
406
439
|
payloadCopy.sequence = ++payload.sequence
|
|
407
440
|
|
|
408
441
|
payloadCopy.chunk = chunk
|
|
409
|
-
transport.log.debug(
|
|
442
|
+
transport.log.debug(`Send Stream chunk to ${target}`)
|
|
410
443
|
|
|
411
|
-
const message =
|
|
444
|
+
const message = createMessage(MessageTypes.MESSAGE_RESPONSE, target, payloadCopy)
|
|
412
445
|
transport.send(message)
|
|
413
446
|
}
|
|
414
447
|
|
|
@@ -424,10 +457,11 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
424
457
|
payloadCopy.chunk = null
|
|
425
458
|
payloadCopy.isStream = false
|
|
426
459
|
|
|
427
|
-
transport.log.debug(
|
|
460
|
+
transport.log.debug(`Send end stream chunk to ${target}`)
|
|
428
461
|
|
|
429
|
-
const message =
|
|
462
|
+
const message = createMessage(MessageTypes.MESSAGE_RESPONSE, target, payloadCopy)
|
|
430
463
|
transport.send(message)
|
|
464
|
+
pending.outboundResponseStreams.delete(payload.id)
|
|
431
465
|
})
|
|
432
466
|
|
|
433
467
|
stream.on('error', (error) => {
|
|
@@ -439,18 +473,23 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
439
473
|
|
|
440
474
|
if (error) {
|
|
441
475
|
payloadCopy.success = false
|
|
476
|
+
payloadCopy.error = getErrorPayload(error)
|
|
442
477
|
}
|
|
443
|
-
|
|
478
|
+
|
|
479
|
+
transport.log.debug(`Send closing chunk to ${target}`)
|
|
480
|
+
|
|
481
|
+
const message = createMessage(MessageTypes.MESSAGE_RESPONSE, target, payloadCopy)
|
|
444
482
|
transport.send(message)
|
|
483
|
+
pending.outboundResponseStreams.delete(payload.id)
|
|
445
484
|
})
|
|
446
485
|
|
|
447
486
|
payload.data = null
|
|
448
|
-
const message =
|
|
487
|
+
const message = createMessage(MessageTypes.MESSAGE_RESPONSE, target, payload)
|
|
449
488
|
return transport.send(message)
|
|
450
489
|
.then(() => stream.resume())
|
|
451
490
|
}
|
|
452
491
|
|
|
453
|
-
const message =
|
|
492
|
+
const message = createMessage(MessageTypes.MESSAGE_RESPONSE, target, payload)
|
|
454
493
|
return transport.send(message)
|
|
455
494
|
}
|
|
456
495
|
|
|
@@ -528,7 +567,11 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
528
567
|
adapter.subscribe(MessageTypes.MESSAGE_PONG, nodeId),
|
|
529
568
|
adapter.subscribe(MessageTypes.MESSAGE_DISCONNECT),
|
|
530
569
|
adapter.subscribe(MessageTypes.MESSAGE_HEARTBEAT),
|
|
531
|
-
adapter.subscribe(MessageTypes.MESSAGE_EVENT, nodeId)
|
|
570
|
+
adapter.subscribe(MessageTypes.MESSAGE_EVENT, nodeId),
|
|
571
|
+
adapter.subscribe(MessageTypes.MESSAGE_RESPONSE_STREAM_BACKPRESSURE, nodeId),
|
|
572
|
+
adapter.subscribe(MessageTypes.MESSAGE_RESPONSE_STREAM_RESUME, nodeId),
|
|
573
|
+
adapter.subscribe(MessageTypes.MESSAGE_REQUEST_STREAM_BACKPRESSURE, nodeId),
|
|
574
|
+
adapter.subscribe(MessageTypes.MESSAGE_REQUEST_STREAM_RESUME, nodeId)
|
|
532
575
|
])
|
|
533
576
|
}
|
|
534
577
|
|
|
@@ -567,7 +610,7 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
567
610
|
const node = runtime.registry.nodeCollection.localNode
|
|
568
611
|
node.updateLocalInfo()
|
|
569
612
|
|
|
570
|
-
log.verbose(`Send heartbeat from ${node.id}`)
|
|
613
|
+
transport.log.verbose(`Send heartbeat from ${node.id}`)
|
|
571
614
|
|
|
572
615
|
const payload = {
|
|
573
616
|
cpu: node.cpu,
|
|
@@ -575,7 +618,7 @@ exports.createTransport = (runtime, adapter) => {
|
|
|
575
618
|
sequence: node.sequence
|
|
576
619
|
}
|
|
577
620
|
|
|
578
|
-
const message =
|
|
621
|
+
const message = createMessage(MessageTypes.MESSAGE_HEARTBEAT, null, payload)
|
|
579
622
|
transport.send(message)
|
|
580
623
|
}
|
|
581
624
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Payload factory
|
|
3
|
+
* @param {import("../types").Runtime} runtime Runtime
|
|
4
|
+
* @returns {function(Error)} Generate error payload object
|
|
5
|
+
*/
|
|
6
|
+
const errorPayloadFactory = (runtime) => (error) => {
|
|
7
|
+
return {
|
|
8
|
+
name: error.name,
|
|
9
|
+
message: error.message,
|
|
10
|
+
nodeId: error.nodeId || runtime.nodeId,
|
|
11
|
+
code: error.code,
|
|
12
|
+
type: error.type,
|
|
13
|
+
stack: error.stack,
|
|
14
|
+
data: error.data
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = { errorPayloadFactory }
|