@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,10 +1,10 @@
1
1
  /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
2
+ * Author: Kevin Ries (kevin.ries@fachwerk.io)
3
3
  * -----
4
4
  * Copyright 2021 Fachwerk
5
5
  */
6
-
7
- const { WeaveQueueSizeExceededError } = require('../../errors')
6
+ const { Constants } = require('../../metrics');
7
+ const { WeaveQueueSizeExceededError } = require('../../errors');
8
8
 
9
9
  /**
10
10
  * @typedef {import('../../types').Runtime} Runtime
@@ -18,47 +18,47 @@ const { WeaveQueueSizeExceededError } = require('../../errors')
18
18
  */
19
19
  module.exports = (runtime) => {
20
20
  const wrapBulkheadMiddleware = function (handler, action) {
21
- const bulkheadOptions = runtime.options.bulkhead
21
+ const bulkheadOptions = runtime.options.bulkhead;
22
22
 
23
23
  if (bulkheadOptions.enabled) {
24
- const queue = []
25
- let currentlyInFlight = 0
24
+ const queue = [];
25
+ let currentlyInFlight = 0;
26
26
 
27
27
  const callNext = () => {
28
- if (queue.length === 0) return
29
- if (currentlyInFlight >= bulkheadOptions.concurrentCalls) return
28
+ if (queue.length === 0) return;
29
+ if (currentlyInFlight >= bulkheadOptions.concurrentCalls) return;
30
30
 
31
- const item = queue.shift()
31
+ const item = queue.shift();
32
32
 
33
- currentlyInFlight++
33
+ currentlyInFlight++;
34
34
  handler(item.context)
35
35
  .then(result => {
36
- currentlyInFlight--
37
- item.resolve(result)
38
- callNext()
36
+ currentlyInFlight--;
37
+ item.resolve(result);
38
+ callNext();
39
39
  })
40
40
  .catch(error => {
41
- currentlyInFlight--
42
- callNext()
43
- return item.reject(error)
44
- })
45
- }
41
+ currentlyInFlight--;
42
+ callNext();
43
+ return item.reject(error);
44
+ });
45
+ };
46
46
 
47
47
  return function bulkheadMiddlware (context, serviceInjections) {
48
48
  // Execute action immediately
49
49
  if (currentlyInFlight < bulkheadOptions.concurrentCalls) {
50
- currentlyInFlight++
50
+ currentlyInFlight++;
51
51
  return handler(context, serviceInjections)
52
52
  .then(result => {
53
- currentlyInFlight--
54
- callNext()
55
- return result
53
+ currentlyInFlight--;
54
+ callNext();
55
+ return result;
56
56
  })
57
57
  .catch(error => {
58
- currentlyInFlight--
59
- callNext()
60
- return Promise.reject(error)
61
- })
58
+ currentlyInFlight--;
59
+ callNext();
60
+ return Promise.reject(error);
61
+ });
62
62
  }
63
63
 
64
64
  // Reject the action if the max queue size is reached.
@@ -67,22 +67,23 @@ module.exports = (runtime) => {
67
67
  action: action.name,
68
68
  limit: bulkheadOptions.maxQueueSize,
69
69
  size: queue.length
70
- }))
70
+ }));
71
71
  }
72
72
 
73
73
  // Queue the request
74
- return new Promise((resolve, reject) => queue.push({ resolve, reject, context }))
75
- }
74
+ return new Promise((resolve, reject) => queue.push({ resolve, reject, context }));
75
+ };
76
76
  }
77
- return handler
78
- }
77
+ return handler;
78
+ };
79
79
 
