@weave-js/core 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/broker/defaultOptions.js +2 -1
- package/lib/broker/index.js +1 -1
- package/lib/cache/adapters/base.js +143 -0
- package/lib/cache/adapters/inMemory.js +154 -0
- package/lib/cache/{inMemory.js → adapters/inMemoryLru.js} +7 -7
- package/lib/cache/adapters/index.js +46 -0
- package/lib/cache/base.js +35 -46
- package/lib/index.js +3 -4
- package/lib/middlewares/cache/index.js +37 -11
- package/lib/registry/registry.js +10 -16
- package/lib/runtime/initCache.js +12 -3
- package/lib/types.js +22 -11
- package/lib/utils/index.js +1 -1
- package/package.json +4 -4
- package/lib/cache/index.js +0 -48
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
/** @module weave */
|
|
12
12
|
const os = require('os')
|
|
13
|
+
const { createInMemoryCache } = require('../cache/adapters/inMemory.js')
|
|
13
14
|
const { loadBalancingStrategy } = require('../constants')
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -28,7 +29,7 @@ exports.getDefaultOptions = () => {
|
|
|
28
29
|
},
|
|
29
30
|
cache: {
|
|
30
31
|
enabled: false,
|
|
31
|
-
adapter:
|
|
32
|
+
adapter: createInMemoryCache(),
|
|
32
33
|
ttl: 3000,
|
|
33
34
|
lock: {
|
|
34
35
|
enabled: false
|
package/lib/broker/index.js
CHANGED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Author: Kevin Ries (kevin@fachw3rk.de)
|
|
3
|
+
* -----
|
|
4
|
+
* Copyright 2021 Fachwerk
|
|
5
|
+
*/
|
|
6
|
+
const crypto = require('crypto')
|
|
7
|
+
const { isObject, dotGet, isString } = require('@weave-js/utils')
|
|
8
|
+
const Constants = require('../../metrics/constants')
|
|
9
|
+
const { WeaveError } = require('../../errors')
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get property from data or metadata object.
|
|
13
|
+
* @param {any} data data object
|
|
14
|
+
* @param {object} metadata metadata object
|
|
15
|
+
* @param {string} key key
|
|
16
|
+
* @returns {any} Result
|
|
17
|
+
*/
|
|
18
|
+
function getPropertyFromDataOrMetadata (data, metadata, key) {
|
|
19
|
+
// if a key starts with ":", the property is picked from metadata
|
|
20
|
+
if (key.startsWith(':')) {
|
|
21
|
+
// remove ':' from key.
|
|
22
|
+
key = key.replace(':', '')
|
|
23
|
+
return dotGet(metadata, key)
|
|
24
|
+
}
|
|
25
|
+
return dotGet(data, key)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getCacheKeyByObject (val) {
|
|
29
|
+
if (Array.isArray(val)) {
|
|
30
|
+
return val.map(object => getCacheKeyByObject(object)).join('/')
|
|
31
|
+
} else if (isObject(val)) {
|
|
32
|
+
return Object.keys(val).map(key => {
|
|
33
|
+
return [key, getCacheKeyByObject(val[key])].join('/')
|
|
34
|
+
}).join('/')
|
|
35
|
+
} else if (val !== null) {
|
|
36
|
+
return val.toString()
|
|
37
|
+
} else {
|
|
38
|
+
return 'null'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function generateHash (key) {
|
|
43
|
+
return crypto
|
|
44
|
+
.createHash('sha1')
|
|
45
|
+
.update(key)
|
|
46
|
+
.digest('base64')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function registerCacheMetrics (metrics) {
|
|
50
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_GET_TOTAL })
|
|
51
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_SET_TOTAL })
|
|
52
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_FOUND_TOTAL })
|
|
53
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_EXPIRED_TOTAL })
|
|
54
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_DELETED_TOTAL })
|
|
55
|
+
metrics.register({ type: 'counter', name: Constants.CACHE_CLEANED_TOTAL })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const createCacheBase = (name, runtime, adapterOptions, options) => {
|
|
59
|
+
if (!isString(name)) {
|
|
60
|
+
throw new WeaveError('Name must be a string.')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const cache = {
|
|
64
|
+
name,
|
|
65
|
+
isConnected: false,
|
|
66
|
+
runtime,
|
|
67
|
+
options: Object.assign({
|
|
68
|
+
ttl: null
|
|
69
|
+
}, options),
|
|
70
|
+
init () {
|
|
71
|
+
// register metrics
|
|
72
|
+
if (runtime.metrics) {
|
|
73
|
+
this.metrics = runtime.metrics
|
|
74
|
+
registerCacheMetrics(runtime.metrics)
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
log: runtime.createLogger('CACHER'),
|
|
78
|
+
set (/* hashKey, result, ttl */) {
|
|
79
|
+
/* istanbul ignore next */
|
|
80
|
+
runtime.handleError(new Error('Method not implemented.'))
|
|
81
|
+
},
|
|
82
|
+
get (/* hashKey */) {
|
|
83
|
+
/* istanbul ignore next */
|
|
84
|
+
runtime.handleError(new Error('Method not implemented.'))
|
|
85
|
+
},
|
|
86
|
+
remove () {
|
|
87
|
+
/* istanbul ignore next */
|
|
88
|
+
runtime.handleError(new Error('Method not implemented.'))
|
|
89
|
+
},
|
|
90
|
+
clear () {
|
|
91
|
+
/* istanbul ignore next */
|
|
92
|
+
runtime.handleError(new Error('Method not implemented.'))
|
|
93
|
+
},
|
|
94
|
+
stop () {
|
|
95
|
+
/* istanbul ignore next */
|
|
96
|
+
return Promise.resolve()
|
|
97
|
+
},
|
|
98
|
+
getCachingKey (actionName, data, metadata, keys) {
|
|
99
|
+
if (data || metadata) {
|
|
100
|
+
const prefix = actionName + ':'
|
|
101
|
+
|
|
102
|
+
if (keys) {
|
|
103
|
+
// fast path for single keys
|
|
104
|
+
if (keys.length === 1) {
|
|
105
|
+
const value = getPropertyFromDataOrMetadata(data, metadata, keys[0])
|
|
106
|
+
const key = getCacheKeyByObject(value)
|
|
107
|
+
return prefix + (isObject(value) ? key : value)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Handle data cache keys
|
|
111
|
+
if (keys.length > 0) {
|
|
112
|
+
const res = keys.reduce((pre, property, index) => {
|
|
113
|
+
const value = getPropertyFromDataOrMetadata(data, metadata, property)
|
|
114
|
+
let hash
|
|
115
|
+
if (isObject(value)) {
|
|
116
|
+
const key = getCacheKeyByObject(value)
|
|
117
|
+
hash = generateHash(key)
|
|
118
|
+
} else {
|
|
119
|
+
hash = value
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return pre + (index > 0 ? '|' : '') + hash
|
|
123
|
+
}, prefix)
|
|
124
|
+
return res
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
return prefix + generateHash(getCacheKeyByObject(data))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return actionName
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
Object.defineProperty(cache, 'adapterOptions', {
|
|
136
|
+
value: adapterOptions,
|
|
137
|
+
writable: false
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
return cache
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = { createCacheBase }
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Author: Kevin Ries (kevin@fachw3rk.de)
|
|
3
|
+
* -----
|
|
4
|
+
* Copyright 2021 Fachwerk
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { match, defaultsDeep } = require('@weave-js/utils')
|
|
8
|
+
const { createCacheBase } = require('./base')
|
|
9
|
+
const { createLock } = require('../lock')
|
|
10
|
+
const Constants = require('../../metrics/constants')
|
|
11
|
+
|
|
12
|
+
const defaultAdapterOptions = {
|
|
13
|
+
ttlCheckInterval: 3000
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} InMemoryAdapterOptions
|
|
18
|
+
* @property {number=} ttlCheckInterval TTL check interval
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create an in-memory cache adapter.
|
|
23
|
+
* @param {InMemoryAdapterOptions} adapterOptions Adapter options
|
|
24
|
+
* @returns {any} CacheFactory
|
|
25
|
+
*/
|
|
26
|
+
const createInMemoryCache = (adapterOptions = {}) => (runtime, options = {}) => {
|
|
27
|
+
adapterOptions = defaultsDeep(adapterOptions, defaultAdapterOptions)
|
|
28
|
+
const base = createCacheBase('In-Memory', runtime, adapterOptions, options)
|
|
29
|
+
const storage = new Map()
|
|
30
|
+
|
|
31
|
+
const lock = createLock()
|
|
32
|
+
|
|
33
|
+
const ttlTimerHandle = setInterval(() => {
|
|
34
|
+
checkTtl()
|
|
35
|
+
}, adapterOptions.ttlCheckInterval)
|
|
36
|
+
|
|
37
|
+
ttlTimerHandle.unref()
|
|
38
|
+
|
|
39
|
+
// if a new broker gets connected, we need to clear the cache
|
|
40
|
+
runtime.bus.on('$transport.connected', () => {
|
|
41
|
+
base.log.debug('Transport adapter connected. Cache will be cleared.')
|
|
42
|
+
cache.clear()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const checkTtl = () => {
|
|
46
|
+
const now = Date.now()
|
|
47
|
+
|
|
48
|
+
storage.forEach((item, hashKey) => {
|
|
49
|
+
if (item.expire && item.expire < now) {
|
|
50
|
+
cache.log.debug(`Delete ${hashKey}`)
|
|
51
|
+
storage.delete(hashKey)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const cache = Object.assign(
|
|
57
|
+
{},
|
|
58
|
+
base,
|
|
59
|
+
{
|
|
60
|
+
init () {
|
|
61
|
+
base.init()
|
|
62
|
+
cache.isConnected = true
|
|
63
|
+
},
|
|
64
|
+
get (cacheKey) {
|
|
65
|
+
base.log.debug(`Get ${cacheKey}`)
|
|
66
|
+
|
|
67
|
+
if (base.metrics) {
|
|
68
|
+
base.metrics.increment(Constants.CACHE_GET_TOTAL)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const item = storage.get(cacheKey)
|
|
72
|
+
|
|
73
|
+
if (item) {
|
|
74
|
+
cache.log.debug(`Found ${cacheKey}`)
|
|
75
|
+
|
|
76
|
+
if (base.metrics) {
|
|
77
|
+
base.metrics.increment(Constants.CACHE_FOUND_TOTAL)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (item.expire && item.expire < Date.now()) {
|
|
81
|
+
cache.log.debug(`Delete ${cacheKey}`)
|
|
82
|
+
storage.delete(cacheKey)
|
|
83
|
+
if (base.metrics) {
|
|
84
|
+
base.metrics.increment(Constants.CACHE_EXPIRED_TOTAL)
|
|
85
|
+
}
|
|
86
|
+
return Promise.resolve(null)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return Promise.resolve(item.data)
|
|
90
|
+
}
|
|
91
|
+
return Promise.resolve(null)
|
|
92
|
+
},
|
|
93
|
+
set (hashKey, data, ttl) {
|
|
94
|
+
if (base.metrics) {
|
|
95
|
+
base.metrics.increment(Constants.CACHE_SET_TOTAL)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// if ttl is not set in action cache settings, use options ttl
|
|
99
|
+
if (ttl == null) {
|
|
100
|
+
ttl = options.ttl
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
storage.set(hashKey, {
|
|
104
|
+
data,
|
|
105
|
+
expire: ttl ? Date.now() + ttl : null
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
base.log.debug(`Set ${hashKey}`)
|
|
109
|
+
|
|
110
|
+
return Promise.resolve(data)
|
|
111
|
+
},
|
|
112
|
+
remove (hashKey) {
|
|
113
|
+
if (base.metrics) {
|
|
114
|
+
base.metrics.increment(Constants.CACHE_DELETED_TOTAL)
|
|
115
|
+
}
|
|
116
|
+
storage.delete(hashKey)
|
|
117
|
+
base.log.debug(`Delete ${hashKey}`)
|
|
118
|
+
|
|
119
|
+
return Promise.resolve()
|
|
120
|
+
},
|
|
121
|
+
clear (pattern = '**') {
|
|
122
|
+
if (base.metrics) {
|
|
123
|
+
base.metrics.increment(Constants.CACHE_DELETED_TOTAL)
|
|
124
|
+
}
|
|
125
|
+
storage.forEach((_, key) => {
|
|
126
|
+
if (match(key, pattern)) {
|
|
127
|
+
base.log.debug(`Delete ${key}`)
|
|
128
|
+
this.remove(key)
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
return Promise.resolve()
|
|
132
|
+
},
|
|
133
|
+
lock (key, ttl) {
|
|
134
|
+
return lock.acquire(key, ttl).then(() => {
|
|
135
|
+
return () => lock.release(key)
|
|
136
|
+
})
|
|
137
|
+
},
|
|
138
|
+
tryAcquireLock (key, ttl) {
|
|
139
|
+
if (lock.isLocked(key)) {
|
|
140
|
+
return Promise.reject(new Error('Locked'))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return lock.acquire(key, ttl).then(() => {
|
|
144
|
+
return () => lock.release(key)
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
async stop () {
|
|
148
|
+
clearInterval(ttlTimerHandle)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
return cache
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = { createInMemoryCache }
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
const { match } = require('@weave-js/utils')
|
|
8
8
|
const { createCacheBase } = require('./base')
|
|
9
|
-
const { createLock } = require('
|
|
10
|
-
const Constants = require('
|
|
9
|
+
const { createLock } = require('../lock')
|
|
10
|
+
const Constants = require('../../metrics/constants')
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
const
|
|
12
|
+
const createInMemoryLruCache = (adapterOptions) => (runtime, options = {}) => {
|
|
13
|
+
const name = 'In-Memory'
|
|
14
|
+
const base = createCacheBase(name, runtime, options)
|
|
14
15
|
const storage = new Map()
|
|
15
|
-
const name = 'Memory'
|
|
16
16
|
|
|
17
17
|
const lock = createLock()
|
|
18
18
|
|
|
@@ -121,7 +121,7 @@ const makeInMemoryCache = (runtime, options = {}) => {
|
|
|
121
121
|
return () => lock.release(key)
|
|
122
122
|
})
|
|
123
123
|
},
|
|
124
|
-
|
|
124
|
+
tryAcquireLock (key, ttl) {
|
|
125
125
|
if (lock.isLocked(key)) {
|
|
126
126
|
return Promise.reject(new Error('Locked'))
|
|
127
127
|
}
|
|
@@ -137,4 +137,4 @@ const makeInMemoryCache = (runtime, options = {}) => {
|
|
|
137
137
|
return cache
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
module.exports =
|
|
140
|
+
module.exports = { createInMemoryLruCache }
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Author: Kevin Ries (kevin@fachw3rk.de)
|
|
3
|
+
* -----
|
|
4
|
+
* Copyright 2021 Fachwerk
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
...require('./base'),
|
|
9
|
+
...require('./inMemory'),
|
|
10
|
+
...require('./inMemoryLru')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// exports.resolve = (cacheOptions) => {
|
|
14
|
+
// const getByName = name => {
|
|
15
|
+
// if (!name) {
|
|
16
|
+
// return null
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
// const n = Object
|
|
20
|
+
// .keys(adapters)
|
|
21
|
+
// .find(n => n.toLowerCase() === name.toLowerCase())
|
|
22
|
+
|
|
23
|
+
// if (n) {
|
|
24
|
+
// return adapters[n]
|
|
25
|
+
// }
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
// let cacheFactory
|
|
29
|
+
|
|
30
|
+
// if (cacheOptions === true) {
|
|
31
|
+
// cacheFactory = this.adapters.Memory
|
|
32
|
+
// } else if (isString(cacheOptions)) {
|
|
33
|
+
// const cache = getByName(cacheOptions)
|
|
34
|
+
|
|
35
|
+
// if (cache) {
|
|
36
|
+
// cacheFactory = cache()
|
|
37
|
+
// } else {
|
|
38
|
+
// throw new WeaveBrokerOptionsError(`Unknown cache type "${cacheOptions}"`)
|
|
39
|
+
// }
|
|
40
|
+
// } else if (isFunction(cacheOptions)) {
|
|
41
|
+
// cacheFactory = cacheOptions
|
|
42
|
+
// }
|
|
43
|
+
// if (cacheFactory) {
|
|
44
|
+
// return cacheFactory
|
|
45
|
+
// }
|
|
46
|
+
// }
|
package/lib/cache/base.js
CHANGED
|
@@ -4,8 +4,26 @@
|
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
6
6
|
const crypto = require('crypto')
|
|
7
|
-
const { isObject } = require('@weave-js/utils')
|
|
7
|
+
const { isObject, dotGet, isString } = require('@weave-js/utils')
|
|
8
8
|
const Constants = require('../metrics/constants')
|
|
9
|
+
const { WeaveError } = require('../errors')
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get property from data or metadata object.
|
|
13
|
+
* @param {any} data data object
|
|
14
|
+
* @param {object} metadata metadata object
|
|
15
|
+
* @param {string} key key
|
|
16
|
+
* @returns {any} Result
|
|
17
|
+
*/
|
|
18
|
+
function getPropertyFromDataOrMetadata (data, metadata, key) {
|
|
19
|
+
// if a key starts with ":", the property is picked from metadata
|
|
20
|
+
if (key.startsWith(':')) {
|
|
21
|
+
// remove ':' from key.
|
|
22
|
+
key = key.replace(':', '')
|
|
23
|
+
return dotGet(metadata, key)
|
|
24
|
+
}
|
|
25
|
+
return dotGet(data, key)
|
|
26
|
+
}
|
|
9
27
|
|
|
10
28
|
function getCacheKeyByObject (val) {
|
|
11
29
|
if (Array.isArray(val)) {
|
|
@@ -37,8 +55,13 @@ function registerCacheMetrics (metrics) {
|
|
|
37
55
|
metrics.register({ type: 'counter', name: Constants.CACHE_CLEANED_TOTAL })
|
|
38
56
|
}
|
|
39
57
|
|
|
40
|
-
exports.createCacheBase = (runtime, options) => {
|
|
58
|
+
exports.createCacheBase = (name, runtime, options) => {
|
|
59
|
+
if (!isString(name)) {
|
|
60
|
+
throw new WeaveError('Name needs to be a string.')
|
|
61
|
+
}
|
|
62
|
+
|
|
41
63
|
const cache = {
|
|
64
|
+
name,
|
|
42
65
|
isConnected: false,
|
|
43
66
|
runtime,
|
|
44
67
|
options: Object.assign({
|
|
@@ -72,20 +95,22 @@ exports.createCacheBase = (runtime, options) => {
|
|
|
72
95
|
/* istanbul ignore next */
|
|
73
96
|
return Promise.resolve()
|
|
74
97
|
},
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
const prefix =
|
|
98
|
+
getCachingKey (actionName, data, metadata, keys) {
|
|
99
|
+
if (data || metadata) {
|
|
100
|
+
const prefix = actionName + ':'
|
|
78
101
|
|
|
79
102
|
if (keys) {
|
|
103
|
+
// fast path for single keys
|
|
80
104
|
if (keys.length === 1) {
|
|
81
|
-
const value =
|
|
105
|
+
const value = getPropertyFromDataOrMetadata(data, metadata, keys[0])
|
|
82
106
|
const key = getCacheKeyByObject(value)
|
|
83
107
|
return prefix + (isObject(value) ? key : value)
|
|
84
108
|
}
|
|
85
109
|
|
|
110
|
+
// Handle data cache keys
|
|
86
111
|
if (keys.length > 0) {
|
|
87
|
-
const res = keys.reduce((pre, property,
|
|
88
|
-
const value =
|
|
112
|
+
const res = keys.reduce((pre, property, index) => {
|
|
113
|
+
const value = getPropertyFromDataOrMetadata(data, metadata, property)
|
|
89
114
|
let hash
|
|
90
115
|
if (isObject(value)) {
|
|
91
116
|
const key = getCacheKeyByObject(value)
|
|
@@ -94,12 +119,12 @@ exports.createCacheBase = (runtime, options) => {
|
|
|
94
119
|
hash = value
|
|
95
120
|
}
|
|
96
121
|
|
|
97
|
-
return pre + (
|
|
122
|
+
return pre + (index > 0 ? '|' : '') + hash
|
|
98
123
|
}, prefix)
|
|
99
124
|
return res
|
|
100
125
|
}
|
|
101
126
|
} else {
|
|
102
|
-
return prefix + generateHash(getCacheKeyByObject(
|
|
127
|
+
return prefix + generateHash(getCacheKeyByObject(data))
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
130
|
|
|
@@ -107,41 +132,5 @@ exports.createCacheBase = (runtime, options) => {
|
|
|
107
132
|
}
|
|
108
133
|
}
|
|
109
134
|
|
|
110
|
-
// cache.middleware = (runtime) => {
|
|
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 = runtime.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
|
-
// if (runtime.cache.isConnected === false) {
|
|
124
|
-
// runtime.cache.log('Cache adapter is not connected yet. Call handler...')
|
|
125
|
-
// return handler(context, serviceInjections)
|
|
126
|
-
// }
|
|
127
|
-
|
|
128
|
-
// return runtime.cache.get(cacheHashKey).then((cachedResult) => {
|
|
129
|
-
// if (cachedResult !== null) {
|
|
130
|
-
// context.isCachedResult = true
|
|
131
|
-
// return cachedResult
|
|
132
|
-
// }
|
|
133
|
-
|
|
134
|
-
// return handler(context, serviceInjections).then((result) => {
|
|
135
|
-
// runtime.cache.set(cacheHashKey, result, action.cache.ttl)
|
|
136
|
-
// return result
|
|
137
|
-
// })
|
|
138
|
-
// })
|
|
139
|
-
// }
|
|
140
|
-
// }
|
|
141
|
-
// return handler
|
|
142
|
-
// }
|
|
143
|
-
// }
|
|
144
|
-
// }
|
|
145
|
-
|
|
146
135
|
return cache
|
|
147
136
|
}
|
package/lib/index.js
CHANGED
|
@@ -45,17 +45,16 @@ exports.Errors = require('./errors')
|
|
|
45
45
|
|
|
46
46
|
exports.Constants = require('./constants')
|
|
47
47
|
|
|
48
|
-
// Transport
|
|
49
|
-
exports.TransportAdapters = require('./transport/adapters')
|
|
50
|
-
|
|
51
48
|
// Caching
|
|
52
|
-
exports.Cache = require('./cache')
|
|
49
|
+
exports.Cache = require('./cache/adapters')
|
|
53
50
|
|
|
54
51
|
/**
|
|
55
52
|
* @deprecated since version 0.10.0
|
|
56
53
|
*/
|
|
57
54
|
exports.createBaseTracingCollector = require('./tracing/collectors/base').createBaseTracingCollector
|
|
55
|
+
exports.TransportAdapters = require('./transport/adapters')
|
|
58
56
|
exports.TracingAdapters = require('./tracing/collectors')
|
|
57
|
+
exports.CacheAdapters = require('./cache/adapters')
|
|
59
58
|
|
|
60
59
|
// Helper
|
|
61
60
|
exports.defineBrokerOptions = require('./helper/defineBrokerOptions')
|
|
@@ -1,36 +1,62 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { isString, isFunction } = require('@weave-js/utils')
|
|
2
2
|
|
|
3
3
|
module.exports = (runtime) => {
|
|
4
4
|
return {
|
|
5
5
|
localAction: (handler, action) => {
|
|
6
|
-
const cacheOptions =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
|
|
11
21
|
return function cacheMiddleware (context, serviceInjections) {
|
|
12
|
-
|
|
13
|
-
|
|
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
|
+
|
|
14
38
|
context.isCachedResult = false
|
|
15
39
|
|
|
40
|
+
// Disable caching by meta property.
|
|
16
41
|
if (context.meta.$noCache === true) {
|
|
17
42
|
return handler(context, serviceInjections)
|
|
18
43
|
}
|
|
19
44
|
|
|
45
|
+
// The cache adapter is not connected yet. In this case, we call the handler regular
|
|
20
46
|
if (cache.isConnected === false) {
|
|
21
47
|
cache.log('Cache adapter is not connected yet. Call handler...')
|
|
22
48
|
return handler(context, serviceInjections)
|
|
23
49
|
}
|
|
24
50
|
|
|
25
51
|
if (cacheOptions.lock.enabled) {
|
|
26
|
-
let
|
|
52
|
+
let cachePromise
|
|
27
53
|
if (cacheOptions.lock.staleTime && cache.getWithTTl) {
|
|
28
54
|
|
|
29
55
|
} else {
|
|
30
|
-
|
|
56
|
+
cachePromise = runtime.cache.get(cacheHashKey)
|
|
31
57
|
}
|
|
32
58
|
|
|
33
|
-
return
|
|
59
|
+
return cachePromise.then((cachedResult) => {
|
|
34
60
|
if (cachedResult !== null) {
|
|
35
61
|
// Found a cached value. Skip calling handler and return our value
|
|
36
62
|
context.isCachedResult = true
|
package/lib/registry/registry.js
CHANGED
|
@@ -147,19 +147,22 @@ exports.createRegistry = (runtime) => {
|
|
|
147
147
|
|
|
148
148
|
// remove old services
|
|
149
149
|
const oldServices = Array.from(this.serviceCollection.services)
|
|
150
|
-
oldServices.forEach((
|
|
151
|
-
if (
|
|
150
|
+
oldServices.forEach((oldService) => {
|
|
151
|
+
if (oldService.node.id !== node.id) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
152
154
|
|
|
153
155
|
let isExisting = false
|
|
154
156
|
|
|
157
|
+
// check if the old service exists in the new services.
|
|
155
158
|
services.forEach((svc) => {
|
|
156
|
-
if (
|
|
159
|
+
if (oldService.equals(svc.name, svc.version)) {
|
|
157
160
|
isExisting = true
|
|
158
161
|
}
|
|
159
162
|
})
|
|
160
163
|
|
|
161
164
|
if (!isExisting) {
|
|
162
|
-
this.deregisterService(
|
|
165
|
+
this.deregisterService(oldService.name, oldService.version, node.id)
|
|
163
166
|
}
|
|
164
167
|
})
|
|
165
168
|
|
|
@@ -186,9 +189,9 @@ exports.createRegistry = (runtime) => {
|
|
|
186
189
|
}
|
|
187
190
|
|
|
188
191
|
if (node.isLocal) {
|
|
189
|
-
action.handler = middlewareHandler.wrapHandler('localAction', action.handler, action)
|
|
192
|
+
action.handler = middlewareHandler.wrapHandler('localAction', action.handler, action)
|
|
190
193
|
} else {
|
|
191
|
-
action.handler = middlewareHandler.wrapHandler('remoteAction', runtime.transport.sendRequest.bind(runtime.transport), action)
|
|
194
|
+
action.handler = middlewareHandler.wrapHandler('remoteAction', runtime.transport.sendRequest.bind(runtime.transport), action)
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
this.actionCollection.add(node, service, action)
|
|
@@ -196,13 +199,10 @@ exports.createRegistry = (runtime) => {
|
|
|
196
199
|
service.addAction(action)
|
|
197
200
|
})
|
|
198
201
|
},
|
|
199
|
-
getActionList (options) {
|
|
200
|
-
return this.actionCollection.list(options)
|
|
201
|
-
},
|
|
202
202
|
deregisterService (name, version, nodeId) {
|
|
203
203
|
this.serviceCollection.remove(nodeId || runtime.nodeId, name, version)
|
|
204
204
|
|
|
205
|
-
// It must be a local service
|
|
205
|
+
// It must be a local service if there is no node ID.
|
|
206
206
|
if (!nodeId) {
|
|
207
207
|
const serviceToRemove = this.nodeCollection.localNode.services.find(service => service.name === name)
|
|
208
208
|
this.nodeCollection.localNode.services.splice(this.nodeCollection.localNode.services.indexOf(serviceToRemove), 1)
|
|
@@ -386,12 +386,6 @@ exports.createRegistry = (runtime) => {
|
|
|
386
386
|
this.nodeCollection.remove(nodeId)
|
|
387
387
|
runtime.eventBus.broadcastLocal('$node.removed', { nodeId })
|
|
388
388
|
this.log.warn(`Node "${nodeId}" removed.`)
|
|
389
|
-
},
|
|
390
|
-
getNodeList (options) {
|
|
391
|
-
return this.nodeCollection.list(options)
|
|
392
|
-
},
|
|
393
|
-
getServiceList (options) {
|
|
394
|
-
return this.serviceCollection.list(options)
|
|
395
389
|
}
|
|
396
390
|
}
|
|
397
391
|
|
package/lib/runtime/initCache.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { isFunction } = require('@weave-js/utils')
|
|
2
|
+
const { WeaveError } = require('../errors')
|
|
2
3
|
|
|
3
4
|
exports.initCache = (runtime) => {
|
|
4
5
|
if (runtime.options.cache && runtime.options.cache.enabled) {
|
|
5
|
-
|
|
6
|
+
if (!isFunction(runtime.options.cache.adapter)) {
|
|
7
|
+
throw new WeaveError('Invalid cache adapter.')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Init cache adapter
|
|
11
|
+
const cache = runtime.options.cache.adapter(runtime, runtime.options.cache)
|
|
12
|
+
|
|
13
|
+
runtime.log.info(`Cache: ${cache.name}`)
|
|
14
|
+
|
|
6
15
|
Object.defineProperty(runtime, 'cache', {
|
|
7
|
-
value:
|
|
16
|
+
value: cache
|
|
8
17
|
})
|
|
9
18
|
}
|
|
10
19
|
}
|
package/lib/types.js
CHANGED
|
@@ -22,7 +22,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
22
22
|
/**
|
|
23
23
|
* @callback CallActionFunctionDef - Action function definition
|
|
24
24
|
* @param {string} actionName - Name of the action
|
|
25
|
-
* @param {object} data - Payload
|
|
25
|
+
* @param {object} [data] - Payload
|
|
26
26
|
* @param {ActionOptions} [options] - Action options
|
|
27
27
|
* @return {Promise<any>} Promise - Result
|
|
28
28
|
*/
|
|
@@ -127,7 +127,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
127
127
|
* @property {function(string, any, any=):Promise<any>} emit - Emit
|
|
128
128
|
* @property {function(string, any, any=):Promise<any>} broadcast broadcast
|
|
129
129
|
* @property {function(string, any, any=):Promise<any>} broadcastLocal broadcastLocal
|
|
130
|
-
* @property {function(string):Promise<any>} waitForServices waitForServices
|
|
130
|
+
* @property {function(Array<string>|string):Promise<any>} waitForServices waitForServices
|
|
131
131
|
* @property {function(string, number=):Promise<PingResult>} ping ping
|
|
132
132
|
* @property {function(Error):void} handleError handleError
|
|
133
133
|
* @property {function():void} fatalError fatalError
|
|
@@ -169,7 +169,13 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
169
169
|
* @property {Boolean} enabled - Enable tracing middleware. (default = false)
|
|
170
170
|
* @property {Number} samplingRate - Rate of traced actions. (default = 1.0)
|
|
171
171
|
* @property {Array<String|Object>} collectors - Array of tracing collectors.
|
|
172
|
-
* @property {TracingErrorOptions} errors - Settings for tracing errors.
|
|
172
|
+
* @property {TracingErrorOptions} [errors] - Settings for tracing errors.
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Configuration object for weave service broker.
|
|
177
|
+
* @typedef {Object} CacheLockOptions
|
|
178
|
+
* @property {Boolean} [enabled=false] Enable cache lock. (default = false)
|
|
173
179
|
*/
|
|
174
180
|
|
|
175
181
|
/**
|
|
@@ -178,6 +184,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
178
184
|
* @property {Boolean} enabled Enable cache middleware. (default = false)
|
|
179
185
|
* @property {String | Object} adapter - Cache adapter. (default = memory (In Memory))
|
|
180
186
|
* @property {number} [ttl=3000] - Cache item TTL.
|
|
187
|
+
* @property {CacheLockOptions} [lock] Cache lock options.
|
|
181
188
|
*/
|
|
182
189
|
|
|
183
190
|
/**
|
|
@@ -328,7 +335,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
328
335
|
* @property {number} stopTime stopTime
|
|
329
336
|
* @property {any} [metrics] metrics
|
|
330
337
|
* @property {function(any):void} setData - Set data object.
|
|
331
|
-
* @property {
|
|
338
|
+
* @property {CallActionFunctionDef} call - Call a service action
|
|
332
339
|
* @property {function(string, object):Promise<any>} emit emit
|
|
333
340
|
* @property {Stream} [stream] - Stream
|
|
334
341
|
* @property {function(string, any):Promise<any>} broadcast Broadcast an event to all listener.
|
|
@@ -350,7 +357,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
350
357
|
* @property {Promise<any>} get get
|
|
351
358
|
* @property {Promise<any>} remove remove
|
|
352
359
|
* @property {Promise<any>} clear clear
|
|
353
|
-
* @property {string}
|
|
360
|
+
* @property {string} getCachingKey getCachingKey
|
|
354
361
|
* @property {function():Middleware} createMiddleware createMiddleware
|
|
355
362
|
* @property {function():Promise<any>} stop stop
|
|
356
363
|
*/
|
|
@@ -482,7 +489,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
482
489
|
* @property {function(string):Endpoint} getLocalActionEndpoint getLocalActionEndpoint
|
|
483
490
|
* @property {function():NodeInfo} getNodeInfo getNodeInfo
|
|
484
491
|
* @property {function():NodeInfo} getLocalNodeInfo getLocalNodeInfo
|
|
485
|
-
* @property {function():NodeInfo} generateLocalNodeInfo generateLocalNodeInfo
|
|
492
|
+
* @property {function(Boolean=):NodeInfo} generateLocalNodeInfo generateLocalNodeInfo
|
|
486
493
|
* @property {*} processNodeInfo processNodeInfo
|
|
487
494
|
* @property {function(string, boolean):void} nodeDisconnected nodeDisconnected
|
|
488
495
|
* @property {function(string):void} removeNode removeNode
|
|
@@ -507,6 +514,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
507
514
|
* @property {function():number} count count
|
|
508
515
|
* @property {function(string):Endpoint} getByNodeId getByNodeId
|
|
509
516
|
* @property {function(string):void} removeByNodeId removeByNodeId
|
|
517
|
+
* @property {function(string):Endpoint} endpointByNodeId Get endpoint by node ID.
|
|
510
518
|
* @property {function():void} removeByService removeByService
|
|
511
519
|
*/
|
|
512
520
|
|
|
@@ -522,6 +530,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
522
530
|
* @property {number} lastHeartbeatTime lastHeartbeatTime
|
|
523
531
|
* @property {number} offlineTime offlineTime
|
|
524
532
|
* @property {boolean} isAvailable isAvailable
|
|
533
|
+
* @property {boolean} wasDisconnectedUnexpectedly Node was disconnected unexpectedly
|
|
525
534
|
* @property {Array<ServiceItem>} services services
|
|
526
535
|
* @property {number} sequence sequence
|
|
527
536
|
* @property {Array<string>} [events] events
|
|
@@ -561,7 +570,8 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
561
570
|
|
|
562
571
|
/**
|
|
563
572
|
* @typedef {object} NodeCollectionListFilterOptions
|
|
564
|
-
* @property {boolean} [
|
|
573
|
+
* @property {boolean} [availableOnly=false] Git only available nodes.
|
|
574
|
+
* @property {boolean} [withServices=false] Output all services on an node.
|
|
565
575
|
*/
|
|
566
576
|
|
|
567
577
|
/**
|
|
@@ -575,14 +585,14 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
575
585
|
* @property {boolean} has has
|
|
576
586
|
* @property {function(string):Node} get get
|
|
577
587
|
* @property {function(string):boolean} remove remove
|
|
578
|
-
* @property {function(NodeCollectionListFilterOptions):Array<Node>} list list
|
|
588
|
+
* @property {function(NodeCollectionListFilterOptions=):Array<Node>} list list
|
|
579
589
|
* @property {void} disconnected disconnected
|
|
580
590
|
* @property {Array<Node>} toArray toArray
|
|
581
591
|
*/
|
|
582
592
|
|
|
583
593
|
/**
|
|
584
594
|
* @typedef {Object} ServiceActionCollectionListFilterParams
|
|
585
|
-
* @property {boolean} [
|
|
595
|
+
* @property {boolean} [localOnly] Shows only local service actions
|
|
586
596
|
* @property {boolean} [skipInternals] Shows only local service actions
|
|
587
597
|
* @property {boolean} [withEndpoints] Shows only local service actions
|
|
588
598
|
*/
|
|
@@ -617,6 +627,7 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
617
627
|
/**
|
|
618
628
|
* @typedef {Object} ServiceCollectionListFilterParams
|
|
619
629
|
* @property {boolean} [localOnly=false] Show only local services.
|
|
630
|
+
* @property {boolean} [availableOnly=false] Show only available services.
|
|
620
631
|
* @property {boolean} [withActions=false] Include actions in result.
|
|
621
632
|
* @property {boolean} [withEvents=false] Include events in result.
|
|
622
633
|
* @property {boolean} [withNodeService=false] Include node service.
|
|
@@ -630,8 +641,8 @@ const { EventEmitter2: EventEmitter } = require('eventemitter2')
|
|
|
630
641
|
* @property {function(Node,string, number, any):ServiceItem} add Add a new service to service collection.
|
|
631
642
|
* @property {*} get get
|
|
632
643
|
* @property {function(string, number, string):boolean} has has
|
|
633
|
-
* @property {function(string, string, number):void} remove
|
|
634
|
-
* @property {function(string):void} removeAllByNodeId
|
|
644
|
+
* @property {function(string, string, number=):void} remove Remove endpoint by node ID, service name and version*.
|
|
645
|
+
* @property {function(string):void} removeAllByNodeId Remove all endpoints by node ID.
|
|
635
646
|
* @property {*} registerAction registerAction
|
|
636
647
|
* @property {function(string):EndpointCollection} tryFindActionsByActionName tryFindActionsByActionName
|
|
637
648
|
* @property {function():Array<any>} getActionsList getActionsList
|
package/lib/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weave-js/core",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "The core package of weave",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Weave",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"license": "MIT",
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@weave-js/errors": "^0.9.1",
|
|
43
|
-
"@weave-js/utils": "^0.10.
|
|
44
|
-
"@weave-js/validator": "^0.11.
|
|
43
|
+
"@weave-js/utils": "^0.10.1",
|
|
44
|
+
"@weave-js/validator": "^0.11.1",
|
|
45
45
|
"eventemitter2": "^6.4.5",
|
|
46
46
|
"glob": "^7.2.0"
|
|
47
47
|
},
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"lib": "lib",
|
|
50
50
|
"test": "test"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "bc467dd08fe0626c40e7eb19b344c102386baf15"
|
|
53
53
|
}
|
package/lib/cache/index.js
DELETED
|
@@ -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('./inMemory')
|
|
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
|
-
}
|