@weave-js/core 0.10.0 → 0.12.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 (132) hide show
  1. package/.eslintrc.js +1 -1
  2. package/jest.config.js +1 -1
  3. package/lib/ExtendableError.js +33 -0
  4. package/lib/broker/context.js +58 -46
  5. package/lib/broker/{default-options.js → defaultOptions.js} +31 -13
  6. package/lib/broker/index.js +273 -251
  7. package/lib/buildRuntime.js +70 -0
  8. package/lib/cache/adapters/base.js +119 -0
  9. package/lib/cache/adapters/inMemory.js +154 -0
  10. package/lib/cache/adapters/inMemoryLru.js +140 -0
  11. package/lib/cache/adapters/index.js +10 -0
  12. package/lib/cache/getCacheKeyByObject.js +31 -0
  13. package/lib/cache/getPropertyFromDataOrMetadata.js +20 -0
  14. package/lib/cache/lock.js +34 -11
  15. package/lib/constants.js +11 -8
  16. package/lib/{error-handler.js → errorHandler.js} +8 -8
  17. package/lib/errors.js +46 -39
  18. package/lib/helper/{define-action.js → defineAction.js} +5 -3
  19. package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +4 -2
  20. package/lib/helper/{define-service.js → defineService.js} +6 -3
  21. package/lib/index.js +25 -22
  22. package/lib/logger/base.js +38 -29
  23. package/lib/logger/format/asHumanReadable.js +15 -14
  24. package/lib/logger/format/asJson.js +10 -10
  25. package/lib/logger/format/index.js +3 -3
  26. package/lib/logger/index.js +28 -25
  27. package/lib/logger/levels.js +23 -22
  28. package/lib/logger/tools.js +17 -13
  29. package/lib/logger/utils/colorize.js +23 -23
  30. package/lib/logger/utils/format.js +89 -65
  31. package/lib/metrics/common.js +47 -47
  32. package/lib/metrics/constants.js +44 -44
  33. package/lib/metrics/exporter/base.js +8 -8
  34. package/lib/metrics/exporter/event.js +20 -20
  35. package/lib/metrics/exporter/index.js +15 -15
  36. package/lib/metrics/index.js +2 -2
  37. package/lib/metrics/types/base.js +20 -20
  38. package/lib/metrics/types/counter.js +6 -6
  39. package/lib/metrics/types/gauge.js +24 -24
  40. package/lib/metrics/types/histogram.js +26 -26
  41. package/lib/metrics/types/index.js +6 -6
  42. package/lib/metrics/types/info.js +17 -17
  43. package/lib/middlewares/action-hooks/index.js +82 -34
  44. package/lib/middlewares/bulkhead/index.js +34 -33
  45. package/lib/middlewares/cache/index.js +106 -0
  46. package/lib/middlewares/circuit-breaker/index.js +85 -60
  47. package/lib/middlewares/context-tracker/index.js +39 -39
  48. package/lib/middlewares/error-handler/index.js +14 -14
  49. package/lib/middlewares/index.js +3 -2
  50. package/lib/middlewares/metrics/getMiddlewareWrapper.js +17 -17
  51. package/lib/middlewares/metrics/index.js +29 -29
  52. package/lib/middlewares/retry/index.js +15 -15
  53. package/lib/middlewares/timeout/index.js +18 -18
  54. package/lib/middlewares/tracing/index.js +50 -37
  55. package/lib/middlewares/tracing/tags.js +43 -0
  56. package/lib/middlewares/validator/index.js +32 -32
  57. package/lib/registry/{action-endpoint.js → actionEndpoint.js} +8 -8
  58. package/lib/registry/collections/{action-collection.js → actionCollection.js} +39 -35
  59. package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +64 -65
  60. package/lib/registry/collections/{event-collection.js → eventCollection.js} +65 -69
  61. package/lib/registry/collections/{node-collection.js → nodeCollection.js} +45 -45
  62. package/lib/registry/collections/{service-collection.js → serviceCollection.js} +61 -55
  63. package/lib/registry/eventEndpoint.js +26 -0
  64. package/lib/registry/load-balancer/base.js +3 -3
  65. package/lib/registry/load-balancer/index.js +7 -7
  66. package/lib/registry/node.js +27 -27
  67. package/lib/registry/registry.js +147 -163
  68. package/lib/registry/service/parseAction.js +16 -16
  69. package/lib/registry/service/parseEvent.js +18 -18
  70. package/lib/registry/service/reduceMixins.js +10 -10
  71. package/lib/registry/service/service.js +72 -72
  72. package/lib/registry/{service-item.js → serviceItem.js} +21 -21
  73. package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +21 -21
  74. package/lib/runtime/initCache.js +19 -0
  75. package/lib/runtime/{init-context-factory.js → initContextFactory.js} +22 -22
  76. package/lib/runtime/{init-eventbus.js → initEventbus.js} +54 -53
  77. package/lib/runtime/{init-logger.js → initLogger.js} +11 -11
  78. package/lib/runtime/{init-metrics.js → initMetrics.js} +55 -54
  79. package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +21 -21
  80. package/lib/runtime/{init-registry.js → initRegistry.js} +6 -6
  81. package/lib/runtime/initServiceManager.js +145 -0
  82. package/lib/runtime/{init-tracing.js → initTracing.js} +25 -24
  83. package/lib/runtime/{init-transport.js → initTransport.js} +5 -5
  84. package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +4 -4
  85. package/lib/runtime/{init-validator.js → initValidator.js} +5 -5
  86. package/lib/tracing/collectors/base.js +29 -37
  87. package/lib/tracing/collectors/event.js +33 -33
  88. package/lib/tracing/collectors/index.js +16 -16
  89. package/lib/tracing/span.js +34 -32
  90. package/lib/tracing/time.js +8 -8
  91. package/lib/transport/InboundTransformStream.js +75 -0
  92. package/lib/transport/adapters/adapteBase.js +107 -0
  93. package/lib/transport/adapters/adapters.js +4 -4
  94. package/lib/transport/adapters/dummy/index.js +19 -19
  95. package/lib/transport/adapters/fromURI.js +13 -13
  96. package/lib/transport/adapters/getAdapterByName.js +5 -5
  97. package/lib/transport/adapters/index.js +12 -12
  98. package/lib/transport/adapters/tcp/discovery/codec.js +4 -4
  99. package/lib/transport/adapters/tcp/discovery/index.js +90 -76
  100. package/lib/transport/adapters/tcp/index.js +180 -175
  101. package/lib/transport/adapters/tcp/tcp-messagetypes.js +7 -7
  102. package/lib/transport/adapters/tcp/tcpReader.js +39 -38
  103. package/lib/transport/adapters/tcp/tcpWriteStream.js +26 -26
  104. package/lib/transport/adapters/tcp/tcpWriter.js +58 -58
  105. package/lib/transport/adapters/tcp/utils.js +12 -12
  106. package/lib/transport/createMessage.js +11 -0
  107. package/lib/transport/createTransport.js +377 -334
  108. package/lib/transport/errorPayloadFactory.js +15 -0
  109. package/lib/transport/messageHandlers.js +517 -0
  110. package/lib/transport/messageTypes.js +23 -0
  111. package/lib/types.js +95 -71
  112. package/lib/utils/index.js +2 -2
  113. package/lib/utils/options.js +47 -45
  114. package/lib/utils/{restore-error.js → restoreError.js} +4 -4
  115. package/package.json +6 -12
  116. package/CHANGELOG.md +0 -1334
  117. package/lib/build-runtime.js +0 -70
  118. package/lib/cache/base.js +0 -142
  119. package/lib/cache/index.js +0 -48
  120. package/lib/cache/memory.js +0 -121
  121. package/lib/middlewares/tracing/buildTags.js +0 -17
  122. package/lib/new-errors.js +0 -25
  123. package/lib/registry/event-endpoint.js +0 -26
  124. package/lib/runtime/init-cache.js +0 -10
  125. package/lib/runtime/init-service-manager.js +0 -128
  126. package/lib/tracing/collectors/console.js +0 -34
  127. package/lib/tracing/index.js +0 -3
  128. package/lib/tracing/tracer.js +0 -64
  129. package/lib/transport/adapters/adapter-base.js +0 -92
  130. package/lib/transport/message-handlers.js +0 -448
  131. package/lib/transport/message-types.js +0 -59
  132. package/lib/transport/message.js +0 -16