80
80
  return {
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
87
- }
88
- }
88
+ };
89
+ };
@@ -0,0 +1,106 @@
1
+ const { isString, isFunction } = require('@weave-js/utils');
2
+
3
+ module.exports = (runtime) => {
4
+ return {
5
+ localAction: (handler, action) => {
6
+ const cacheOptions = runtime.options.cache;
7
+ const cacheActionOptions = {
8
+ enabled: !!action.cache
9
+ };
10
+
11
+ if (isString(action.cache)) {
12
+ cacheActionOptions.keys = action.cache.split(' ');
13
+ } else if (action.cache && Array.isArray(action.cache.keys)) {
14
+ cacheActionOptions.keys = action.cache.keys;
15
+ }
16
+
17
+ if (cacheActionOptions.enabled) {
18
+ const cache = runtime.cache;
19
+ const isEnabledFunction = isFunction(action.cache.condition);
20
+
21
+ return function cacheMiddleware (context, serviceInjections) {
22
+ // handle enabled function
23
+ if (isEnabledFunction) {
24
+ if (!action.cache.enabled.call(null, context)) {
25
+ // Enabled function returns "false". Cache is disabled.
26
+ return handler(context, serviceInjections);
27
+ }
28
+ }
29
+
30
+ // Generate cache hash
31
+ const cacheHashKey = cache.getCachingKey(
32
+ action.name,
33
+ context.data,
34
+ context.meta,
35
+ cacheActionOptions.keys
36
+ );
37
+
38
+ context.isCachedResult = false;
39
+
40
+ // Disable caching by meta property.
41
+ if (context.meta.$noCache === true) {
42
+ return handler(context, serviceInjections);
43
+ }
44
+
45
+ // The cache adapter is not connected yet. In this case, we call the handler regular
46
+ if (cache.isConnected === false) {
47
+ cache.log('Cache adapter is not connected yet. Call handler...');
48
+ return handler(context, serviceInjections);
49
+ }
50
+
51
+ if (cacheOptions.lock.enabled) {
52
+ let cachePromise;
53
+ if (cacheOptions.lock.staleTime && cache.getWithTTl) {
54
+
55
+ } else {
56
+ cachePromise = runtime.cache.get(cacheHashKey);
57
+ }
58
+
59
+ return cachePromise.then((cachedResult) => {
60
+ if (cachedResult !== null) {
61
+ // Found a cached value. Skip calling handler and return our value
62
+ context.isCachedResult = true;
63
+ return cachedResult;
64
+ }
65
+
66
+ return cache.lock(cacheHashKey).then((release) => {
67
+ return cache.get(cacheHashKey).then(cachedResult => {
68
+ if (cachedResult !== null) {
69
+ // Found a cached value. Skip calling handler and return our value
70
+ context.isCachedResult = true;
71
+ return release().then(() => {
72
+ return cachedResult;
73
+ });
74
+ }
75
+
76
+ return handler(context).then((result) => {
77
+ // Cache the value
78
+ cache.set(cacheHashKey, result, action.cache.ttl).then(() => {
79
+ // release the lock
80
+ release();
81
+ });
82
+ return result;
83
+ });
84
+ });
85
+ });
86
+ });
87
+ }
88
+
89
+ // Not using cache lock
90
+ return runtime.cache.get(cacheHashKey).then((cachedResult) => {
91
+ if (cachedResult !== null) {
92
+ context.isCachedResult = true;
93
+ return cachedResult;
94
+ }
95
+
96
+ return handler(context, serviceInjections).then((result) => {
97
+ runtime.cache.set(cacheHashKey, result, action.cache.ttl);
98
+ return result;
99
+ });
100
+ });
101
+ };
102
+ }
103
+ return handler;
104
+ }
105
+ };
106
+ };
@@ -1,143 +1,168 @@
1
1
  /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
2
+ * Author: Kevin Ries (kevin.ries@fachwerk.io)
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
- const storage = new Map()
9
- let log = null
10
- let circuitBreakerTimer = null
14
+ const storage = new Map();
15
+ let log = null;
16
+ let circuitBreakerTimer = null;
11
17
 
