jxp 2.13.0 → 2.13.2
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/docs/caching.md +1 -0
- package/libs/cache.js +51 -16
- package/libs/jxp.js +14 -13
- package/mkdocs.yml +1 -0
- package/package.json +1 -1
- package/test/init.js +2 -0
- package/test/test.js +115 -4
package/docs/caching.md
CHANGED
package/libs/cache.js
CHANGED
|
@@ -2,46 +2,81 @@ const NodeCache = require('node-cache');
|
|
|
2
2
|
const config = require('config');
|
|
3
3
|
const cache = new NodeCache({ stdTTL: config.cache?.ttl || 5 * 60 });
|
|
4
4
|
|
|
5
|
-
const generateKey = (req) => {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const generateKey = (req, res) => {
|
|
6
|
+
if (res.jxp_cache_key) return res.jxp_cache_key;
|
|
7
|
+
let key = `${req.modelname}/`;
|
|
8
|
+
if (req.params.item_id) {
|
|
9
|
+
key += `${req.params.item_id}`
|
|
10
|
+
}
|
|
11
|
+
if (req.query) {
|
|
12
|
+
key += `?${JSON.stringify(req.query)}`
|
|
13
|
+
}
|
|
14
|
+
res.jxp_cache_key = key;
|
|
15
|
+
return key;
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
const set = (req, res
|
|
11
|
-
if (!config.cache?.enabled) return
|
|
12
|
-
const key = generateKey(req)
|
|
18
|
+
const set = async (req, res) => {
|
|
19
|
+
if (!config.cache?.enabled) return;
|
|
20
|
+
const key = generateKey(req, res)
|
|
13
21
|
cache.set(key, res.result)
|
|
14
|
-
|
|
22
|
+
if (config.cache?.debug) {
|
|
23
|
+
console.log('cache set', key)
|
|
24
|
+
}
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
const get = (req, res, next) => {
|
|
18
|
-
if (!config.cache?.enabled) return
|
|
19
|
-
const key = generateKey(req)
|
|
28
|
+
if (!config.cache?.enabled) return;
|
|
29
|
+
const key = generateKey(req, res)
|
|
30
|
+
res.header('jxp-cache-key', key);
|
|
20
31
|
const cached = cache.get(key)
|
|
21
32
|
if (cached) {
|
|
33
|
+
if (config.cache?.debug) {
|
|
34
|
+
console.log('cache hit', key)
|
|
35
|
+
}
|
|
22
36
|
res.header('jxp-cache', 'hit')
|
|
23
37
|
res.result = cached
|
|
24
38
|
return res.send(res.result)
|
|
25
39
|
}
|
|
40
|
+
if (config.cache?.debug) {
|
|
41
|
+
console.log('cache miss', key)
|
|
42
|
+
}
|
|
26
43
|
res.header('jxp-cache', 'miss')
|
|
27
44
|
next()
|
|
28
45
|
}
|
|
29
46
|
|
|
30
|
-
const clear = (req, res
|
|
31
|
-
if (!config.cache?.enabled) return
|
|
47
|
+
const clear = async (req, res) => {
|
|
48
|
+
if (!config.cache?.enabled) return;
|
|
49
|
+
const keys = cache.keys()
|
|
50
|
+
keys.forEach(key => {
|
|
51
|
+
if (key.startsWith(`${req.modelname}/`)) {
|
|
52
|
+
if (config.cache?.debug) {
|
|
53
|
+
console.log('cache del', key)
|
|
54
|
+
}
|
|
55
|
+
cache.del(key)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const clearAll = async () => {
|
|
61
|
+
if (!config.cache?.enabled) return;
|
|
62
|
+
if (config.cache?.debug) {
|
|
63
|
+
console.log('cache flushAll')
|
|
64
|
+
}
|
|
32
65
|
cache.flushAll()
|
|
33
|
-
next()
|
|
34
66
|
}
|
|
35
67
|
|
|
36
|
-
const stats = (req, res
|
|
37
|
-
if (!config.cache?.enabled)
|
|
68
|
+
const stats = async (req, res) => {
|
|
69
|
+
if (!config.cache?.enabled) {
|
|
70
|
+
res.result = { cache_enabled: false }
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
38
73
|
res.result = cache.getStats()
|
|
39
|
-
next()
|
|
40
74
|
}
|
|
41
75
|
|
|
42
76
|
module.exports = {
|
|
43
77
|
set,
|
|
44
78
|
get,
|
|
45
79
|
clear,
|
|
46
|
-
|
|
80
|
+
clearAll,
|
|
81
|
+
stats,
|
|
47
82
|
}
|
package/libs/jxp.js
CHANGED
|
@@ -54,10 +54,9 @@ const middlewareCheckAdmin = (req, res, next) => {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
// Outputs whatever is in res.result as JSON
|
|
57
|
-
const outputJSON = (req, res
|
|
57
|
+
const outputJSON = async (req, res) => {
|
|
58
58
|
try {
|
|
59
59
|
res.send(res.result);
|
|
60
|
-
next();
|
|
61
60
|
} catch (err) {
|
|
62
61
|
console.error(new Date(), err);
|
|
63
62
|
throw new errors.InternalServerError(err.toString());
|
|
@@ -919,7 +918,6 @@ const JXP = function(options) {
|
|
|
919
918
|
middlewareModel,
|
|
920
919
|
security.login,
|
|
921
920
|
security.auth,
|
|
922
|
-
cache.get,
|
|
923
921
|
config.pre_hooks.getOne,
|
|
924
922
|
cache.get,
|
|
925
923
|
actionGetOne,
|
|
@@ -934,7 +932,7 @@ const JXP = function(options) {
|
|
|
934
932
|
middlewarePasswords,
|
|
935
933
|
config.pre_hooks.post,
|
|
936
934
|
actionPost,
|
|
937
|
-
cache.
|
|
935
|
+
cache.clearAll,
|
|
938
936
|
(req, res, next) => {
|
|
939
937
|
next();
|
|
940
938
|
},
|
|
@@ -948,7 +946,10 @@ const JXP = function(options) {
|
|
|
948
946
|
middlewareCheckAdmin,
|
|
949
947
|
config.pre_hooks.put,
|
|
950
948
|
actionPut,
|
|
951
|
-
cache.
|
|
949
|
+
cache.clearAll,
|
|
950
|
+
(req, res, next) => {
|
|
951
|
+
next();
|
|
952
|
+
},
|
|
952
953
|
);
|
|
953
954
|
server.del(
|
|
954
955
|
"/api/:modelname/:item_id",
|
|
@@ -957,7 +958,7 @@ const JXP = function(options) {
|
|
|
957
958
|
security.auth,
|
|
958
959
|
config.pre_hooks.delete,
|
|
959
960
|
actionDelete,
|
|
960
|
-
cache.
|
|
961
|
+
cache.clearAll,
|
|
961
962
|
);
|
|
962
963
|
|
|
963
964
|
// Count
|
|
@@ -967,9 +968,9 @@ const JXP = function(options) {
|
|
|
967
968
|
security.login,
|
|
968
969
|
security.auth,
|
|
969
970
|
config.pre_hooks.get,
|
|
970
|
-
cache.get,
|
|
971
|
+
// cache.get,
|
|
971
972
|
actionCount,
|
|
972
|
-
cache.set,
|
|
973
|
+
// cache.set,
|
|
973
974
|
outputJSON
|
|
974
975
|
);
|
|
975
976
|
|
|
@@ -1021,7 +1022,7 @@ const JXP = function(options) {
|
|
|
1021
1022
|
middlewareCheckAdmin,
|
|
1022
1023
|
config.pre_hooks.update,
|
|
1023
1024
|
actionUpdate,
|
|
1024
|
-
cache.
|
|
1025
|
+
cache.clearAll,
|
|
1025
1026
|
);
|
|
1026
1027
|
|
|
1027
1028
|
/* Batch routes - ROLLED BACK FOR NOW */
|
|
@@ -1034,7 +1035,7 @@ const JXP = function(options) {
|
|
|
1034
1035
|
security.login,
|
|
1035
1036
|
security.auth,
|
|
1036
1037
|
actionCall,
|
|
1037
|
-
cache.
|
|
1038
|
+
cache.clearAll,
|
|
1038
1039
|
);
|
|
1039
1040
|
server.post(
|
|
1040
1041
|
"/call/:modelname/:method_name",
|
|
@@ -1042,7 +1043,7 @@ const JXP = function(options) {
|
|
|
1042
1043
|
security.login,
|
|
1043
1044
|
security.auth,
|
|
1044
1045
|
actionCall,
|
|
1045
|
-
cache.
|
|
1046
|
+
cache.clearAll,
|
|
1046
1047
|
);
|
|
1047
1048
|
server.get(
|
|
1048
1049
|
"/call/:modelname/:item_id/:method_name",
|
|
@@ -1050,7 +1051,7 @@ const JXP = function(options) {
|
|
|
1050
1051
|
security.login,
|
|
1051
1052
|
security.auth,
|
|
1052
1053
|
actionCallItem,
|
|
1053
|
-
cache.
|
|
1054
|
+
cache.clearAll,
|
|
1054
1055
|
);
|
|
1055
1056
|
|
|
1056
1057
|
/* Login and authentication */
|
|
@@ -1100,7 +1101,7 @@ const JXP = function(options) {
|
|
|
1100
1101
|
|
|
1101
1102
|
/* Cache */
|
|
1102
1103
|
server.get("/cache/stats", cache.stats, outputJSON);
|
|
1103
|
-
server.get("/cache/clear", cache.
|
|
1104
|
+
server.get("/cache/clear", cache.clearAll, outputJSON);
|
|
1104
1105
|
|
|
1105
1106
|
return server;
|
|
1106
1107
|
};
|
package/mkdocs.yml
CHANGED
package/package.json
CHANGED
package/test/init.js
CHANGED
|
@@ -8,6 +8,7 @@ global.JXPSchema = require("../libs/schema");
|
|
|
8
8
|
const User = require(path.join(model_dir, "user_model"));
|
|
9
9
|
const Apikey = require(path.join(model_dir, "apikey_model"));
|
|
10
10
|
const Test = require(path.join(model_dir, "test_model"));
|
|
11
|
+
const cache = require("../libs/cache");
|
|
11
12
|
|
|
12
13
|
const security = require("../libs/security");
|
|
13
14
|
|
|
@@ -38,6 +39,7 @@ const admin_password = "SecretPassword";
|
|
|
38
39
|
|
|
39
40
|
const init = async () => {
|
|
40
41
|
try {
|
|
42
|
+
await cache.clearAll();
|
|
41
43
|
await empty_user_collections();
|
|
42
44
|
await post(User, { name: "Admin User", email: admin_email, password: security.encPassword(admin_password), urlid: "admin-user", admin: true });
|
|
43
45
|
await post(User, { name: "Test User", email, password: security.encPassword(password), urlid: "test-user" });
|
package/test/test.js
CHANGED
|
@@ -1142,7 +1142,7 @@ describe('Test', () => {
|
|
|
1142
1142
|
chai.request(server)
|
|
1143
1143
|
.get("/cache/clear")
|
|
1144
1144
|
.end((err, res) => {
|
|
1145
|
-
console.log(res.body);
|
|
1145
|
+
// console.log(res.body);
|
|
1146
1146
|
res.should.have.status(200);
|
|
1147
1147
|
done();
|
|
1148
1148
|
});
|
|
@@ -1173,13 +1173,124 @@ describe('Test', () => {
|
|
|
1173
1173
|
chai.request(server)
|
|
1174
1174
|
.get("/cache/stats")
|
|
1175
1175
|
.end((err, res) => {
|
|
1176
|
-
// console.log(res.body);
|
|
1177
1176
|
res.should.have.status(200);
|
|
1178
1177
|
res.body.should.have.property("hits");
|
|
1179
|
-
res.body.hits.should.
|
|
1180
|
-
res.body.misses.should.
|
|
1178
|
+
res.body.hits.should.be.greaterThan(0);
|
|
1179
|
+
res.body.misses.should.be.greaterThan(0);
|
|
1181
1180
|
done();
|
|
1182
1181
|
});
|
|
1183
1182
|
})
|
|
1184
1183
|
});
|
|
1184
|
+
describe("Cache invalidating", () => {
|
|
1185
|
+
let test_id;
|
|
1186
|
+
it("should get a test record", done => {
|
|
1187
|
+
chai.request(server)
|
|
1188
|
+
.get(`/api/test?populate=link&limit=1`)
|
|
1189
|
+
.auth(init.email, init.password)
|
|
1190
|
+
.end((err, res) => {
|
|
1191
|
+
// console.log(res.headers)
|
|
1192
|
+
res.should.have.status(200);
|
|
1193
|
+
res.body.data[0].should.have.property("_id");
|
|
1194
|
+
test_id = res.body.data[0]._id;
|
|
1195
|
+
res.body.data[0].should.have.property("link");
|
|
1196
|
+
should.equal(res.body.data[0].link, null);
|
|
1197
|
+
res.headers["jxp-cache"].should.equal("miss");
|
|
1198
|
+
done();
|
|
1199
|
+
});
|
|
1200
|
+
});
|
|
1201
|
+
it("should get a cached test record", done => {
|
|
1202
|
+
chai.request(server)
|
|
1203
|
+
.get(`/api/test?populate=link&limit=1`)
|
|
1204
|
+
.auth(init.email, init.password)
|
|
1205
|
+
.end((err, res) => {
|
|
1206
|
+
// console.log(res.headers)
|
|
1207
|
+
res.should.have.status(200);
|
|
1208
|
+
res.body.data[0].should.have.property("_id");
|
|
1209
|
+
res.headers["jxp-cache"].should.equal("hit");
|
|
1210
|
+
should.equal(res.body.data[0].link, null);
|
|
1211
|
+
done();
|
|
1212
|
+
});
|
|
1213
|
+
});
|
|
1214
|
+
let link_id;
|
|
1215
|
+
it("should add a link record", done => {
|
|
1216
|
+
chai.request(server)
|
|
1217
|
+
.post(`/api/link`)
|
|
1218
|
+
.auth(init.email, init.password)
|
|
1219
|
+
.send({
|
|
1220
|
+
name: "cache_test",
|
|
1221
|
+
val: "YoYoYo"
|
|
1222
|
+
})
|
|
1223
|
+
.end((err, res) => {
|
|
1224
|
+
// console.log(res.body)
|
|
1225
|
+
res.should.have.status(200);
|
|
1226
|
+
res.body.data.should.have.property("_id");
|
|
1227
|
+
link_id = res.body.data._id;
|
|
1228
|
+
done();
|
|
1229
|
+
});
|
|
1230
|
+
});
|
|
1231
|
+
it("should put link_id into test record", done => {
|
|
1232
|
+
chai.request(server)
|
|
1233
|
+
.put(`/api/test/${test_id}`)
|
|
1234
|
+
.auth(init.admin_email, init.admin_password)
|
|
1235
|
+
.send({
|
|
1236
|
+
link_id
|
|
1237
|
+
})
|
|
1238
|
+
.end((err, res) => {
|
|
1239
|
+
// console.log(res.body)
|
|
1240
|
+
res.should.have.status(200);
|
|
1241
|
+
res.body.data.should.have.property("_id");
|
|
1242
|
+
res.body.data.link_id.should.equal(link_id);
|
|
1243
|
+
done();
|
|
1244
|
+
});
|
|
1245
|
+
});
|
|
1246
|
+
it("should get a test record with link", done => {
|
|
1247
|
+
chai.request(server)
|
|
1248
|
+
.get(`/api/test?populate=link&limit=1`)
|
|
1249
|
+
.auth(init.email, init.password)
|
|
1250
|
+
.end((err, res) => {
|
|
1251
|
+
// console.log(res.body)
|
|
1252
|
+
res.should.have.status(200);
|
|
1253
|
+
res.body.data[0].should.have.property("_id");
|
|
1254
|
+
res.body.data[0].should.have.property("link");
|
|
1255
|
+
res.body.data[0].link.should.not.equal(null);
|
|
1256
|
+
res.body.data[0].link._id.should.equal(link_id);
|
|
1257
|
+
res.body.data[0].link.name.should.equal("cache_test");
|
|
1258
|
+
res.body.data[0].link.val.should.equal("YoYoYo");
|
|
1259
|
+
res.headers["jxp-cache"].should.equal("miss");
|
|
1260
|
+
done();
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
it("should update link record", done => {
|
|
1264
|
+
chai.request(server)
|
|
1265
|
+
.put(`/api/link/${link_id}`)
|
|
1266
|
+
.auth(init.admin_email, init.admin_password)
|
|
1267
|
+
.send({
|
|
1268
|
+
val: "YoYoYo2"
|
|
1269
|
+
})
|
|
1270
|
+
.end((err, res) => {
|
|
1271
|
+
// console.log(res.body)
|
|
1272
|
+
res.should.have.status(200);
|
|
1273
|
+
res.body.data.should.have.property("_id");
|
|
1274
|
+
res.body.data.val.should.equal("YoYoYo2");
|
|
1275
|
+
done();
|
|
1276
|
+
});
|
|
1277
|
+
});
|
|
1278
|
+
it("should get a test record with updated link", done => {
|
|
1279
|
+
chai.request(server)
|
|
1280
|
+
.get(`/api/test?populate=link&limit=1`)
|
|
1281
|
+
.auth(init.email, init.password)
|
|
1282
|
+
.end((err, res) => {
|
|
1283
|
+
// console.log(res.body.data[0].link)
|
|
1284
|
+
res.should.have.status(200);
|
|
1285
|
+
res.body.data[0].should.have.property("_id");
|
|
1286
|
+
res.body.data[0].should.have.property("link");
|
|
1287
|
+
res.body.data[0].link.should.not.equal(null);
|
|
1288
|
+
res.body.data[0].link._id.should.equal(link_id);
|
|
1289
|
+
res.body.data[0].link.name.should.equal("cache_test");
|
|
1290
|
+
res.body.data[0].link.val.should.equal("YoYoYo2");
|
|
1291
|
+
res.headers["jxp-cache"].should.equal("miss");
|
|
1292
|
+
done();
|
|
1293
|
+
});
|
|
1294
|
+
});
|
|
1295
|
+
})
|
|
1185
1296
|
});
|