@@ -1,70 +0,0 @@
1
- /**
2
- * @typedef {import('./types.js').BrokerOptions} BrokerOptions
3
- * @typedef {import('./types.js').Runtime} Runtime
4
- * @typedef {import('./types.js').Broker} Broker
5
- */
6
-
7
- const { initLogger } = require('./runtime/init-logger')
8
- const { initMiddlewareHandler } = require('./runtime/init-middleware-manager')
9
- const { initRegistry } = require('./runtime/init-registry')
10
- const { initContextFactory } = require('./runtime/init-context-factory')
11
- const { initEventbus } = require('./runtime/init-eventbus')
12
- const { initValidator } = require('./runtime/init-validator')
13
- const { initTransport } = require('./runtime/init-transport')
14
- const { initCache } = require('./runtime/init-cache')
15
- const { initActionInvoker } = require('./runtime/init-action-invoker')
16
- const { initServiceManager } = require('./runtime/init-service-manager')
17
- const { initMetrics } = require('./runtime/init-metrics')
18
- const { initTracer } = require('./runtime/init-tracing')
19
- const { initUUIDFactory } = require('./runtime/init-uuid-factory')
20
- const { version } = require('../package.json')
21
- const { errorHandler, fatalErrorHandler } = require('./error-handler')
22
- const EventEmitter = require('eventemitter2')
23
- const { uuid } = require('@weave-js/utils')
24
-
25
- /**
26
- * Build runtime object
27
- * @param {BrokerOptions} options Broker options
28
- * @return {Runtime} Runtime
29
- */
30
- exports.buildRuntime = (options) => {
31
- /**
32
- * Event bus
33
- * @returns {EventEmitter} Service object.
34
- */
35
- const bus = new EventEmitter({
36
- wildcard: true,
37
- maxListeners: 1000
38
- })
39
-
40
- // Create base runtime object
41
- const runtime = {
42
- nodeId: options.nodeId,
43
- version,
44
- options,
45
- bus,
46
- state: {
47
- instanceId: uuid(),
48
- isStarted: false
49
- },
50
- handleError: (error) => errorHandler(runtime, error),
51
- fatalError: (message, error, killProcess) => fatalErrorHandler(runtime, message, error, killProcess)
52
- }
53
-
54
- // Init modules
55
- initLogger(runtime)
56
- initUUIDFactory(runtime)
57
- initMiddlewareHandler(runtime)
58
- initRegistry(runtime)
59
- initContextFactory(runtime)
60
- initEventbus(runtime)
61
- initValidator(runtime)
62
- initTransport(runtime)
63
- initCache(runtime)
64
- initActionInvoker(runtime)
65
- initServiceManager(runtime)
66
- initMetrics(runtime)
67
- initTracer(runtime)
68
-
69
- return runtime
70
- }
package/lib/cache/base.js DELETED
@@ -1,142 +0,0 @@
1
- /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
3
- * -----
4
- * Copyright 2021 Fachwerk
5
- */
6
- const crypto = require('crypto')
7
- const { isObject } = require('@weave-js/utils')
8
- const Constants = require('../metrics/constants')
9
-
10
- function getCacheKeyByObject (val) {
11
- if (Array.isArray(val)) {
12
- return val.map(object => getCacheKeyByObject(object)).join('/')
13
- } else if (isObject(val)) {
14
- return Object.keys(val).map(key => {
15
- return [key, getCacheKeyByObject(val[key])].join('/')
16
- }).join('/')
17
- } else if (val !== null) {
18
- return val.toString()
19
- } else {
20
- return 'null'
21
- }
22
- }
23
-
24
- function generateHash (key) {
25
- return crypto
26
- .createHash('sha1')
27
- .update(key)
28
- .digest('base64')
29
- }
30
-
31
- function registerCacheMetrics (metrics) {
32
- metrics.register({ type: 'counter', name: Constants.CACHE_GET_TOTAL })
33
- metrics.register({ type: 'counter', name: Constants.CACHE_SET_TOTAL })
34
- metrics.register({ type: 'counter', name: Constants.CACHE_FOUND_TOTAL })
35
- metrics.register({ type: 'counter', name: Constants.CACHE_EXPIRED_TOTAL })
36
- metrics.register({ type: 'counter', name: Constants.CACHE_DELETED_TOTAL })
37
- metrics.register({ type: 'counter', name: Constants.CACHE_CLEANED_TOTAL })
38
- }
39
-
40
- exports.createCacheBase = (runtime, options) => {
41
- const cache = {
42
- runtime,
43
- options,
44
- options: Object.assign({
45
- ttl: null
46
- }, options),
47
- init () {
48
- // register metrics
49
- if (runtime.metrics) {
50
- this.metrics = runtime.metrics
51
- registerCacheMetrics(runtime.metrics)
52
- }
53
- },
54
- log: runtime.createLogger('CACHER'),
55
- set (/* hashKey, result, ttl */) {
56
- /* istanbul ignore next */
57
- runtime.handleError(new Error('Method not implemented.'))
58
- },
59
- get (/* hashKey */) {
60
- /* istanbul ignore next */
61
- runtime.handleError(new Error('Method not implemented.'))
62
- },
63
- remove () {
64
- /* istanbul ignore next */
65
- runtime.handleError(new Error('Method not implemented.'))
66
- },
67
- clear () {
68
- /* istanbul ignore next */
69
- runtime.handleError(new Error('Method not implemented.'))
70
- },
71
- stop () {
72
- /* istanbul ignore next */
73
- return Promise.resolve()
74
- },
75
- getCachingHash (actionName, params, meta, keys) {
76
- if (params || meta) {
77
- const prefix = `${actionName}:`
78
-
79
- if (keys) {
80
- if (keys.length === 1) {
81
- const value = params[keys[0]]
82
- const key = getCacheKeyByObject(value)
83
- return prefix + (isObject(value) ? key : value)
84
- }
85
-
86
- if (keys.length > 0) {
87
- const res = keys.reduce((pre, property, i) => {
88
- const value = params[property]
89
- let hash
90
- if (isObject(value)) {
91
- const key = getCacheKeyByObject(value)
92
- hash = generateHash(key)
93
- } else {
94
- hash = value
95
- }
96
-
97
- return pre + (i > 0 ? '|' : '') + hash
98
- }, prefix)
99
- return res
100
- }
101
- } else {
102
- return prefix + generateHash(getCacheKeyByObject(params))
103
- }
104
- }
105
-
106
- return actionName
107
- }
108
- }
109
-
110
- cache.middleware = () => {
111
- return {
112
- localAction: (handler, action) => {
113
- const cacheOptions = Object.assign({ enabled: true }, isObject(action.cache) ? action.cache : { enabled: !!action.cache })
114
- if (cacheOptions.enabled) {
115
- return function cacheMiddleware (context, serviceInjections) {
116
- const cacheHashKey = cache.getCachingHash(action.name, context.data, context.meta, action.cache.keys)
117
- context.isCachedResult = false
118
-
119
- if (context.meta.$noCache === true) {
120
- return handler(context, serviceInjections)
121
- }
122
-
123
- return cache.get(cacheHashKey).then((content) => {
124
- if (content !== null) {
125
- context.isCachedResult = true
126
- return content
127
- }
128
-
129
- return handler(context, serviceInjections).then((result) => {
130
- cache.set(cacheHashKey, result, action.cache.ttl)
131
- return result
132
- })
133
- })
134
- }
135
- }
136
- return handler
137
- }
138
- }
139
- }
140
-
141
- return cache
142
- }
@@ -1,48 +0,0 @@
1
- /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
3
- * -----
4
- * Copyright 2021 Fachwerk
5
- */
6
-
7
- const { isString, isFunction } = require('@weave-js/utils')
8
- const { WeaveBrokerOptionsError } = require('../errors')
9
-
10
- const adapters = {
11
- Memory: require('./memory')
12
- }
13
-
14
- exports.adapters = adapters
15
-
16
- exports.createCacheBase = require('./base').createCacheBase
17
-
18
- exports.resolve = (cacheOptions) => {
19
- const getByName = name => {
20
- if (!name) {
21
- return null
22
- }
23
-
24
- const n = Object.keys(adapters).find(n => n.toLowerCase() === name.toLowerCase())
25
- if (n) {
26
- return adapters[n]
27
- }
28
- }
29
-
30
- let cacheFactory
31
-
32
- if (cacheOptions === true) {
33
- cacheFactory = this.adapters.Memory
34
- } else if (isString(cacheOptions)) {
35
- const cache = getByName(cacheOptions)
36
-
37
- if (cache) {
38
- cacheFactory = cache
39
- } else {
40
- throw new WeaveBrokerOptionsError(`Unknown cache type "${cacheOptions}"`)
41
- }
42
- } else if (isFunction(cacheOptions)) {
43
- cacheFactory = cacheOptions
44
- }
45
- if (cacheFactory) {
46
- return cacheFactory
47
- }
48
- }
@@ -1,121 +0,0 @@
1
- /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
3
- * -----
4
- * Copyright 2021 Fachwerk
5
- */
6
-
7
- const { match } = require('@weave-js/utils')
8
- const { createCacheBase } = require('./base')
9
- const Constants = require('../metrics/constants')
10
-
11
- const makeMemoryCache = (runtime, options = {}) => {
12
- const base = createCacheBase(runtime, options)
13
- const storage = new Map()
14
- const name = 'Memory'
15
-
16
- const timer = setInterval(() => {
17
- checkTtl()
18
- }, 3000)
19
-
20
- timer.unref()
21
-
22
- // if a new broker gets connected, we need to clear the cache
23
- runtime.bus.on('$transport.connected', () => {
24
- base.log.verbose('Transport adapter connected. Cache will be cleared.')
25
- cache.clear()
26
- })
27
-
28
- const checkTtl = () => {
29
- const now = Date.now()
30
-
31
- storage.forEach((item, hashKey) => {
32
- if (item.expire && item.expire < now) {
33
- cache.log.debug(`Delete ${hashKey}`)
34
- storage.delete(hashKey)
35
- }
36
- })
37
- }
38
-
39
- const cache = Object.assign(base, {
40
- name,
41
- get (cacheKey) {
42
- base.log.debug(`Get ${cacheKey}`)
43
-
44
- if (this.metrics) {
45
- this.metrics.increment(Constants.CACHE_GET_TOTAL)
46
- }
47
-
48
- const item = storage.get(cacheKey)
49
-
50
- if (item) {
51
- cache.log.debug(`Found ${cacheKey}`)
52
-
53
- if (this.metrics) {
54
- this.metrics.increment(Constants.CACHE_FOUND_TOTAL)
55
- }
56
-
57
- // if (options.ttl) {
58
- // item.expire = Date.now()// + options_.ttl
59
- // }
60
-
61
- if (item.expire && item.expire < Date.now()) {
62
- cache.log.debug(`Delete ${cacheKey}`)
63
- storage.delete(cacheKey)
64
- if (this.metrics) {
65
- this.metrics.increment(Constants.CACHE_EXPIRED_TOTAL)
66
- }
67
- return Promise.resolve(null)
68
- }
69
-
70
- return Promise.resolve(item.data)
71
- }
72
- return Promise.resolve(null)
73
- },
74
- set (hashKey, data, ttl) {
75
- if (this.metrics) {
76
- this.metrics.increment(Constants.CACHE_SET_TOTAL)
77
- }
78
-
79
- if (ttl == null) {
80
- ttl = options.ttl
81
- }
82
-
83
- storage.set(hashKey, {
84
- data,
85
- expire: ttl ? Date.now() + ttl : null
86
- })
87
-
88
- base.log.debug(`Set ${hashKey}`)
89
-
90
- return Promise.resolve(data)
91
- },
92
- remove (hashKey) {
93
- if (this.metrics) {
94
- this.metrics.increment(Constants.CACHE_DELETED_TOTAL)
95
- }
96
- storage.delete(hashKey)
97
- base.log.debug(`Delete ${hashKey}`)
98
-
99
- return Promise.resolve()
100
- },
101
- clear (pattern = '**') {
102
- if (this.metrics) {
103
- this.metrics.increment(Constants.CACHE_DELETED_TOTAL)
104
- }
105
- storage.forEach((_, key) => {
106
- if (match(key, pattern)) {
107
- base.log.debug(`Delete ${key}`)
108
- this.remove(key)
109
- }
110
- })
111
- return Promise.resolve()
112
- },
113
- stop () {
114
- clearInterval(timer)
115
- }
116
- })
117
-
118
- return cache
119
- }
120
-
121
- module.exports = makeMemoryCache
@@ -1,17 +0,0 @@
1
- /**
2
- * @typedef {import("../../types.js").Context} Context
3
- */
4
-
5
- /**
6
- * Build span tags object
7
- * @param {Context} context - Context
8
- * @returns {object} Tags
9
- */
10
- module.exports.buildTags = (context) => {
11
- return {
12
- requestLevel: context.level,
13
- action: context.action ? { name: context.action.name, shortName: context.action.shortName } : null,
14
- isRemoteCall: !!context.callerNodeId,
15
- nodeId: context.nodeId
16
- }
17
- }
package/lib/new-errors.js DELETED
@@ -1,25 +0,0 @@
1
- /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
3
- * -----
4
- * Copyright 2021 Fachwerk
5
- */
6
-
7
- const errors = require('@weave-js/errors')
8
-
9
- class RetrieableError extends Error {
10
- constructor () {
11
- super(...arguments)
12
- this.retryable = true
13
- }
14
- }
15
-
16
- module.exports = errors({
17
- WeaveError: { code: 500 },
18
- WeaveRetrieableError: { baseClass: RetrieableError },
19
- WeaveServiceNotFoundError: {}, // retrieable
20
- WeaveServiceNotAvailableError: {},
21
- WeaveRequestTimeoutError: {},
22
- WeaveParameterValidationError: {},
23
- WeaveBrokerOptionsError: {},
24
- WeaveQueueSizeExceededError: {}
25
- })
@@ -1,26 +0,0 @@
1
- /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
3
- * -----
4
- * Copyright 2021 Fachwerk
5
- */
6
-
7
- exports.createEventEndpoint = (broker, node, service, event) => {
8
- const eventEndpoint = Object.create(null)
9
-
10
- eventEndpoint.node = node
11
- eventEndpoint.service = service
12
- eventEndpoint.action = event
13
- eventEndpoint.isLocal = eventEndpoint.node.id === broker.nodeId
14
- eventEndpoint.state = true
15
- eventEndpoint.name = `${node.id}:${event.name}`
16
-
17
- eventEndpoint.updateEvent = (newEvent) => {
18
- eventEndpoint.action = newEvent
19
- }
20
-
21
- eventEndpoint.isAvailable = () => {
22
- return eventEndpoint.state
23
- }
24
-
25
- return eventEndpoint
26
- }
@@ -1,10 +0,0 @@
1
- const Cache = require('../cache')
2
-
3
- exports.initCache = (runtime) => {
4
- if (runtime.options.cache && runtime.options.cache.enabled) {
5
- const createCache = Cache.resolve(runtime.options.cache.adapter)
6
- Object.defineProperty(runtime, 'cache', {
7
- value: createCache(runtime, runtime.options.cache)
8
- })
9
- }
10
- }
@@ -1,128 +0,0 @@
1
- const { createServiceFromSchema } = require('../registry/service/service.js')
2
- const { WeaveError } = require('../errors')
3
- const { debounce } = require('@weave-js/utils')
4
- const fs = require('fs')
5
-
6
- exports.initServiceManager = (runtime) => {
7
- const { options, log, eventBus, transport, state, registry, handleError } = runtime
8
-
9
- // Internal service list
10
- const serviceList = []
11
-
12
- const serviceChanged = (isLocalService = false) => {
13
- // Send local notification.
14
- eventBus.broadcastLocal('$services.changed', { isLocalService })
15
-
16
- // If the service is a local service - send current node information to other nodes
17
- if (state.isStarted && isLocalService && transport) {
18
- transport.sendNodeInfo()
19
- }
20
- }
21
-
22
- const destroyService = (service) => Promise.resolve()
23
- .then(() => service.stop())
24
- .then(() => log.info(`Service "${service.name}" was stopped.`))
25
- .then(() => {
26
- registry.deregisterService(service.name, service.version)
27
- log.info(`Service "${service.name}" was deregistered.`)
28
- // Remove service from service store.
29
- serviceList.splice(serviceList.indexOf(service), 1)
30
- // Fire services changed event
31
- serviceChanged(true)
32
- return Promise.resolve()
33
- })
34
- .catch(error => log.error(error, `Unable to stop service "${service.name}"`))
35
-
36
- // `onServiceFileChanged` only triggered by the file watcher
37
- const onServiceFileChanged = async (service) => {
38
- const filename = service.filename
39
-
40
- // Clear the require cache
41
- Object.keys(require.cache).forEach(key => {
42
- if (key === filename) {
43
- delete require.cache[key]
44
- }
45
- })
46
-
47
- // Service has changed - 1. destroy the service, then reload it
48
- await destroyService(service)
49
- await runtime.broker.loadService(filename)
50
- }
51
-
52
- Object.defineProperty(runtime, 'services', {
53
- value: {
54
- serviceList,
55
- serviceChanged,
56
- createService (schema) {
57
- try {
58
- const newService = createServiceFromSchema(runtime, schema)
59
-
60
- // if the broker is already startet, we need to start the service.
61
- if (runtime.state.isStarted) {
62
- newService.start().catch(error => log.error(`Unable to start service ${newService.name}: ${error}`))
63
- }
64
-
65
- return newService
66
- } catch (error) {
67
- log.error(error)
68
- handleError(error)
69
- }
70
- },
71
- /**
72
- * Wait for services before continuing startup.
73
- * @param {Array.<string>} serviceNames Names of the services
74
- * @param {Number} timeout Time in Miliseconds before the broker stops.
75
- * @param {Number} interval Time in Miliseconds to check for services.
76
- * @returns {Promise} Promise
77
- */
78
- waitForServices (serviceNames, timeout, interval = 500) {
79
- if (!Array.isArray(serviceNames)) {
80
- serviceNames = [serviceNames]
81
- }
82
-
83
- const startTimestamp = Date.now()
84
- return new Promise((resolve, reject) => {
85
- // todo: add timout for service waiter
86
- log.warn(`Waiting for services '${serviceNames.join(',')}'`)
87
-
88
- const serviceCheck = () => {
89
- const count = serviceNames.filter(serviceName => registry.hasService(serviceName))
90
-
91
- log.warn(`${count.length} services of ${serviceNames.length} available. Waiting...`)
92
-
93
- if (count.length === serviceNames.length) {
94
- return resolve()
95
- }
96
-
97
- if (timeout && (Date.now() - startTimestamp) > timeout) {
98
- return reject(new WeaveError('The waiting of the services is interrupted due to a timeout.', 500, 'WAIT_FOR_SERVICE', { services: serviceNames }))
99
- }
100
-
101
- options.waitForServiceInterval = setTimeout(serviceCheck, interval)
102
- }
103
-
104
- serviceCheck()
105
- })
106
- },
107
- /**
108
- * Watch a Service object for changes.
109
- * @param {Service} service Service object
110
- * @return {void}
111
- */
112
- watchService: (service) => {
113
- if (service.filename && onServiceFileChanged) {
114
- // Create debounced service changed reference
115
- const debouncedOnServiceChange = debounce(onServiceFileChanged, 500)
116
-
117
- // Watch file changes
118
- const watcher = fs.watch(service.filename, (eventType, filename) => {
119
- log.info(`The Service ${service.name} has been changed. (${eventType}, ${filename})`)
120
- watcher.close()
121
- debouncedOnServiceChange(service)
122
- })
123
- }
124
- },
125
- destroyService
126
- }
127
- })
128
- }
@@ -1,34 +0,0 @@
1
- /* istanbul ignore file */
2
-
3
- const BaseCollector = require('./base')
4
-
5
- class ConsoleCollector extends BaseCollector {
6
- constructor (options) {
7
- super(options)
8
-
9
- this.options = Object.assign({
10
- events: {
11
- started: '$tracing.trace.span.started',
12
- finished: '$tracing.trace.span.finished'
13
- },
14
- broadcast: false
15
- })
16
- }
17
-
18
- init (broker, tracer) {
19
- super.init(tracer)
20
- this.broker = broker
21
- }
22
-
23
- startedSpan (span) {
24
- // const data = this.generateTracePayload(span)
25
- this.broker.emit(this.options.events.started, span)
26
- }
27
-
28
- finishedSpan (span) {
29
- // const data = this.generateTracePayload(span)
30
- this.broker.emit(this.options.events.finished, span)
31
- }
32
- }
33
-
34
- module.exports = ConsoleCollector
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- Tracer: require('./tracer')
3
- }
@@ -1,64 +0,0 @@
1
- const { resolveCollector } = require('./collectors')
2
- const { createSpan } = require('./span')
3
-
4
- module.exports = () => {
5
- let collectors = []
6
- let samplingCounter = 0
7
-
8
- return {
9
- init (broker, options) {
10
- this.options = options
11
- this.broker = broker
12
- this.log = broker.createLogger('Tracer')
13
- // this.storage = asyncStore()
14
- // this.storage.enable()
15
-
16
- if (options.enabled) {
17
- this.log.info('Tracer initialized.')
18
-
19
- if (options.collectors) {
20
- collectors = options.collectors
21
- .map(entry => {
22
- const initCollector = resolveCollector(broker, entry, this)
23
- // collector.init(this)
24
- return initCollector()
25
- })
26
- }
27
- }
28
- },
29
- async stop () {
30
- if (collectors) {
31
- return await Promise.all(collectors.map(collector => collector.stop()))
32
- }
33
- },
34
- shouldSample (span) {
35
- // check span priority
36
- if (this.options.samplingRate === 0) {
37
- return false
38
- }
39
-
40
- if (this.options.samplingRate === 1) {
41
- return true
42
- }
43
-
44
- if (++samplingCounter * this.options.samplingRate >= 1) {
45
- samplingCounter = 0
46
- return true
47
- }
48
-
49
- return false
50
- },
51
- invokeCollectorMethod (method, args) {
52
- collectors.map(collector => collector[method].apply(collector, args))
53
- },
54
- startSpan (name, options) {
55
- const span = createSpan(this, name, Object.assign({
56
- type: 'custom'
57
- }, options))
58
-
59
- span.start()
60
-
61
- return span
62
- }
63
- }
64
- }