@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.
Files changed (98) hide show
  1. package/lib/ExtendableError.js +33 -0
  2. package/lib/broker/context.js +25 -13
  3. package/lib/broker/{default-options.js → defaultOptions.js} +25 -6
  4. package/lib/broker/index.js +224 -194
  5. package/lib/buildRuntime.js +70 -0
  6. package/lib/cache/adapters/base.js +143 -0
  7. package/lib/cache/adapters/inMemory.js +154 -0
  8. package/lib/cache/adapters/inMemoryLru.js +140 -0
  9. package/lib/cache/adapters/index.js +46 -0
  10. package/lib/cache/base.js +49 -44
  11. package/lib/cache/lock.js +21 -4
  12. package/lib/constants.js +8 -5
  13. package/lib/errorHandler.js +19 -0
  14. package/lib/errors.js +17 -10
  15. package/lib/helper/{define-action.js → defineAction.js} +3 -1
  16. package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +2 -0
  17. package/lib/helper/{define-service.js → defineService.js} +4 -1
  18. package/lib/index.js +17 -92
  19. package/lib/logger/format/asHumanReadable.js +4 -3
  20. package/lib/logger/index.js +7 -1
  21. package/lib/logger/levels.js +8 -7
  22. package/lib/logger/tools.js +4 -0
  23. package/lib/logger/utils/format.js +18 -4
  24. package/lib/metrics/constants.js +8 -6
  25. package/lib/metrics/types/gauge.js +1 -1
  26. package/lib/middlewares/action-hooks/index.js +62 -14
  27. package/lib/middlewares/bulkhead/index.js +5 -4
  28. package/lib/middlewares/cache/index.js +106 -0
  29. package/lib/middlewares/circuit-breaker/index.js +41 -16
  30. package/lib/middlewares/context-tracker/index.js +3 -3
  31. package/lib/middlewares/error-handler/index.js +3 -3
  32. package/lib/middlewares/index.js +2 -1
  33. package/lib/middlewares/metrics/getMiddlewareWrapper.js +2 -2
  34. package/lib/middlewares/metrics/index.js +2 -2
  35. package/lib/middlewares/retry/index.js +11 -10
  36. package/lib/middlewares/timeout/index.js +5 -5
  37. package/lib/middlewares/tracing/index.js +27 -14
  38. package/lib/middlewares/tracing/tags.js +43 -0
  39. package/lib/middlewares/validator/index.js +6 -6
  40. package/lib/registry/{action-endpoint.js → actionEndpoint.js} +0 -0
  41. package/lib/registry/collections/{action-collection.js → actionCollection.js} +2 -2
  42. package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +19 -3
  43. package/lib/registry/collections/{event-collection.js → eventCollection.js} +15 -9
  44. package/lib/registry/collections/{node-collection.js → nodeCollection.js} +1 -1
  45. package/lib/registry/collections/{service-collection.js → serviceCollection.js} +2 -2
  46. package/lib/registry/{event-endpoint.js → eventEndpoint.js} +1 -1
  47. package/lib/registry/node.js +1 -1
  48. package/lib/registry/registry.js +19 -38
  49. package/lib/registry/service/service.js +2 -2
  50. package/lib/registry/{service-item.js → serviceItem.js} +1 -1
  51. package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +3 -3
  52. package/lib/runtime/initCache.js +19 -0
  53. package/lib/runtime/{init-context-factory.js → initContextFactory.js} +2 -2
  54. package/lib/runtime/{init-eventbus.js → initEventbus.js} +11 -10
  55. package/lib/runtime/{init-logger.js → initLogger.js} +0 -0
  56. package/lib/runtime/{init-metrics.js → initMetrics.js} +11 -10
  57. package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +1 -1
  58. package/lib/runtime/{init-registry.js → initRegistry.js} +1 -1
  59. package/lib/runtime/{init-service-manager.js → initServiceManager.js} +0 -0
  60. package/lib/runtime/{init-tracing.js → initTracing.js} +2 -1
  61. package/lib/runtime/{init-transport.js → initTransport.js} +0 -0
  62. package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +0 -0
  63. package/lib/runtime/{init-validator.js → initValidator.js} +1 -1
  64. package/lib/tracing/collectors/base.js +11 -19
  65. package/lib/tracing/collectors/event.js +2 -2
  66. package/lib/tracing/collectors/index.js +2 -2
  67. package/lib/tracing/span.js +8 -6
  68. package/lib/transport/InboundTransformStream.js +75 -0
  69. package/lib/transport/adapters/{adapter-base.js → adapteBase.js} +16 -1
  70. package/lib/transport/adapters/adapters.js +1 -1
  71. package/lib/transport/adapters/dummy/index.js +3 -3
  72. package/lib/transport/adapters/index.js +1 -1
  73. package/lib/transport/adapters/tcp/discovery/index.js +45 -31
  74. package/lib/transport/adapters/tcp/index.js +20 -13
  75. package/lib/transport/adapters/tcp/tcpReader.js +1 -0
  76. package/lib/transport/adapters/tcp/tcpWriteStream.js +1 -1
  77. package/lib/transport/adapters/tcp/tcpWriter.js +2 -2
  78. package/lib/transport/createMessage.js +11 -0
  79. package/lib/transport/createTransport.js +215 -172
  80. package/lib/transport/errorPayloadFactory.js +18 -0
  81. package/lib/transport/{message-handlers.js → messageHandlers.js} +92 -23
  82. package/lib/transport/messageTypes.js +23 -0
  83. package/lib/types.js +86 -75
  84. package/lib/utils/index.js +1 -1
  85. package/lib/utils/options.js +4 -2
  86. package/lib/utils/{restore-error.js → restoreError.js} +1 -1
  87. package/package.json +6 -12
  88. package/CHANGELOG.md +0 -1317
  89. package/lib/cache/index.js +0 -48
  90. package/lib/cache/memory.js +0 -91
  91. package/lib/middlewares/tracing/buildTags.js +0 -17
  92. package/lib/new-errors.js +0 -25
  93. package/lib/runtime/init-cache.js +0 -10
  94. package/lib/tracing/collectors/console.js +0 -34
  95. package/lib/tracing/index.js +0 -3
  96. package/lib/tracing/tracer.js +0 -64
  97. package/lib/transport/message-types.js +0 -59
  98. package/lib/transport/message.js +0 -16