12
18
  function createWindowTimer (windowTime) {
13
- circuitBreakerTimer = setInterval(() => clearEndpointStore(), windowTime)
14
- circuitBreakerTimer.unref()
19
+ circuitBreakerTimer = setInterval(() => clearEndpointStore(), windowTime);
20
+ circuitBreakerTimer.unref();
15
21
  }
16
22
 
17
23
  function clearEndpointStore () {
18
- storage.forEach(item => {
24
+ storage.forEach((item) => {
19
25
  if (item.callCounter === 0) {
20
- storage.delete(item.name)
21
- return
26
+ storage.delete(item.name);
27
+ return;
22
28
  }
23
29
 
24
- item.callCounter = 0
25
- item.failureCouter = 0
26
- })
30
+ item.callCounter = 0;
31
+ item.failureCouter = 0;
32
+ });
27
33
  }
28
34
 
29
35
  function getEndpointState (endpoint, options) {
30
- let item = storage.get(endpoint.name)
36
+ let item = storage.get(endpoint.name);
31
37
  if (!item) {
32
38
  item = {
33
39
  endpoint,
34
40
  options,
35
41
  callCounter: 0,
36
42
  failureCouter: 0,
37
- state: 'CIRCUIT_BREAKER_CLOSED',
43
+ state: CIRCUIT_CLOSED,
38
44
  circuitBreakerTimer: null
39
- }
40
- storage.set(endpoint.name, item)
45
+ };
46
+ storage.set(endpoint.name, item);
41
47
  }
42
48
 
43
- return item
49
+ return item;
44
50
  }
45
51
 
