@autofleet/matmon 2.0.4-beta-3 → 2.0.4
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/cache.js +1 -1
- package/lib/orm-cache/sequelize-adapter.js +37 -42
- package/package.json +1 -2
package/lib/cache.js
CHANGED
|
@@ -37,7 +37,7 @@ const locking = __importStar(require("./locking"));
|
|
|
37
37
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
38
38
|
dotenv_1.default.config();
|
|
39
39
|
const DEFAULT_CACHE_SIZE = 300;
|
|
40
|
-
const MAX_SIZE =
|
|
40
|
+
const MAX_SIZE = 100000;
|
|
41
41
|
const MUTEX_MAP = {};
|
|
42
42
|
const getOptions = ({ lifeTimeInSec, size = DEFAULT_CACHE_SIZE, }) => ({
|
|
43
43
|
max: Math.min(size, MAX_SIZE),
|
|
@@ -12,15 +12,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const newrelic_1 = __importDefault(require("newrelic"));
|
|
16
15
|
const logger_1 = __importDefault(require("../logger"));
|
|
17
16
|
const util_1 = require("util");
|
|
18
17
|
const { AF_SERVICE_NAME } = process.env;
|
|
19
18
|
const ORM_CACHE_PREFIX = 'ormCache';
|
|
20
|
-
const INVALIDATION_HOOKS = ['afterUpdate', 'afterDestroy'];
|
|
19
|
+
const INVALIDATION_HOOKS = ['afterSave', 'afterUpdate', 'afterDestroy'];
|
|
20
|
+
const BULK_HOOKS = ['beforeBulkUpdate', 'beforeBulkDestroy'];
|
|
21
21
|
const generateInstanceKey = (name, id) => `${AF_SERVICE_NAME}:${ORM_CACHE_PREFIX}:${name}_${id}`;
|
|
22
22
|
const generateDependencyKey = (modelName, associationName, associationId) => `${AF_SERVICE_NAME}:${ORM_CACHE_PREFIX}:${modelName}_${associationName}_${associationId}_DEPENDENCIES`;
|
|
23
|
-
const getInstanceDependencyKeys = (modelOptions, instance) =>
|
|
23
|
+
const getInstanceDependencyKeys = (modelOptions, instance) => {
|
|
24
24
|
const keys = modelOptions.associations
|
|
25
25
|
.filter((associationOptions) => instance[associationOptions.alias])
|
|
26
26
|
.map((associationOptions) => {
|
|
@@ -41,17 +41,11 @@ const getInstanceDependencyKeys = (modelOptions, instance) => newrelic_1.default
|
|
|
41
41
|
];
|
|
42
42
|
});
|
|
43
43
|
return keys.reduce((flattenArray, array) => flattenArray.concat(array), []);
|
|
44
|
-
}
|
|
44
|
+
};
|
|
45
45
|
const handleTransactionHook = (instance, options, func) => {
|
|
46
46
|
const { transaction } = options;
|
|
47
47
|
if (transaction) {
|
|
48
|
-
|
|
49
|
-
transaction[ORM_CACHE_PREFIX] = new Set();
|
|
50
|
-
}
|
|
51
|
-
if (!transaction[ORM_CACHE_PREFIX].has(instance.id)) {
|
|
52
|
-
transaction.afterCommit(() => func(instance));
|
|
53
|
-
transaction[ORM_CACHE_PREFIX].add(instance.id);
|
|
54
|
-
}
|
|
48
|
+
transaction.afterCommit(() => func(instance));
|
|
55
49
|
}
|
|
56
50
|
else {
|
|
57
51
|
func(instance);
|
|
@@ -66,28 +60,26 @@ class SequelizeAdapter {
|
|
|
66
60
|
return this.ormInstance.models[modelName];
|
|
67
61
|
}
|
|
68
62
|
getModelDependencies(modelName) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
const { associations } = this.ormInstance.models[modelName];
|
|
64
|
+
return [
|
|
65
|
+
...Object.keys(associations).map(association => {
|
|
66
|
+
const sequelizeAssociation = associations[association];
|
|
67
|
+
const associationOptions = {
|
|
68
|
+
alias: sequelizeAssociation.as,
|
|
69
|
+
name: sequelizeAssociation.target.name,
|
|
70
|
+
accessKey: sequelizeAssociation.target.primaryKeyAttribute,
|
|
71
|
+
};
|
|
72
|
+
if (sequelizeAssociation.through) {
|
|
73
|
+
const relationModel = sequelizeAssociation.through.model;
|
|
74
|
+
associationOptions.innerAssociation = {
|
|
75
|
+
alias: relationModel.name,
|
|
76
|
+
name: relationModel.name,
|
|
77
|
+
accessKey: relationModel.primaryKeyAttribute,
|
|
78
78
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
name: relationModel.name,
|
|
84
|
-
accessKey: relationModel.primaryKeyAttribute,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
return associationOptions;
|
|
88
|
-
}),
|
|
89
|
-
];
|
|
90
|
-
});
|
|
79
|
+
}
|
|
80
|
+
return associationOptions;
|
|
81
|
+
}),
|
|
82
|
+
];
|
|
91
83
|
}
|
|
92
84
|
debug(message, payload) {
|
|
93
85
|
if (this.debugMode) {
|
|
@@ -95,7 +87,7 @@ class SequelizeAdapter {
|
|
|
95
87
|
}
|
|
96
88
|
}
|
|
97
89
|
injectGetWithCacheFunction(cache, modelOptions) {
|
|
98
|
-
const addDependencies = (instance) =>
|
|
90
|
+
const addDependencies = (instance) => __awaiter(this, void 0, void 0, function* () {
|
|
99
91
|
const dependencyKeys = getInstanceDependencyKeys(modelOptions, instance);
|
|
100
92
|
const instanceKey = generateInstanceKey(modelOptions.name, instance.id);
|
|
101
93
|
this.debug('Adding dependencies', { instanceKey, dependencyKeys });
|
|
@@ -125,19 +117,19 @@ class SequelizeAdapter {
|
|
|
125
117
|
});
|
|
126
118
|
}
|
|
127
119
|
addInvalidationHooks(cache, modelOptions) {
|
|
128
|
-
const invalidateModelInstance = (
|
|
120
|
+
const invalidateModelInstance = (instance) => __awaiter(this, void 0, void 0, function* () {
|
|
129
121
|
const dependencyKeys = getInstanceDependencyKeys(modelOptions, instance);
|
|
130
122
|
const instanceKey = generateInstanceKey(modelOptions.name, instance.id);
|
|
131
|
-
this.debug(
|
|
123
|
+
this.debug('Removing dependencies', { instance, instanceKey, dependencyKeys });
|
|
132
124
|
const removeMulti = cache.getClient().multi();
|
|
133
125
|
const removeMultiAsync = util_1.promisify(removeMulti.exec).bind(removeMulti);
|
|
134
126
|
dependencyKeys.map(key => removeMulti.srem(key, instanceKey));
|
|
135
127
|
removeMulti.del(instanceKey);
|
|
136
128
|
return removeMultiAsync();
|
|
137
129
|
});
|
|
138
|
-
const invalidateModelInstanceByAssociation = (
|
|
130
|
+
const invalidateModelInstanceByAssociation = (association, associationId) => __awaiter(this, void 0, void 0, function* () {
|
|
139
131
|
const dependentInstancesKeys = yield cache.getClient().smembersAsync(generateDependencyKey(modelOptions.name, association, associationId));
|
|
140
|
-
this.debug(
|
|
132
|
+
this.debug('Invalidating dependent instances', { dependentInstancesKeys });
|
|
141
133
|
const removeMulti = cache.getClient().multi();
|
|
142
134
|
const removeMultiAsync = util_1.promisify(removeMulti.exec).bind(removeMulti);
|
|
143
135
|
const dependenciesToRemove = yield Promise.all(dependentInstancesKeys.map((instanceKey) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -150,19 +142,22 @@ class SequelizeAdapter {
|
|
|
150
142
|
removeMulti.del(instanceKey);
|
|
151
143
|
return dependencyKeys;
|
|
152
144
|
})));
|
|
153
|
-
this.debug(
|
|
145
|
+
this.debug('Removing dependencies', { dependentInstancesKeys, dependenciesToRemove });
|
|
154
146
|
return removeMultiAsync();
|
|
155
|
-
})
|
|
147
|
+
});
|
|
156
148
|
const model = this.getModel(modelOptions.name);
|
|
157
|
-
INVALIDATION_HOOKS.map(hook => model.addHook(hook, (instance, options) => handleTransactionHook(instance, options, instance => invalidateModelInstance(
|
|
149
|
+
INVALIDATION_HOOKS.map(hook => model.addHook(hook, (instance, options) => handleTransactionHook(instance, options, instance => invalidateModelInstance(instance))));
|
|
150
|
+
BULK_HOOKS.map(hook => model.addHook(hook, options => options.individualHook = true));
|
|
158
151
|
modelOptions.associations = this.getModelDependencies(modelOptions.name);
|
|
159
152
|
this.debug(`Adding Invalidations Hooks to ${modelOptions.name}'s associations`, { associations: modelOptions.associations });
|
|
160
153
|
modelOptions.associations.map((associationOptions) => {
|
|
161
154
|
const associationModel = this.getModel(associationOptions.name);
|
|
162
|
-
INVALIDATION_HOOKS.map(hook => associationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, associationInstance => invalidateModelInstanceByAssociation(
|
|
155
|
+
INVALIDATION_HOOKS.map(hook => associationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, associationInstance => invalidateModelInstanceByAssociation(associationOptions.name, associationInstance[associationOptions.accessKey]))));
|
|
156
|
+
BULK_HOOKS.map(hook => associationModel.addHook(hook, options => options.individualHook = true));
|
|
163
157
|
if (associationOptions.innerAssociation) {
|
|
164
158
|
const innerAssociationModel = this.getModel(associationOptions.innerAssociation.name);
|
|
165
|
-
INVALIDATION_HOOKS.map(hook => innerAssociationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, innerAssociationInstance => invalidateModelInstanceByAssociation(
|
|
159
|
+
INVALIDATION_HOOKS.map(hook => innerAssociationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, innerAssociationInstance => invalidateModelInstanceByAssociation(associationOptions.innerAssociation.name, innerAssociationInstance[associationOptions.innerAssociation.accessKey]))));
|
|
160
|
+
BULK_HOOKS.map(hook => innerAssociationModel.addHook(hook, options => options.individualHook = true));
|
|
166
161
|
}
|
|
167
162
|
});
|
|
168
163
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/matmon",
|
|
3
|
-
"version": "2.0.4
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "manage cache",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
"bluebird": "^3.7.2",
|
|
33
33
|
"dotenv": "^8.2.0",
|
|
34
34
|
"lru-cache": "^6.0.0",
|
|
35
|
-
"newrelic": "^7.5.2",
|
|
36
35
|
"redis": "^3.0.2",
|
|
37
36
|
"redis-lock": "^0.1.4",
|
|
38
37
|
"sequelize": "^6.6.2",
|