@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.
- package/lib/ExtendableError.js +33 -0
- package/lib/broker/context.js +12 -0
- package/lib/broker/{default-options.js → defaultOptions.js} +22 -4
- package/lib/broker/index.js +218 -192
- package/lib/{build-runtime.js → buildRuntime.js} +16 -16
- package/lib/cache/base.js +33 -28
- package/lib/cache/inMemory.js +140 -0
- package/lib/cache/index.js +1 -1
- package/lib/cache/lock.js +21 -4
- package/lib/constants.js +7 -4
- package/lib/{error-handler.js → errorHandler.js} +0 -0
- package/lib/errors.js +16 -9
- 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 +13 -9
- package/lib/logger/format/asHumanReadable.js +4 -3
- package/lib/logger/index.js +4 -1
- package/lib/logger/levels.js +2 -1
- package/lib/logger/tools.js +4 -0
- package/lib/logger/utils/format.js +18 -4
- package/lib/metrics/constants.js +1 -1
- package/lib/metrics/types/gauge.js +1 -1
- package/lib/middlewares/action-hooks/index.js +59 -11
- package/lib/middlewares/bulkhead/index.js +2 -1
- package/lib/middlewares/cache/index.js +80 -0
- package/lib/middlewares/circuit-breaker/index.js +38 -13
- package/lib/middlewares/index.js +1 -0
- package/lib/middlewares/metrics/index.js +1 -1
- package/lib/middlewares/timeout/index.js +2 -2
- package/lib/middlewares/tracing/index.js +24 -11
- package/lib/middlewares/tracing/tags.js +43 -0
- package/lib/middlewares/validator/index.js +1 -1
- package/lib/registry/{action-endpoint.js → actionEndpoint.js} +0 -0
- package/lib/registry/collections/{action-collection.js → actionCollection.js} +1 -1
- package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +2 -3
- package/lib/registry/collections/{event-collection.js → eventCollection.js} +4 -8
- package/lib/registry/collections/{node-collection.js → nodeCollection.js} +0 -0
- package/lib/registry/collections/{service-collection.js → serviceCollection.js} +1 -1
- package/lib/registry/{event-endpoint.js → eventEndpoint.js} +0 -0
- package/lib/registry/registry.js +9 -22
- package/lib/registry/service/service.js +2 -2
- package/lib/registry/{service-item.js → serviceItem.js} +0 -0
- package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +1 -1
- package/lib/runtime/{init-cache.js → initCache.js} +0 -0
- package/lib/runtime/{init-context-factory.js → initContextFactory.js} +0 -0
- package/lib/runtime/{init-eventbus.js → initEventbus.js} +8 -7
- 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} +0 -0
- package/lib/runtime/{init-registry.js → initRegistry.js} +0 -0
- 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} +0 -0
- 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} +15 -0
- package/lib/transport/adapters/adapters.js +1 -1
- package/lib/transport/adapters/dummy/index.js +2 -2
- 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 +214 -171
- package/lib/transport/errorPayloadFactory.js +18 -0
- package/lib/transport/{message-handlers.js → messageHandlers.js} +91 -22
- package/lib/transport/messageTypes.js +23 -0
- package/lib/types.js +49 -49
- 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 -1334
- package/lib/cache/memory.js +0 -121
- package/lib/middlewares/tracing/buildTags.js +0 -17
- package/lib/new-errors.js +0 -25
- 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
|
@@ -8,7 +8,19 @@ function callHook (hook, service, context, result) {
|
|
|
8
8
|
if (typeof hook === 'function') {
|
|
9
9
|
return hook.call(service, context, result)
|
|
10
10
|
} else if (Array.isArray(hook)) {
|
|
11
|
-
return hook.reduce(
|
|
11
|
+
return hook.reduce(
|
|
12
|
+
(promise, fn) => promise.then(res => fn.call(service, context, res)),
|
|
13
|
+
Promise.resolve(result))
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function callErrorHook (hook, service, context, error) {
|
|
18
|
+
if (typeof hook === 'function') {
|
|
19
|
+
return hook.call(service, context, error)
|
|
20
|
+
} else if (Array.isArray(hook)) {
|
|
21
|
+
return hook.reduce(
|
|
22
|
+
(promise, fn) => promise.catch(err => fn.call(service, context, err)),
|
|
23
|
+
Promise.reject(error))
|
|
12
24
|
}
|
|
13
25
|
}
|
|
14
26
|
|
|
@@ -19,6 +31,7 @@ function sanitizeHooks (hooks, service) {
|
|
|
19
31
|
|
|
20
32
|
if (Array.isArray(hooks)) {
|
|
21
33
|
return hooks.map((hook) => {
|
|
34
|
+
// resolve the method name
|
|
22
35
|
if (typeof hook === 'string') {
|
|
23
36
|
return (service && typeof service[hook] === 'function') ? service[hook] : null
|
|
24
37
|
}
|
|
@@ -32,15 +45,33 @@ const makeActionHookMiddleware = function (handler, action) {
|
|
|
32
45
|
const name = action.shortName
|
|
33
46
|
const hooks = (action.service && action.service.schema) ? action.service.schema.hooks : null
|
|
34
47
|
|
|
35
|
-
if (hooks) {
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
if (hooks || action.hooks) {
|
|
49
|
+
// Wildcard hooks
|
|
50
|
+
const beforeWildcardHook = hooks && hooks.before ? sanitizeHooks(hooks.before['*'], action.service) : null
|
|
51
|
+
const afterWildcardHook = hooks && hooks.after ? sanitizeHooks(hooks.after['*'], action.service) : null
|
|
52
|
+
const errorWildcardHook = hooks && hooks.error ? sanitizeHooks(hooks.error['*'], action.service) : null
|
|
53
|
+
|
|
54
|
+
// Action name-related hooks
|
|
55
|
+
const beforeHook = hooks && hooks.before ? sanitizeHooks(hooks.before[name], action.service) : null
|
|
56
|
+
const afterHook = hooks && hooks.after ? sanitizeHooks(hooks.after[name], action.service) : null
|
|
57
|
+
const errorHook = hooks && hooks.error ? sanitizeHooks(hooks.error[name], action.service) : null
|
|
42
58
|
|
|
43
|
-
|
|
59
|
+
// Hooks in action definition
|
|
60
|
+
const actionBeforeHook = action.hooks && action.hooks.before ? sanitizeHooks(action.hooks.before, action.service) : null
|
|
61
|
+
const actionAfterHook = action.hooks && action.hooks.after ? sanitizeHooks(action.hooks.after, action.service) : null
|
|
62
|
+
const actionErrorHook = action.hooks && action.hooks.error ? sanitizeHooks(action.hooks.error, action.service) : null
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
beforeWildcardHook ||
|
|
66
|
+
afterWildcardHook ||
|
|
67
|
+
errorWildcardHook ||
|
|
68
|
+
beforeHook ||
|
|
69
|
+
afterHook ||
|
|
70
|
+
errorHook ||
|
|
71
|
+
actionBeforeHook ||
|
|
72
|
+
actionAfterHook ||
|
|
73
|
+
actionErrorHook
|
|
74
|
+
) {
|
|
44
75
|
return function actionHookMiddleware (context, serviceInjections) {
|
|
45
76
|
let promise = Promise.resolve()
|
|
46
77
|
|
|
@@ -54,9 +85,19 @@ const makeActionHookMiddleware = function (handler, action) {
|
|
|
54
85
|
promise = promise.then(() => callHook(beforeHook, action.service, context))
|
|
55
86
|
}
|
|
56
87
|
|
|
88
|
+
// Before hook
|
|
89
|
+
if (actionBeforeHook) {
|
|
90
|
+
promise = promise.then(() => callHook(actionBeforeHook, action.service, context))
|
|
91
|
+
}
|
|
92
|
+
|
|
57
93
|
// Call action handler
|
|
58
94
|
promise = promise.then(() => handler(context, serviceInjections))
|
|
59
95
|
|
|
96
|
+
// After hook in action definition
|
|
97
|
+
if (actionAfterHook) {
|
|
98
|
+
promise = promise.then(result => callHook(actionAfterHook, action.service, context, result))
|
|
99
|
+
}
|
|
100
|
+
|
|
60
101
|
// After hook
|
|
61
102
|
if (afterHook) {
|
|
62
103
|
promise = promise.then(result => callHook(afterHook, action.service, context, result))
|
|
@@ -67,13 +108,20 @@ const makeActionHookMiddleware = function (handler, action) {
|
|
|
67
108
|
promise = promise.then(result => callHook(afterWildcardHook, action.service, context, result))
|
|
68
109
|
}
|
|
69
110
|
|
|
111
|
+
// Error hooks
|
|
112
|
+
// Error hook in action definition
|
|
113
|
+
if (actionErrorHook) {
|
|
114
|
+
promise = promise.catch(error => callErrorHook(actionErrorHook, action.service, context, error))
|
|
115
|
+
}
|
|
116
|
+
|
|
70
117
|
// Error hook
|
|
71
118
|
if (errorHook) {
|
|
72
|
-
promise = promise.catch(error =>
|
|
119
|
+
promise = promise.catch(error => callErrorHook(errorHook, action.service, context, error))
|
|
73
120
|
}
|
|
121
|
+
|
|
74
122
|
// Error wildcard hook
|
|
75
123
|
if (errorWildcardHook) {
|
|
76
|
-
promise = promise.catch(error =>
|
|
124
|
+
promise = promise.catch(error => callErrorHook(errorWildcardHook, action.service, context, error))
|
|
77
125
|
}
|
|
78
126
|
|
|
79
127
|
return promise
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* -----
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
const { Constants } = require('../../metrics')
|
|
7
7
|
const { WeaveQueueSizeExceededError } = require('../../errors')
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -81,6 +81,7 @@ module.exports = (runtime) => {
|
|
|
81
81
|
created () {
|
|
82
82
|
if (runtime.options.metrics.enabled) {
|
|
83
83
|
// todo: add bulkhead metrics
|
|
84
|
+
runtime.metrics.register({ type: 'gauge', name: Constants.BULKHEAD_REQUESTS_IN_FLIGHT, description: 'Number of in flight requests.' })
|
|
84
85
|
}
|
|
85
86
|
},
|
|
86
87
|
localAction: wrapBulkheadMiddleware
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const { isObject } = require('@weave-js/utils')
|
|
2
|
+
|
|
3
|
+
module.exports = (runtime) => {
|
|
4
|
+
return {
|
|
5
|
+
localAction: (handler, action) => {
|
|
6
|
+
const cacheOptions = Object.assign(
|
|
7
|
+
isObject(action.cache) ? action.cache : { enabled: !!action.cache },
|
|
8
|
+
runtime.options.cache
|
|
9
|
+
)
|
|
10
|
+
if (cacheOptions.enabled) {
|
|
11
|
+
return function cacheMiddleware (context, serviceInjections) {
|
|
12
|
+
const cache = runtime.cache
|
|
13
|
+
const cacheHashKey = cache.getCachingHash(action.name, context.data, context.meta, action.cache.keys)
|
|
14
|
+
context.isCachedResult = false
|
|
15
|
+
|
|
16
|
+
if (context.meta.$noCache === true) {
|
|
17
|
+
return handler(context, serviceInjections)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (cache.isConnected === false) {
|
|
21
|
+
cache.log('Cache adapter is not connected yet. Call handler...')
|
|
22
|
+
return handler(context, serviceInjections)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (cacheOptions.lock.enabled) {
|
|
26
|
+
let cacheProm
|
|
27
|
+
if (cacheOptions.lock.staleTime && cache.getWithTTl) {
|
|
28
|
+
|
|
29
|
+
} else {
|
|
30
|
+
cacheProm = runtime.cache.get(cacheHashKey)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return cacheProm.then((cachedResult) => {
|
|
34
|
+
if (cachedResult !== null) {
|
|
35
|
+
// Found a cached value. Skip calling handler and return our value
|
|
36
|
+
context.isCachedResult = true
|
|
37
|
+
return cachedResult
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return cache.lock(cacheHashKey).then((release) => {
|
|
41
|
+
return cache.get(cacheHashKey).then(cachedResult => {
|
|
42
|
+
if (cachedResult !== null) {
|
|
43
|
+
// Found a cached value. Skip calling handler and return our value
|
|
44
|
+
context.isCachedResult = true
|
|
45
|
+
return release().then(() => {
|
|
46
|
+
return cachedResult
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return handler(context).then((result) => {
|
|
51
|
+
// Cache the value
|
|
52
|
+
cache.set(cacheHashKey, result, action.cache.ttl).then(() => {
|
|
53
|
+
// release the lock
|
|
54
|
+
release()
|
|
55
|
+
})
|
|
56
|
+
return result
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Not using cache lock
|
|
64
|
+
return runtime.cache.get(cacheHashKey).then((cachedResult) => {
|
|
65
|
+
if (cachedResult !== null) {
|
|
66
|
+
context.isCachedResult = true
|
|
67
|
+
return cachedResult
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return handler(context, serviceInjections).then((result) => {
|
|
71
|
+
runtime.cache.set(cacheHashKey, result, action.cache.ttl)
|
|
72
|
+
return result
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return handler
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
* -----
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
|
+
const {
|
|
7
|
+
CIRCUIT_CLOSED,
|
|
8
|
+
CIRCUIT_HALF_OPENED,
|
|
9
|
+
CIRCUIT_HALF_OPEN_WAITING,
|
|
10
|
+
CIRCUIT_OPENED
|
|
11
|
+
} = require('../../constants').circuitBreakerStates
|
|
6
12
|
|
|
7
13
|
module.exports = (runtime) => {
|
|
8
14
|
const storage = new Map()
|
|
@@ -15,7 +21,7 @@ module.exports = (runtime) => {
|
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
function clearEndpointStore () {
|
|
18
|
-
storage.forEach(item => {
|
|
24
|
+
storage.forEach((item) => {
|
|
19
25
|
if (item.callCounter === 0) {
|
|
20
26
|
storage.delete(item.name)
|
|
21
27
|
return
|
|
@@ -34,7 +40,7 @@ module.exports = (runtime) => {
|
|
|
34
40
|
options,
|
|
35
41
|
callCounter: 0,
|
|
36
42
|
failureCouter: 0,
|
|
37
|
-
state:
|
|
43
|
+
state: CIRCUIT_CLOSED,
|
|
38
44
|
circuitBreakerTimer: null
|
|
39
45
|
}
|
|
40
46
|
storage.set(endpoint.name, item)
|
|
@@ -43,17 +49,17 @@ module.exports = (runtime) => {
|
|
|
43
49
|
return item
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
function
|
|
52
|
+
function onSuccess (item, options) {
|
|
47
53
|
item.callCounter++
|
|
48
54
|
|
|
49
|
-
if (item.state ===
|
|
50
|
-
closeCircuitBreaker(item
|
|
55
|
+
if (item.state === CIRCUIT_HALF_OPENED) {
|
|
56
|
+
closeCircuitBreaker(item)
|
|
51
57
|
} else {
|
|
52
58
|
checkThreshold(item, options)
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
function
|
|
62
|
+
function onFailure (item, options) {
|
|
57
63
|
item.callCounter++
|
|
58
64
|
item.failureCouter++
|
|
59
65
|
|
|
@@ -67,24 +73,36 @@ module.exports = (runtime) => {
|
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
function openCircuitBreaker (item) {
|
|
70
|
-
item.state =
|
|
76
|
+
item.state = CIRCUIT_OPENED
|
|
71
77
|
item.endpoint.state = false
|
|
72
78
|
item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout)
|
|
73
|
-
|
|
79
|
+
item.circuitBreakerTimer.unref()
|
|
74
80
|
log.debug(`Circuit breaker has been opened for endpoint '${item.endpoint.name}'`)
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
function halfOpenCircuitBreaker (item) {
|
|
78
|
-
item.state =
|
|
84
|
+
item.state = CIRCUIT_HALF_OPENED
|
|
79
85
|
item.endpoint.state = true
|
|
80
86
|
|
|
81
87
|
log.debug(`Circuit breaker has been half opened for endpoint '${item.endpoint.name}'`)
|
|
88
|
+
|
|
89
|
+
if (item.circuitBreakerTimer) {
|
|
90
|
+
clearTimeout(item.circuitBreakerTimer)
|
|
91
|
+
item.circuitBreakerTimer = null
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
94
|
|
|
84
|
-
function
|
|
95
|
+
function handleHalfOpen (item) {
|
|
96
|
+
item.state = CIRCUIT_HALF_OPEN_WAITING
|
|
97
|
+
item.endpoint.state = false
|
|
98
|
+
item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout)
|
|
99
|
+
item.circuitBreakerTimer.unref()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function closeCircuitBreaker (item) {
|
|
85
103
|
item.failureCouter = 0
|
|
86
104
|
item.callCounter = 0
|
|
87
|
-
item.state =
|
|
105
|
+
item.state = CIRCUIT_CLOSED
|
|
88
106
|
item.endpoint.state = true
|
|
89
107
|
|
|
90
108
|
if (item.circuitBreakerTimer) {
|
|
@@ -103,15 +121,22 @@ module.exports = (runtime) => {
|
|
|
103
121
|
const endpoint = context.endpoint
|
|
104
122
|
const item = getEndpointState(endpoint, options)
|
|
105
123
|
|
|
124
|
+
// handle half open states
|
|
125
|
+
if (item.state === CIRCUIT_HALF_OPENED) {
|
|
126
|
+
handleHalfOpen(item, context)
|
|
127
|
+
}
|
|
128
|
+
|
|
106
129
|
return handler(context, serviceInjections)
|
|
107
130
|
.then(result => {
|
|
108
131
|
const item = getEndpointState(endpoint, options)
|
|
109
|
-
|
|
132
|
+
onSuccess(item, options)
|
|
110
133
|
|
|
111
134
|
return result
|
|
112
135
|
})
|
|
113
136
|
.catch(error => {
|
|
114
|
-
|
|
137
|
+
if (item && (!error.nodeId || error.nodeId === context.nodeId)) {
|
|
138
|
+
onFailure(item, options)
|
|
139
|
+
}
|
|
115
140
|
|
|
116
141
|
return Promise.reject(error)
|
|
117
142
|
})
|
package/lib/middlewares/index.js
CHANGED
|
@@ -33,7 +33,7 @@ module.exports = (runtime) => {
|
|
|
33
33
|
return wrapMetricMiddleware('local', action, next)
|
|
34
34
|
},
|
|
35
35
|
remoteAction (next, action) {
|
|
36
|
-
return wrapMetricMiddleware
|
|
36
|
+
return wrapMetricMiddleware('remote', action, next)
|
|
37
37
|
},
|
|
38
38
|
emit (next) {
|
|
39
39
|
return (event, payload) => {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
const { promiseTimeout } = require('@weave-js/utils')
|
|
8
8
|
const { WeaveRequestTimeoutError } = require('../../errors')
|
|
9
9
|
|
|
10
|
-
const wrapTimeoutMiddleware = function (handler
|
|
10
|
+
const wrapTimeoutMiddleware = function (handler) {
|
|
11
11
|
const self = this
|
|
12
12
|
const registryOptions = self.options.registry || {}
|
|
13
13
|
|
|
@@ -23,7 +23,7 @@ const wrapTimeoutMiddleware = function (handler, action) {
|
|
|
23
23
|
let promise = handler(context, serviceInjections)
|
|
24
24
|
|
|
25
25
|
if (context.options.timeout > 0) {
|
|
26
|
-
promise = promiseTimeout(context.options.timeout, promise, new WeaveRequestTimeoutError(context.action.name, context.nodeId))
|
|
26
|
+
promise = promiseTimeout(context.options.timeout, promise, new WeaveRequestTimeoutError(context.action.name, context.nodeId, context.options.timeout))
|
|
27
27
|
.catch(error => {
|
|
28
28
|
if (error instanceof WeaveRequestTimeoutError) {
|
|
29
29
|
self.log.warn(`Request '${context.action.name}' timed out.`)
|
|
@@ -4,17 +4,22 @@
|
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { isPlainObject } = require('@weave-js/utils')
|
|
8
|
+
const { buildActionTags, buildEventTags } = require('./tags')
|
|
8
9
|
|
|
9
10
|
const wrapTracingLocalActionMiddleware = function (handler) {
|
|
10
11
|
const broker = this
|
|
11
|
-
const
|
|
12
|
+
const tracingOptions = broker.options.tracing || {}
|
|
12
13
|
|
|
13
|
-
if (
|
|
14
|
+
if (tracingOptions.enabled) {
|
|
14
15
|
return function metricsLocalMiddleware (context, serviceInjections) {
|
|
15
|
-
const tags =
|
|
16
|
+
const tags = buildActionTags(context, tracingOptions)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
if (tracingOptions) {
|
|
19
|
+
tags.data = context.data !== null && isPlainObject(context.data) ? Object.assign({}, context.data) : context.data
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const spanName = `action "${context.action.name}"`
|
|
18
23
|
|
|
19
24
|
const span = context.startSpan(spanName, {
|
|
20
25
|
id: context.id,
|
|
@@ -30,6 +35,15 @@ const wrapTracingLocalActionMiddleware = function (handler) {
|
|
|
30
35
|
|
|
31
36
|
return handler(context, serviceInjections)
|
|
32
37
|
.then(result => {
|
|
38
|
+
const tags = {
|
|
39
|
+
isCachedResult: context.isCachedResult
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (tracingOptions) {
|
|
43
|
+
tags.response = result !== null && isPlainObject(result) ? Object.assign({}, result) : result
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
span.addTags(tags)
|
|
33
47
|
span.finish()
|
|
34
48
|
return result
|
|
35
49
|
})
|
|
@@ -47,13 +61,13 @@ const wrapTracingLocalActionMiddleware = function (handler) {
|
|
|
47
61
|
const wrapTracingLocalEventMiddleware = function (handler, event) {
|
|
48
62
|
const broker = this
|
|
49
63
|
const service = event.service
|
|
50
|
-
const
|
|
64
|
+
const tracingOptions = broker.options.tracing || {}
|
|
51
65
|
|
|
52
|
-
if (
|
|
66
|
+
if (tracingOptions.enabled) {
|
|
53
67
|
return function metricsLocalMiddleware (context) {
|
|
54
|
-
const tags =
|
|
68
|
+
const tags = buildEventTags(context)
|
|
55
69
|
|
|
56
|
-
const span = context.startSpan(`event
|
|
70
|
+
const span = context.startSpan(`event "${context.eventName}"`, {
|
|
57
71
|
id: context.id,
|
|
58
72
|
traceId: context.requestId,
|
|
59
73
|
parentId: context.parentId,
|
|
@@ -67,7 +81,6 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
|
|
|
67
81
|
|
|
68
82
|
return handler(context)
|
|
69
83
|
.then(result => {
|
|
70
|
-
span.addTags(tags)
|
|
71
84
|
span.finish()
|
|
72
85
|
return result
|
|
73
86
|
})
|
|
@@ -82,7 +95,7 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
|
|
|
82
95
|
return handler
|
|
83
96
|
}
|
|
84
97
|
|
|
85
|
-
module.exports = (
|
|
98
|
+
module.exports = () => {
|
|
86
99
|
return {
|
|
87
100
|
localAction: wrapTracingLocalActionMiddleware,
|
|
88
101
|
localEvent: wrapTracingLocalEventMiddleware
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../../types.js").Context} Context
|
|
3
|
+
* @typedef {import("../../types.js").TracingOptions} TracingOptions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Build span tags object
|
|
8
|
+
* @param {Context} context - Context
|
|
9
|
+
* @param {TracingOptions} brokerTracingOptions - Tracing options
|
|
10
|
+
* @param {TracingOptions} actionTracingOptions - Tracing options
|
|
11
|
+
* @returns {object} Tags
|
|
12
|
+
*/
|
|
13
|
+
module.exports.buildActionTags = (context, brokerTracingOptions, actionTracingOptions) => {
|
|
14
|
+
const tags = {
|
|
15
|
+
requestLevel: context.level,
|
|
16
|
+
action: context.action ? { name: context.action.name, shortName: context.action.shortName } : null,
|
|
17
|
+
isRemoteCall: !!context.callerNodeId,
|
|
18
|
+
nodeId: context.nodeId,
|
|
19
|
+
requestId: context.requestId
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return tags
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Build span tags object
|
|
27
|
+
* @param {Context} context - Context
|
|
28
|
+
* @param {TracingOptions} brokerTracingOptions - Tracing options
|
|
29
|
+
* @param {TracingOptions} actionTracingOptions - Tracing options
|
|
30
|
+
* @returns {object} Tags
|
|
31
|
+
*/
|
|
32
|
+
module.exports.buildEventTags = (context, brokerTracingOptions, actionTracingOptions) => {
|
|
33
|
+
const tags = {
|
|
34
|
+
requestLevel: context.level,
|
|
35
|
+
event: context.eventName,
|
|
36
|
+
eventType: context.eventType,
|
|
37
|
+
isRemoteCall: !!context.callerNodeId,
|
|
38
|
+
nodeId: context.nodeId,
|
|
39
|
+
requestId: context.requestId
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return tags
|
|
43
|
+
}
|
|
@@ -16,7 +16,7 @@ const { capitalize } = require('@weave-js/utils')
|
|
|
16
16
|
* Create validator middleware
|
|
17
17
|
* @param {Runtime} runtime - Runtime reference
|
|
18
18
|
* @returns {Middleware} - Validator middleware
|
|
19
|
-
|
|
19
|
+
*/
|
|
20
20
|
module.exports = (runtime) => {
|
|
21
21
|
const validator = runtime.validator
|
|
22
22
|
|
|
File without changes
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @typedef {import('../../types.js').ServiceActionCollection} ServiceActionCollection
|
|
12
12
|
*/
|
|
13
13
|
const { omit } = require('@weave-js/utils')
|
|
14
|
-
const { createEndpointList } = require('./
|
|
14
|
+
const { createEndpointList } = require('./endpointCollection')
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Configuration object for weave service broker.
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* @typedef {import('../../types.js').EndpointCollection} EndpointCollection
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
const { createActionEndpoint } = require('../
|
|
17
|
+
const { createActionEndpoint } = require('../actionEndpoint')
|
|
18
18
|
const { loadBalancingStrategy } = require('../../constants')
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
*
|
|
22
22
|
* @param {Runtime} runtime Runtime instance
|
|
23
23
|
* @param {string} name name
|
|
24
|
-
* @param {string} groupName Group name
|
|
24
|
+
* @param {string=} groupName Group name
|
|
25
25
|
* @returns {EndpointCollection} EndpointCollection
|
|
26
26
|
*/
|
|
27
27
|
exports.createEndpointList = (runtime, name, groupName) => {
|
|
@@ -33,7 +33,6 @@ exports.createEndpointList = (runtime, name, groupName) => {
|
|
|
33
33
|
|
|
34
34
|
let counter = 0
|
|
35
35
|
|
|
36
|
-
endpointList.state = runtime // ????
|
|
37
36
|
endpointList.name = name
|
|
38
37
|
endpointList.groupName = groupName
|
|
39
38
|
endpointList.isInternal = name.startsWith('$')
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const { omit, match } = require('@weave-js/utils')
|
|
18
|
-
const { createEndpointList } = require('./
|
|
18
|
+
const { createEndpointList } = require('./endpointCollection')
|
|
19
19
|
|
|
20
20
|
const broadcastEvents = ['broadcast', 'localBroadcast']
|
|
21
21
|
/**
|
|
@@ -51,7 +51,7 @@ exports.createEventCollection = (registry) => {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
eventCollection.remove = (node, eventName) => {
|
|
54
|
-
events.map(list => {
|
|
54
|
+
events.map((list) => {
|
|
55
55
|
if (list.name === eventName) {
|
|
56
56
|
list.removeByNodeId(node.id)
|
|
57
57
|
}
|
|
@@ -59,7 +59,7 @@ exports.createEventCollection = (registry) => {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
eventCollection.removeByService = (service) => {
|
|
62
|
-
events.map(list => {
|
|
62
|
+
events.map((list) => {
|
|
63
63
|
list.removeByService(service)
|
|
64
64
|
})
|
|
65
65
|
}
|
|
@@ -67,7 +67,7 @@ exports.createEventCollection = (registry) => {
|
|
|
67
67
|
eventCollection.getBalancedEndpoints = (eventName, groups) => {
|
|
68
68
|
const result = []
|
|
69
69
|
getAllEventsByEventName(eventName)
|
|
70
|
-
.forEach(endpointList => {
|
|
70
|
+
.forEach((endpointList) => {
|
|
71
71
|
if (groups == null || groups.length === 0 || groups.indexOf(endpointList.groupName) !== -1) {
|
|
72
72
|
const endpoint = endpointList.getNextAvailableEndpoint()
|
|
73
73
|
if (endpoint && endpoint.isAvailable()) {
|
|
@@ -75,10 +75,6 @@ exports.createEventCollection = (registry) => {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
})
|
|
78
|
-
// .filter(endpointList => (groups == null || groups.length === 0 || groups.includes(endpointList.groupName)))
|
|
79
|
-
// .map(endpointList => ({ endpoint: endpointList.getNextAvailableEndpoint(), endpointList }))
|
|
80
|
-
// .filter(({ endpoint }) => endpoint && endpoint.isAvailable())
|
|
81
|
-
// .map(({ endpoint, endpointList }) => [endpoint, endpointList.groupName])
|
|
82
78
|
return result
|
|
83
79
|
}
|
|
84
80
|
|
|
File without changes
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
// const { createEndpointCollection } = require('./endpoint-collection')
|
|
15
15
|
const { omit, remove } = require('@weave-js/utils')
|
|
16
|
-
const { createServiceItem } = require('../
|
|
16
|
+
const { createServiceItem } = require('../serviceItem')
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Service collection factory
|
|
File without changes
|
package/lib/registry/registry.js
CHANGED
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
const { safeCopy } = require('@weave-js/utils')
|
|
22
22
|
|
|
23
23
|
// own packages
|
|
24
|
-
const { createNodeCollection } = require('./collections/
|
|
25
|
-
const { createServiceCollection } = require('./collections/
|
|
26
|
-
const { createActionCollection } = require('./collections/
|
|
27
|
-
const { createEventCollection } = require('./collections/
|
|
28
|
-
const { createActionEndpoint } = require('./
|
|
24
|
+
const { createNodeCollection } = require('./collections/nodeCollection')
|
|
25
|
+
const { createServiceCollection } = require('./collections/serviceCollection')
|
|
26
|
+
const { createActionCollection } = require('./collections/actionCollection')
|
|
27
|
+
const { createEventCollection } = require('./collections/eventCollection')
|
|
28
|
+
const { createActionEndpoint } = require('./actionEndpoint')
|
|
29
29
|
const { createNode } = require('./node')
|
|
30
30
|
const { WeaveServiceNotFoundError, WeaveServiceNotAvailableError } = require('../errors')
|
|
31
31
|
|
|
@@ -47,24 +47,12 @@ exports.createRegistry = (runtime) => {
|
|
|
47
47
|
log: runtime.createLogger('REGISTRY'),
|
|
48
48
|
/**
|
|
49
49
|
* Initialize the registry
|
|
50
|
-
* @param {
|
|
50
|
+
* @param {Runtime} runtime Runtime
|
|
51
51
|
* @param {MiddlewareHandler} middlewareHandler Middleware handler
|
|
52
52
|
* @param {ServiceChangedDelegate} serviceChanged Service changed delegate
|
|
53
53
|
* @returns {void}
|
|
54
54
|
*/
|
|
55
55
|
init (runtime) {
|
|
56
|
-
/**
|
|
57
|
-
* @type {Broker}
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @type {MiddlewareHandler}
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @type {ServiceChangedDelegate}
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
56
|
// init collections
|
|
69
57
|
this.nodeCollection = createNodeCollection(this)
|
|
70
58
|
this.serviceCollection = createServiceCollection(this)
|
|
@@ -141,7 +129,6 @@ exports.createRegistry = (runtime) => {
|
|
|
141
129
|
}
|
|
142
130
|
|
|
143
131
|
if (oldActions) {
|
|
144
|
-
// this.deregisterAction()
|
|
145
132
|
Object.keys(oldActions).forEach(actionName => {
|
|
146
133
|
if (!service.actions[actionName]) {
|
|
147
134
|
this.actionCollection.remove(actionName, node)
|
|
@@ -201,7 +188,7 @@ exports.createRegistry = (runtime) => {
|
|
|
201
188
|
if (node.isLocal) {
|
|
202
189
|
action.handler = middlewareHandler.wrapHandler('localAction', action.handler, action)// this.onRegisterLocalAction(action)
|
|
203
190
|
} else {
|
|
204
|
-
action.handler = middlewareHandler.wrapHandler('remoteAction', runtime.transport.
|
|
191
|
+
action.handler = middlewareHandler.wrapHandler('remoteAction', runtime.transport.sendRequest.bind(runtime.transport), action)// this.onRegisterRemoteAction(action)
|
|
205
192
|
}
|
|
206
193
|
|
|
207
194
|
this.actionCollection.add(node, service, action)
|
|
@@ -369,9 +356,9 @@ exports.createRegistry = (runtime) => {
|
|
|
369
356
|
}
|
|
370
357
|
|
|
371
358
|
// todo: Handle multiple nodes with the same ID.
|
|
372
|
-
const
|
|
359
|
+
const updateNecessary = node.update(payload, isReconnected)
|
|
373
360
|
|
|
374
|
-
if (
|
|
361
|
+
if (updateNecessary && node.services) {
|
|
375
362
|
this.registerRemoteServices(node, node.services)
|
|
376
363
|
}
|
|
377
364
|
|