46
- function success (item, options) {
47
- item.callCounter++
52
+ function onSuccess (item, options) {
53
+ item.callCounter++;
48
54
 
49
- if (item.state === 'CIRCUIT_BREAKER_HALF_OPENED') {
50
- closeCircuitBreaker(item, options)
55
+ if (item.state === CIRCUIT_HALF_OPENED) {
56
+ closeCircuitBreaker(item);
51
57
  } else {
52
- checkThreshold(item, options)
58
+ checkThreshold(item, options);
53
59
  }
54
60
  }
55
61
 
56
- function failure (item, error, options) {
57
- item.callCounter++
58
- item.failureCouter++
62
+ function onFailure (item, options) {
63
+ item.callCounter++;
64
+ item.failureCouter++;
59
65
 
60
- checkThreshold(item, options)
66
+ checkThreshold(item, options);
61
67
  }
62
68
 
63
69
  function checkThreshold (item, options) {
64
70
  if (item.failureCouter >= options.maxFailures) {
65
- openCircuitBreaker(item)
71
+ openCircuitBreaker(item);
66
72
  }
67
73
  }
68
74
 
69
75
  function openCircuitBreaker (item) {
70
- item.state = 'CIRCUIT_BREAKER_OPEN'
71
- item.endpoint.state = false
72
- item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout)
73
-
74
- log.debug(`Circuit breaker has been opened for endpoint '${item.endpoint.name}'`)
76
+ item.state = CIRCUIT_OPENED;
77
+ item.endpoint.state = false;
78
+ item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout);
79
+ item.circuitBreakerTimer.unref();
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 = 'CIRCUIT_BREAKER_HALF_OPEN'
79
- item.endpoint.state = true
84
+ item.state = CIRCUIT_HALF_OPENED;
85
+ item.endpoint.state = true;
86
+
87
+ log.debug(`Circuit breaker has been half opened for endpoint '${item.endpoint.name}'`);
80
88
 
81
- log.debug(`Circuit breaker has been half opened for endpoint '${item.endpoint.name}'`)
89
+ if (item.circuitBreakerTimer) {
90
+ clearTimeout(item.circuitBreakerTimer);
91
+ item.circuitBreakerTimer = null;
92
+ }
82
93
  }
83
94
 
84
- function closeCircuitBreaker (item, options) {
85
- item.failureCouter = 0
86
- item.callCounter = 0
87
- item.state = 'CIRCUIT_BREAKER_CLOSED'
88
- item.endpoint.state = true
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) {
103
+ item.failureCouter = 0;
104
+ item.callCounter = 0;
105
+ item.state = CIRCUIT_CLOSED;
106
+ item.endpoint.state = true;
89
107
 
90
108
  if (item.circuitBreakerTimer) {
91
- clearTimeout(item.circuitBreakerTimer)
92
- item.circuitBreakerTimer = null
109
+ clearTimeout(item.circuitBreakerTimer);
110
+ item.circuitBreakerTimer = null;
93
111
  }
94
112
 
95
- log.debug(`Circuit breaker has been closed for endpoint '${item.endpoint.name}'`)
113
+ log.debug(`Circuit breaker has been closed for endpoint '${item.endpoint.name}'`);
96
114
  }
97
115
 
98
116
  function wrapCircuitBreakerMiddleware (handler, action) {
99
- const options = Object.assign({}, runtime.options.circuitBreaker, action.circuitBreaker || {})
117
+ const options = Object.assign({}, runtime.options.circuitBreaker, action.circuitBreaker || {});
100
118
 
101
119
  if (options.enabled) {
102
120
  return function curcuitBreakerMiddleware (context, serviceInjections) {
103
- const endpoint = context.endpoint
104
- const item = getEndpointState(endpoint, options)
121
+ const endpoint = context.endpoint;
122
+ const item = getEndpointState(endpoint, options);
123
+
124
+ // handle half open states
125
+ if (item.state === CIRCUIT_HALF_OPENED) {
126
+ handleHalfOpen(item, context);
127
+ }
105
128
 
106
129
  return handler(context, serviceInjections)
107
130
  .then(result => {
108
- const item = getEndpointState(endpoint, options)
109
- success(item, options)
131
+ const item = getEndpointState(endpoint, options);
132
+ onSuccess(item, options);
110
133
 
111
- return result
134
+ return result;
112
135
  })
113
136
  .catch(error => {
114
- failure(item, error, options)
137
+ if (item && (!error.nodeId || error.nodeId === context.nodeId)) {
138
+ onFailure(item, options);
139
+ }
115
140
 
116
- return Promise.reject(error)
117
- })
118
- }
141
+ return Promise.reject(error);
142
+ });
143
+ };
119
144
  }
120
- return handler
145
+ return handler;
121
146
  }
122
147
 
123
148
  return {
124
149
  created () {
125
- log = runtime.createLogger('circuit-breaker')
150
+ log = runtime.createLogger('circuit-breaker');
126
151
 
127
152
  if (runtime.options.metrics.enabled) {
128
153
  // todo: add circuit breaker metrics
129
154
  }
130
155
  },
131
156
  started () {
132
- const { enabled, windowTime } = this.options.circuitBreaker
157
+ const { enabled, windowTime } = this.options.circuitBreaker;
133
158
  if (enabled) {
134
- createWindowTimer(windowTime)
159
+ createWindowTimer(windowTime);
135
160
  }
136
161
  },
137
162
  localAction: wrapCircuitBreakerMiddleware,
138
163
  remoteAction: wrapCircuitBreakerMiddleware,
139
164
  brokerStopped () {
140
- clearInterval(circuitBreakerTimer)
165
+ clearInterval(circuitBreakerTimer);
141
166
  }
142
- }
143
- }
167
+ };
168
+ };
@@ -1,107 +1,107 @@
1
- const { WeaveGracefulStopTimeoutError } = require('../../errors')
1
+ const { WeaveGracefulStopTimeoutError } = require('../../errors');
2
2
 