package/lib/cache/lock.js CHANGED
@@ -1,14 +1,31 @@
1
- exports.ttlcreateLock = () => {
1
+ const createLock = () => {
2
2
  const locked = new Map()
3
+
3
4
  return {
4
5
  acquire (key, ttl) {
5
- const lock = locked.get(key)
6
- if (!lock) {
7
- lock.set(key, [])
6
+ const lockedItems = locked.get(key)
7
+ if (!lockedItems) {
8
+ locked.set(key, [])
9
+ return Promise.resolve()
10
+ } else {
11
+ return new Promise((resolve) => lockedItems.push(resolve))
8
12
  }
9
13
  },
10
14
  isLocked (key) {
11
15
  return !!locked.has(key)
16
+ },
17
+ release (key) {
18
+ const lockedItems = locked.get(key)
19
+ if (lockedItems) {
20
+ if (lockedItems.length > 0) {
21
+ lockedItems.shift()()
22
+ } else {
23
+ locked.delete(key)
24
+ }
25
+ }
26
+ return Promise.resolve()
12
27
  }
13
28
  }
14
29
  }
30
+
31
+ module.exports = { createLock }
package/lib/constants.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  exports.PROTOCOL_VERSION = 1
@@ -11,6 +11,13 @@ exports.loadBalancingStrategy = {
11
11
  RANDOM: 'random'
12
12
  }
13
13
 
14
+ exports.circuitBreakerStates = {
15
+ CIRCUIT_CLOSED: 'closed',
16
+ CIRCUIT_HALF_OPENED: 'half_opened',
17
+ CIRCUIT_HALF_OPEN_WAITING: 'half_open_waiting',
18
+ CIRCUIT_OPENED: 'opened'
19
+ }
20
+
14
21
  exports.level = {
15
22
  trace: 'trace',
16
23
  debug: 'debug',
@@ -19,7 +26,3 @@ exports.level = {
19
26
  error: 'error',
20
27
  fatal: 'fatal'
21
28
  }
22
-
23
- exports.SYNC_MIDDLEWARE_HOOKS = {
24
- STARTING: 'starting'
25
- }
@@ -0,0 +1,19 @@
1
+ exports.errorHandler = ({ options }, error) => {
2
+ if (options.errorHandler) {
3
+ return options.errorHandler.call(null, error)
4
+ }
5
+ throw error
6
+ }
7
+
8
+ exports.fatalErrorHandler = (runtime, message, error, killProcess = true) => {
9
+ const { options, log } = runtime
10
+ if (options.logger.enabled) {
11
+ log.fatal(error, message)
12
+ } else {
13
+ console.error(message, error)
14
+ }
15
+
16
+ if (killProcess) {
17
+ process.exit(1)
18
+ }
19
+ }
package/lib/errors.js CHANGED
@@ -1,10 +1,12 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
- class WeaveError extends Error {
7
+ const { ExtendableError } = require('./ExtendableError')
8
+
9
+ class WeaveError extends ExtendableError {
8
10
  constructor (message, code, type, data) {
9
11
  super(message)
10
12
  this.name = this.constructor.name
@@ -15,7 +17,7 @@ class WeaveError extends Error {
15
17
  }
16
18
  }
17
19
 
18
- class WeaveRetrieableError extends WeaveError {
20
+ class WeaveRetryableError extends WeaveError {
19
21
  constructor (message, code, type, data) {
20
22
  super(message)
21
23
  this.code = code || 500
@@ -25,7 +27,7 @@ class WeaveRetrieableError extends WeaveError {
25
27
  }
26
28
  }
27
29
 
28
- class WeaveServiceNotFoundError extends WeaveRetrieableError {
30
+ class WeaveServiceNotFoundError extends WeaveRetryableError {
29
31
  constructor (data = {}) {
30
32
  let message
31
33
 
@@ -33,31 +35,36 @@ class WeaveServiceNotFoundError extends WeaveRetrieableError {
33
35
  message = `Service "${data.actionName}" not found on node "${data.nodeId}".`
34
36
  } else if (data.actionName) {
35
37
  message = `Service "${data.actionName}" not found.`
38
+ } else {
39
+ message = 'Service not found.'
36
40
  }
37
41
 
38
42
  super(message, 404, 'WEAVE_SERVICE_NOT_FOUND_ERROR', data)
39
43
  }
40
44
  }
41
45
 
42
- class WeaveServiceNotAvailableError extends WeaveRetrieableError {
46
+ class WeaveServiceNotAvailableError extends WeaveRetryableError {
43
47
  constructor (data = {}) {
44
48
  let message
45
49
  if (data.nodeId) {
46
50
  message = `Service "${data.actionName}" not available on node "${data.nodeId}".`
47
- } else {
51
+ } else if (data.actionName) {
48
52
  message = `Service "${data.actionName}" not available.`
53
+ } else {
54
+ message = 'Service not available.'
49
55
  }
50
56
 
51
- super(message, 405, 'WEAVE_SERVICE_NOT_AVAILABLE_ERROR', data)
57
+ super(message, 503, 'WEAVE_SERVICE_NOT_AVAILABLE_ERROR', data)
52
58
  }
53
59
  }
54
60
 
55
- class WeaveRequestTimeoutError extends WeaveRetrieableError {
61
+ class WeaveRequestTimeoutError extends WeaveRetryableError {
56
62
  constructor (actionName, nodeId, timeout) {
57
63
  const message = `Action ${actionName} timed out node ${nodeId || '<local>'}.`
58
64
  super(message, 504, 'WEAVE_REQUEST_TIMEOUT_ERROR', {
59
65
  actionName,
60
- nodeId
66
+ nodeId,
67
+ timeout
61
68
  })
62
69
  this.retryable = true
63
70
  }
@@ -116,7 +123,7 @@ module.exports = {
116
123
  WeaveParameterValidationError,
117
124
  WeaveQueueSizeExceededError,
118
125
  WeaveRequestTimeoutError,
119
- WeaveRetrieableError,
126
+ WeaveRetryableError,
120
127
  WeaveServiceNotAvailableError,
121
128
  WeaveServiceNotFoundError,
122
129
  WeaveGracefulStopTimeoutError,
@@ -1,3 +1,5 @@
1
+ /* istanbul ignore next */
2
+
1
3
  /**
2
4
  * @typedef {import('../types.js').ServiceActionDefinition} ServiceActionDefinition
3
5
  */
@@ -6,7 +8,7 @@
6
8
  * Create and register a new service action.
7
9
  * @param {ServiceActionDefinition} actionDefinition - Schema of the the action
8
10
  * @returns {ServiceActionDefinition} Action definition
9
- */
11
+ */
10
12
  module.exports = function (actionDefinition) {
11
13
  return actionDefinition
12
14
  }
@@ -1,3 +1,5 @@
1
+ /* istanbul ignore next */
2
+
1
3
  /**
2
4
  * @typedef {import('../types.js').BrokerOptions} BrokerOptions
3
5
  */
@@ -1,3 +1,6 @@
1
+
2
+ /* istanbul ignore next */
3
+
1
4
  /**
2
5
  * @typedef {import('../types.js').ServiceSchema} ServiceSchema
3
6
  */
@@ -6,7 +9,7 @@
6
9
  * Create and register a new service
7
10
  * @param {ServiceSchema} serviceSchema - Schema of the Service
8
11
  * @returns {ServiceSchema} Service schema
9
- */
12
+ */
10
13
  module.exports = function (serviceSchema) {
11
14
  return serviceSchema
12
15
  }
package/lib/index.js CHANGED
@@ -4,93 +4,15 @@
4
4
  * @typedef {import('./types.js').Broker} Broker
5
5
  */
6
6
 
7
- const EventEmitter = require('eventemitter2')
8
- const { getDefaultOptions } = require('./broker/default-options')
9
- const { defaultsDeep, uuid, isFunction } = require('@weave-js/utils')
10
- const { initLogger } = require('./runtime/init-logger')
11
- const { initMiddlewareHandler } = require('./runtime/init-middleware-manager')
12
- const { initRegistry } = require('./runtime/init-registry')
13
- const { initContextFactory } = require('./runtime/init-context-factory')
14
- const { initEventbus } = require('./runtime/init-eventbus')
15
- const { initValidator } = require('./runtime/init-validator')
16
- const { initTransport } = require('./runtime/init-transport')
17
- const { initCache } = require('./runtime/init-cache')
18
- const { initActionInvoker } = require('./runtime/init-action-invoker')
19
- const { initServiceManager } = require('./runtime/init-service-manager')
20
- const { initMetrics } = require('./runtime/init-metrics')
21
- const { initTracer } = require('./runtime/init-tracing')
22
- const { initUUIDFactory } = require('./runtime/init-uuid-factory')
7
+ const { getDefaultOptions } = require('./broker/defaultOptions')
8
+ const { defaultsDeep } = require('@weave-js/utils')
9
+ const { initRuntime } = require('./buildRuntime')
23
10
  const { createBrokerInstance } = require('./broker')
24
- const { version } = require('../package.json')
25
-
26
- exports.defaultOptions = require('./broker/default-options')
27
-
28
- const errorHandler = ({ options }, error) => {
29
- if (options.errorHandler) {
30
- return options.errorHandler.call(null, error)
31
- }
32
- throw error
33
- }
34
-
35
- const fatalErrorHandler = (runtime, message, error, killProcess = true) => {
36
- const { options, log } = runtime
37
- if (options.logger.enabled) {
38
- log.fatal(error, message)
39
- } else {
40
- console.error(message, error)
41
- }
42
-
43
- if (killProcess) {
44
- process.exit(1)
45
- }
46
- }
47
11
 
48
12
  /**
49
- * Build runtime object
50
- * @param {BrokerOptions} options Broker options
51
- * @return {Runtime} Runtime
13
+ * @type {BrokerOptions} options Broker options
52
14
  */
53
- const buildRuntime = (options) => {
54
- /**
55
- * Event bus
56
- * @returns {EventEmitter} Service object.
57
- */
58
- const bus = new EventEmitter({
59
- wildcard: true,
60
- maxListeners: 1000
61
- })
62
-
63
- // Create base runtime object
64
- const runtime = {
65
- nodeId: options.nodeId,
66
- version,
67
- options,
68
- bus,
69
- state: {
70
- instanceId: uuid(),
71
- isStarted: false
72
- },
73
- handleError: (error) => errorHandler(runtime, error),
74
- fatalError: (message, error, killProcess) => fatalErrorHandler(runtime, message, error, killProcess)
75
- }
76
-
77
- // Init modules
78
- initLogger(runtime)
79
- initUUIDFactory(runtime)
80
- initMiddlewareHandler(runtime)
81
- initRegistry(runtime)
82
- initContextFactory(runtime)
83
- initEventbus(runtime)
84
- initValidator(runtime)
85
- initTransport(runtime)
86
- initCache(runtime)
87
- initActionInvoker(runtime)
88
- initServiceManager(runtime)
89
- initMetrics(runtime)
90
- initTracer(runtime)
91
-
92
- return runtime
93
- }
15
+ exports.defaultOptions = getDefaultOptions()
94
16
 
95
17
  /**
96
18
  * Build runtime object
@@ -105,13 +27,12 @@ exports.createBroker = (options) => {
105
27
  options = defaultsDeep(options, defaultOptions)
106
28
 
107
29
  // Init runtime
108
- const runtime = buildRuntime(options)
30
+ const runtime = initRuntime(options)
109
31
 
110
32
  // Create broker instance
111
33
  return createBrokerInstance(runtime)
112
34
  }
113
35
 
114
- // eslint-disable-next-line valid-jsdoc
115
36
  /**
116
37
  * @deprecated since version 0.9.0
117
38
  * @param {import('./types.js').BrokerOptions} options Broker options.
@@ -123,15 +44,19 @@ exports.Weave = exports.createBroker
123
44
  exports.Errors = require('./errors')
124
45
 
125
46
  exports.Constants = require('./constants')
126
- // Transport
127
- exports.TransportAdapters = require('./transport/adapters')
128
47
 
129
48
  // Caching
130
- exports.Cache = require('./cache')
131
- exports.createBaseTracingCollector = require('./tracing/collectors/base')
49
+ exports.Cache = require('./cache/adapters')
50
+
51
+ /**
52
+ * @deprecated since version 0.10.0
53
+ */
54
+ exports.createBaseTracingCollector = require('./tracing/collectors/base').createBaseTracingCollector
55
+ exports.TransportAdapters = require('./transport/adapters')
132
56
  exports.TracingAdapters = require('./tracing/collectors')
57
+ exports.CacheAdapters = require('./cache/adapters')
133
58
 
134
59
  // Helper
135
- exports.defineBrokerOptions = require('./helper/define-broker-options')
136
- exports.defineService = require('./helper/define-service')
137
- exports.defineAction = require('./helper/define-action')
60
+ exports.defineBrokerOptions = require('./helper/defineBrokerOptions')
61
+ exports.defineService = require('./helper/defineService')
62
+ exports.defineAction = require('./helper/defineAction')
@@ -1,4 +1,4 @@
1
- const { green, magenta, red, yellow, white, gray, cyan } = require('../utils/colorize')
1
+ const { green, magenta, red, yellow, gray, cyan } = require('../utils/colorize')
2
2
  const os = require('os')
3
3
 
4
4
  exports.asHumanReadable = ({ levels, options }, originObj, message, number, time) => {
@@ -15,8 +15,9 @@ exports.asHumanReadable = ({ levels, options }, originObj, message, number, time
15
15
 
16
16
  const currentLabel = levels.labels[number]
17
17
 
18
+ const color = logLevelColors[currentLabel] || yellow
18
19
  // Log level label
19
- logResult += logLevelColors[currentLabel](currentLabel.toUpperCase())
20
+ logResult += color(currentLabel.toUpperCase())
20
21
 
21
22
  // date time
22
23
  logResult += ' [' + new Date(time).toISOString() + '] '
@@ -26,7 +27,7 @@ exports.asHumanReadable = ({ levels, options }, originObj, message, number, time
26
27
  }
27
28
 
28
29
  if (message) {
29
- logResult += ' ' + logLevelColors[currentLabel](message)
30
+ logResult += ' ' + color(message)
30
31
  }
31
32
 
32
33
  if (Object.keys(originObj).length > 0) {
@@ -18,10 +18,16 @@ const defaultOptions = {
18
18
  level: 'info',
19
19
  messageKey: 'message',
20
20
  customLevels: null,
21
- base: { pid, hostname },
21
+ base: {
22
+ pid,
23
+ hostname
24
+ },
22
25
  hooks: {
23
26
  logMethod: undefined
24
27
  },
28
+ formatter: {
29
+ messageFormat: false
30
+ },
25
31
  destination: process.stdout
26
32
  }
27
33
 
@@ -1,12 +1,12 @@
1
1
  const { generateLogMethod } = require('./tools')
2
2
 
3
3
  const levels = {
4
- verbose: 6,
5
- debug: 5,
6
- info: 4,
7
- warn: 3,
8
- error: 2,
9
- fatal: 1
4
+ verbose: 60,
5
+ debug: 50,
6
+ info: 40,
7
+ warn: 30,
8
+ error: 20,
9
+ fatal: 10
10
10
  }
11
11
 
12
12
  // wrap log methods
@@ -51,8 +51,9 @@ exports.mappings = (customLevels = null, useOnlyCustomLevels = false) => {
51
51
  customNums
52
52
  )
53
53
 
54
+ // Merge log levels with "silent" log level.
54
55
  const values = Object.assign(
55
- Object.create(Object.prototype, { silent: { value: Infinity }}),
56
+ Object.create(Object.prototype, { silent: { value: 0 }}),
56
57
  useOnlyCustomLevels ? null : levels,
57
58
  customLevels
58
59
  )
@@ -7,6 +7,10 @@ exports.generateLogMethod = (runtime, level, hook) => {
7
7
  return log
8
8
  }
9
9
 
10
+ return function hookWrappedLog (...args) {
11
+ hook.call(runtime, args, log, level)
12
+ }
13
+
10
14
  function log (origin, ...n) {
11
15
  if (typeof origin === 'object') {
12
16
  let message = origin
@@ -52,29 +52,43 @@ exports.format = (f, args, opts) => {
52
52
  case 79: // 'O'
53
53
  case 111: // 'o'
54
54
  case 106: // 'j'
55
- if (a >= argumentLength) { break }
56
- if (lastPos < i) { str += f.slice(lastPos, i) }
57
- if (args[a] === undefined) break
55
+ if (a >= argumentLength) {
56
+ break
57
+ }
58
+
59
+ if (lastPos < i) {
60
+ str += f.slice(lastPos, i)
61
+ }
62
+
63
+ if (args[a] === undefined) {
64
+ break
65
+ }
66
+
58
67
  const type = typeof args[a]
68
+
59
69
  if (type === 'string') {
60
70
  str += '\'' + args[a] + '\''
61
71
  lastPos = i + 2
62
72
  i++
63
73
  break
64
74
  }
75
+
65
76
  if (type === 'function') {
66
77
  str += args[a].name || '<anonymous>'
67
78
  lastPos = i + 2
68
79
  i++
69
80
  break
70
81
  }
82
+
71
83
  str += ss(args[a])
72
84
  lastPos = i + 2
73
85
  i++
74
86
  break
75
87
  case 115: // 's'
76
88
  if (a >= argumentLength) { break }
77
- if (lastPos < i) { str += f.slice(lastPos, i) }
89
+ if (lastPos < i) {
90
+ str += f.slice(lastPos, i)
91
+ }
78
92
  str += String(args[a])
79
93
  lastPos = i + 2
80
94
  i++
@@ -29,7 +29,7 @@ exports.TRANSPORTER_PACKETS_RECEIVED = 'weave.transport.packets.received'
29
29
  exports.TRANSPORT_IN_FLIGHT_STREAMS = 'weave.transport.streams.in-flight'
30
30
 
31
31
  // Bulkhead
32
- exports.REQUESTS_BULKHEAD_IN_FLIGHT = 'weave.requests.bulkhead.in-flight'
32
+ exports.BULKHEAD_REQUESTS_IN_FLIGHT = 'weave.bulkhead.requests.in-flight'
33
33
 
34
34
  // OS Metrics
35
35
  exports.OS_HOSTNAME = 'os.hostname'
@@ -50,8 +50,10 @@ exports.OS_CPU_LOAD_1 = 'os.cpu-load.1'
50
50
  exports.OS_CPU_LOAD_5 = 'os.cpu-load.5'
51
51
  exports.OS_CPU_LOAD_15 = 'os.cpu-load.15'
52
52
 
53
- // Metric types
54
- exports.TYPE_INFO = 'info'
55
- exports.TYPE_GAUGE = 'gauge'
56
- exports.TYPE_COUNTER = 'counter'
57
- exports.TYPE_HISTOGRAM = 'counter'
53
+ // Cache
54
+ exports.CACHE_GET_TOTAL = 'weave.cache.items.get'
55
+ exports.CACHE_SET_TOTAL = 'weave.cache.items.set'
56
+ exports.CACHE_DELETED_TOTAL = 'weave.cache.items.deleted'
57
+ exports.CACHE_FOUND_TOTAL = 'weave.cache.items.found'
58
+ exports.CACHE_CLEANED_TOTAL = 'weave.cache.items.cleaned'
59
+ exports.CACHE_EXPIRED_TOTAL = 'weave.cache.items.expired'
@@ -6,7 +6,7 @@ exports.createGauge = (registry, obj) => {
6
6
  base.value = 0
7
7
 
8
8
  base.increment = (labels, value, timestamp) => {
9
- const item = base.values.get(labels)
9
+ const item = base.get(labels)
10
10
  base.set((item ? item.value : 0) + value, labels, timestamp)
11
11
  }
12
12
 
@@ -1,14 +1,26 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  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((promise, fn) => promise.then(res => fn.call(service, context, res)), Promise.resolve(result))
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,16 +45,34 @@ 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
- const beforeWildcardHook = hooks.before ? sanitizeHooks(hooks.before['*'], action.service) : null
37
- const afterWildcardHook = hooks.after ? sanitizeHooks(hooks.after['*'], action.service) : null
38
- const errorWildcardHook = hooks.error ? sanitizeHooks(hooks.error['*'], action.service) : null
39
- const beforeHook = hooks.before ? sanitizeHooks(hooks.before[name], action.service) : null
40
- const afterHook = hooks.after ? sanitizeHooks(hooks.after[name], action.service) : null
41
- const errorHook = hooks.error ? sanitizeHooks(hooks.error[name], action.service) : null
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
- if (beforeWildcardHook || afterWildcardHook || errorWildcardHook || beforeHook || afterHook || errorHook) {
44
- return function actionHookMiddleware (context) {
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
+ ) {
75
+ return function actionHookMiddleware (context, serviceInjections) {
45
76
  let promise = Promise.resolve()
46
77
 
47
78
  // before all hook
@@ -54,8 +85,18 @@ 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
- promise = promise.then(() => handler(context))
94
+ promise = promise.then(() => handler(context, serviceInjections))
95
+
96
+ // After hook in action definition
97
+ if (actionAfterHook) {
98
+ promise = promise.then(result => callHook(actionAfterHook, action.service, context, result))
99
+ }
59
100
 
60
101
  // After hook
61
102
  if (afterHook) {
@@ -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 => callHook(errorHook, action.service, context, 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 => callHook(errorWildcardHook, action.service, context, error))
124
+ promise = promise.catch(error => callErrorHook(errorWildcardHook, action.service, context, error))
77
125
  }
78
126
 
79
127
  return promise
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
-
6
+ const { Constants } = require('../../metrics')
7
7
  const { WeaveQueueSizeExceededError } = require('../../errors')
8
8
 
9
9
  /**
@@ -44,11 +44,11 @@ module.exports = (runtime) => {
44
44
  })
45
45
  }
46
46
 
47
- return function bulkheadMiddlware (context) {
47
+ return function bulkheadMiddlware (context, serviceInjections) {
48
48
  // Execute action immediately
49
49
  if (currentlyInFlight < bulkheadOptions.concurrentCalls) {
50
50
  currentlyInFlight++
51
- return handler(context)
51
+ return handler(context, serviceInjections)
52
52
  .then(result => {
53
53
  currentlyInFlight--
54
54
  callNext()
@@ -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