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