3
3
  module.exports = (runtime) => {
4
4
  function addContext (context) {
5
5
  if (context.service) {
6
6
  // local actions
7
- context.service._trackedContexts.push(context)
7
+ context.service._trackedContexts.push(context);
8
8
  } else {
9
9
  // remote actions
10
- context.service._trackedContexts.push(context)
10
+ context.service._trackedContexts.push(context);
11
11
  }
12
12
  }
13
13
 
14
14
  function removeContext (context) {
15
15
  if (context.service) {
16
16
  // local actions
17
- const index = context.service._trackedContexts.indexOf(context)
17
+ const index = context.service._trackedContexts.indexOf(context);
18
18
  if (index !== -1) {
19
- context.service._trackedContexts.splice(index, 1)
19
+ context.service._trackedContexts.splice(index, 1);
20
20
  }
21
21
  } else {
22
- const index = context.service._trackedContexts.indexOf(context)
22
+ const index = context.service._trackedContexts.indexOf(context);
23
23
  if (index !== -1) {
24
- context.service._trackedContexts.splice(index, 1)
24
+ context.service._trackedContexts.splice(index, 1);
25
25
  }
26
26
  }
27
27
  }
28
28
 
29
29
  function wrapContextTrackerMiddleware (actionHandler) {
30
30
  return function ContextTrackerMiddleware (context, serviceInjections) {
31
- const isTracked = context.options.track === true ? context.options.track : runtime.options.contextTracking.enabled
31
+ const isTracked = context.options.track === true ? context.options.track : runtime.options.contextTracking.enabled;
32
32
 
33
33
  if (!isTracked) {
34
- return actionHandler(context, serviceInjections)
34
+ return actionHandler(context, serviceInjections);
35
35
  }
36
36
 
37
- addContext(context)
37
+ addContext(context);
38
38
 
39
39
  return actionHandler(context, serviceInjections)
40
40
  .then(result => {
41
- removeContext(context)
42
- return result
41
+ removeContext(context);
42
+ return result;
43
43
  })
44
44
  .catch(error => {
45
- removeContext(context)
46
- throw error
47
- })
48
- }
45
+ removeContext(context);
46
+ throw error;
47
+ });
48
+ };
49
49
  }
50
50
 
51
51
  const waitingForActiveContexts = (contextList, log, shutdownTimeout, service) => {
52
52
  return new Promise((resolve) => {
53
53
  if (contextList.length === 0) {
54
- resolve()
54
+ resolve();
55
55
  }
56
56
 
57
- let isTimedOut = false
57
+ let isTimedOut = false;
58
58
  const timeout = setTimeout(() => {
59
- isTimedOut = true
60
- log.error(new WeaveGracefulStopTimeoutError(service))
61
- contextList = []
62
- resolve()
63
- }, shutdownTimeout)
59
+ isTimedOut = true;
60
+ log.error(new WeaveGracefulStopTimeoutError(service));
61
+ contextList = [];
62
+ resolve();
63
+ }, shutdownTimeout);
64
64
 
65
- let isFirstCheck = true
65
+ let isFirstCheck = true;
66
66
  const checkContexts = () => {
67
67
  if (contextList.length === 0) {
68
- clearTimeout(timeout)
69
- resolve()
68
+ clearTimeout(timeout);
69
+ resolve();
70
70
  } else {
71
71
  if (isFirstCheck) {
72
- log.info(`Waiting for ${contextList.length} open Contexts...`)
73
- isFirstCheck = false
72
+ log.info(`Waiting for ${contextList.length} open Contexts...`);
73
+ isFirstCheck = false;
74
74
  }
75
75
 
76
76
  if (!isTimedOut) {
77
- setTimeout(checkContexts, 100)
77
+ setTimeout(checkContexts, 100);
78
78
  }
79
79
  }
80
- }
81
- setImmediate(checkContexts)
82
- })
83
- }
80
+ };
81
+ setImmediate(checkContexts);
82
+ });
83
+ };
84
84
 
85
85
  return {
86
86
  created () {
87
87
  // init context-store
88
- runtime.state.trackedContexts = []
88
+ runtime.state.trackedContexts = [];
89
89
  },
90
90
  serviceStarting (service) {
91
- service._trackedContexts = []
91
+ service._trackedContexts = [];
92
92
  },
93
93
 
94
94
  // Before a local service stopping
95
95
  serviceStopping (service) {
96
- return waitingForActiveContexts(service._trackedContexts, service.log, service.settings.$shutdownTimeout || service.broker.options.contextTracking.shutdownTimeout, service)
96
+ return waitingForActiveContexts(service._trackedContexts, service.log, service.settings.$shutdownTimeout || service.broker.options.contextTracking.shutdownTimeout, service);
97
97
  },
98
98
 
99
99
  // Before broker stopping
100
100
  stopping () {
101
- return waitingForActiveContexts(runtime.state.trackedContexts, runtime.log, runtime.options.contextTracking.shutdownTimeout)
101
+ return waitingForActiveContexts(runtime.state.trackedContexts, runtime.log, runtime.options.contextTracking.shutdownTimeout);
102
102
  },
103
103
  localAction: wrapContextTrackerMiddleware,
104
104
  remoteAction: wrapContextTrackerMiddleware,
105
105
  localEvent: wrapContextTrackerMiddleware
106
- }
107
- }
106
+ };
107
+ };
@@ -1,10 +1,10 @@
1
1
  /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
2
+ * Author: Kevin Ries (kevin.ries@fachwerk.io)
3
3
  * -----
4
4
  * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
- const { WeaveError } = require('../../errors')
7
+ const { WeaveError } = require('../../errors');
8
8
 
9
9
  module.exports = (runtime) => {
10
10
  const wrapErrorHandlerMiddleware = function (handler) {
@@ -12,24 +12,24 @@ module.exports = (runtime) => {
12
12
  return handler(context, serviceInjections)
13
13
  .catch(error => {
14
14
  if (!(error instanceof Error)) {
15
- error = new WeaveError(error, 500)
15
+ error = new WeaveError(error, 500);
16
16
  }
17
17
 
18
18
  if (runtime.nodeId !== context.nodeId) {
19
- runtime.transport.removePendingRequestsById(context.id)
19
+ runtime.transport.removePendingRequestsById(context.id);
20
20
  }
21
21
 
22
- runtime.log.debug(`The action ${context.action.name} is rejected`, { requestId: context.id }, error)
23
- return runtime.handleError(error)
24
- })
25
- // .catch(error => {
26
- // runtime.log.error(error)
27
- // })
28
- }
29
- }
22
+ runtime.log.debug(`The action ${context.action.name} is rejected`, { requestId: context.id }, error);
23
+ return runtime.handleError(error);
24
+ });
25
+ // .catch(error => {
26
+ // runtime.log.error(error)
27
+ // })
28
+ };
29
+ };
30
30
 
31
31
  return {
32
32
  localAction: wrapErrorHandlerMiddleware,
33
33
  remoteAction: wrapErrorHandlerMiddleware
34
- }
35
- }
34
+ };
35
+ };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Author: Kevin Ries (kevin@fachw3rk.de)
2
+ * Author: Kevin Ries (kevin.ries@fachwerk.io)
3
3
  * -----
4
4
  * Copyright 2021 Fachwerk
5
5
  */
@@ -7,6 +7,7 @@
7
7
  module.exports = {
8
8
  ActionHooks: require('./action-hooks'),
9
9
  Bulkhead: require('./bulkhead'),
10
+ Cache: require('./cache'),
10
11
  CircuitBreaker: require('./circuit-breaker'),
11
12
  ErrorHandler: require('./error-handler'),
12
13
  Metrics: require('./metrics'),
@@ -15,4 +16,4 @@ module.exports = {
15
16
  Timeout: require('./timeout'),
16
17
  ContextTracker: require('./context-tracker'),
17
18
  Validator: require('./validator')
18
- }
19
+ };