Skip to content

Commit 47f0357

Browse files
committed
merge master
2 parents 515fcfb + 072f1b6 commit 47f0357

File tree

27 files changed

+20694
-20035
lines changed

27 files changed

+20694
-20035
lines changed

.vscode/launch.json

+21-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"program": "${workspaceRoot}/dev",
1212
"cwd": "${workspaceRoot}",
1313
"args": [
14-
"moleculer-db-adapter-mongo",
15-
"issue"
14+
"moleculer-db-adapter-mongoose",
15+
"simple"
1616
]
1717
},
1818
{
@@ -28,6 +28,25 @@
2828
"stopOnEntry": true
2929

3030
},
31+
{
32+
"type": "node",
33+
"request": "launch",
34+
"name": "Launch benchmark",
35+
"program": "${workspaceRoot}/benchmark/index.js",
36+
"cwd": "${workspaceRoot}",
37+
"args": [
38+
"common"
39+
]
40+
},
41+
{
42+
"name": "Attach by Benchmark",
43+
"processId": "${command:PickProcess}",
44+
"request": "attach",
45+
"skipFiles": [
46+
"<node_internals>/**"
47+
],
48+
"type": "node"
49+
},
3150
{
3251
"type": "node",
3352
"request": "launch",

benchmark/.eslintrc.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
env: {
3+
node: true,
4+
commonjs: true,
5+
es6: true
6+
},
7+
extends: ["eslint:recommended"],
8+
parserOptions: {
9+
sourceType: "module",
10+
ecmaVersion: 2017,
11+
ecmaFeatures: {
12+
experimentalObjectRestSpread: true
13+
}
14+
},
15+
rules: {
16+
indent: ["warn", "tab", { SwitchCase: 1 }],
17+
quotes: ["warn", "double"],
18+
semi: ["error", "always"],
19+
"no-var": ["warn"],
20+
"no-console": ["off"],
21+
"no-unused-vars": ["off"],
22+
"no-trailing-spaces": ["error"],
23+
"security/detect-possible-timing-attacks": ["off"]
24+
}
25+
};

benchmark/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"use strict";
2+
3+
require("./suites/" + (process.argv[2] || "common"));

benchmark/suites/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tmp/

benchmark/suites/common.js

+279
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
"use strict";
2+
3+
const path = require("path");
4+
const fs = require("fs");
5+
const { makeDirs } = require("moleculer").Utils;
6+
7+
const Benchmarkify = require("benchmarkify");
8+
const _ = require("lodash");
9+
const { ServiceBroker } = require("moleculer");
10+
const DbService = require("../../packages/moleculer-db/index");
11+
const SequelizeAdapter = require("../../packages/moleculer-db-adapter-sequelize/index");
12+
const Sequelize = require("sequelize");
13+
14+
const Fakerator = require("fakerator");
15+
const fakerator = new Fakerator();
16+
17+
const COUNT = 1000;
18+
19+
makeDirs(path.join(__dirname, "tmp"));
20+
21+
const neDBFileName = path.join(__dirname, "tmp", "common.db");
22+
const sqliteFilename = path.join(__dirname, "tmp", "common.sqlite3");
23+
24+
const Adapters = [
25+
//{ name: "NeDB (memory)", type: "NeDB", adapter: new DbService.MemoryAdapter(), ref: true },
26+
{ name: "NeDB (file)", type: "NeDB", adapter: new DbService.MemoryAdapter({ filename: neDBFileName }) },
27+
{ name: "SQLite (memory)", type: "Sequelize", adapter: new SequelizeAdapter("sqlite://:memory:", { logging: false }) },
28+
// { name: "SQLite (file)", type: "Sequelize", adapter: new SequelizeAdapter("sqlite://benchmark/suites/tmp/common.sqlite3", { logging: false }) },
29+
];
30+
31+
const benchmark = new Benchmarkify("Moleculer Database benchmark - Common");
32+
33+
const suites = [];
34+
35+
const UserServiceSchema = (serviceName, adapterDef) => {
36+
return {
37+
name: serviceName,
38+
mixins: [DbService],
39+
adapter: adapterDef.adapter,
40+
model: {
41+
name: "post",
42+
define: {
43+
firstName: Sequelize.STRING,
44+
lastName: Sequelize.STRING,
45+
userName: Sequelize.STRING,
46+
email: Sequelize.STRING,
47+
password: Sequelize.STRING,
48+
status: Sequelize.BOOLEAN
49+
},
50+
options: {
51+
52+
}
53+
},
54+
settings: {
55+
idField: "id",
56+
fields: ["id", "firstName", "lastName", "userName", "email", "password", "status"],
57+
},
58+
async started() {
59+
await this.adapter.clear();
60+
}
61+
};
62+
};
63+
64+
const USERS = fakerator.times(fakerator.entity.user, COUNT * 5).map(user => {
65+
return _.pick(user, ["firstName", "lastName", "userName", "email", "password", "status"]);
66+
});
67+
68+
const broker = new ServiceBroker({ logger: false });
69+
Adapters.forEach((adapterDef, i) => {
70+
// const adapterName = adapterDef.name || adapterDef.type;
71+
const serviceName = `users-${i}`;
72+
adapterDef.svcName = serviceName;
73+
adapterDef.svc = broker.createService(UserServiceSchema(serviceName, adapterDef));
74+
});
75+
76+
// --- ENTITY CREATION ---
77+
(function () {
78+
const bench = benchmark.createSuite("Entity creation", {
79+
description: "This test calls the `create` action to create an entity.",
80+
meta: {
81+
type: "create"
82+
}
83+
});
84+
suites.push(bench);
85+
const tearDowns = [];
86+
bench.tearDown(tearDowns);
87+
88+
Adapters.forEach(adapterDef => {
89+
const adapterName = adapterDef.name || adapterDef.type;
90+
const svc = adapterDef.svc;
91+
const actionName = `${adapterDef.svcName}.create`;
92+
93+
const len = USERS.length;
94+
let c = 0;
95+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
96+
broker.call(actionName, USERS[c++ % len]).then(done).catch(err => console.error(err));
97+
});
98+
99+
// Clear all entities and create only the specified count.
100+
tearDowns.push(async () => {
101+
try {
102+
await svc.adapter.clear();
103+
await svc.adapter.insertMany(USERS.slice(0, COUNT));
104+
} catch(err) {
105+
console.error(err);
106+
}
107+
});
108+
});
109+
})();
110+
111+
// --- ENTITY FINDING ---
112+
(function () {
113+
const bench = benchmark.createSuite("Entity finding", {
114+
description: "This test calls the `find` action to get random 20 entities.",
115+
meta: {
116+
type: "find"
117+
}
118+
});
119+
suites.push(bench);
120+
121+
Adapters.forEach(adapterDef => {
122+
const adapterName = adapterDef.name || adapterDef.type;
123+
const actionName = `${adapterDef.svcName}.find`;
124+
125+
let c = 0;
126+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
127+
const offset = Math.floor(Math.random() * (COUNT - 20));
128+
broker.call(actionName, { offset, limit: 20 }).then(done).catch(err => console.error(err));
129+
});
130+
});
131+
})();
132+
133+
// --- ENTITY LISTING ---
134+
(function () {
135+
const bench = benchmark.createSuite("Entity listing", {
136+
description: "This test calls the `users.list` service action to random 20 entities.",
137+
meta: {
138+
type: "list"
139+
}
140+
});
141+
suites.push(bench);
142+
143+
Adapters.forEach(adapterDef => {
144+
const adapterName = adapterDef.name || adapterDef.type;
145+
const actionName = `${adapterDef.svcName}.list`;
146+
147+
const maxPage = COUNT / 20 - 2;
148+
let c = 0;
149+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
150+
const page = Math.floor(Math.random() * maxPage) + 1;
151+
broker.call(actionName, { page, pageSize: 20 }).then(done).catch(err => console.error(err));
152+
});
153+
});
154+
})();
155+
156+
// --- ENTITY COUNTING ---
157+
(function () {
158+
const bench = benchmark.createSuite("Entity counting", {
159+
description:
160+
"This test calls the `users.count` service action to get the number of entities.",
161+
meta: {
162+
type: "count"
163+
}
164+
});
165+
suites.push(bench);
166+
167+
Adapters.forEach(adapterDef => {
168+
const adapterName = adapterDef.name || adapterDef.type;
169+
const actionName = `${adapterDef.svcName}.count`;
170+
171+
let c = 0;
172+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
173+
broker.call(actionName).then(done).catch(err => console.error(err));
174+
});
175+
});
176+
})();
177+
178+
// --- ENTITY GETTING ---
179+
(function () {
180+
const bench = benchmark.createSuite("Entity getting", {
181+
description: "This test calls the `users.get` service action to get a random entity.",
182+
meta: {
183+
type: "get"
184+
}
185+
});
186+
suites.push(bench);
187+
const setups = [];
188+
bench.setup(setups);
189+
190+
Adapters.forEach(adapterDef => {
191+
const adapterName = adapterDef.name || adapterDef.type;
192+
const actionName = `${adapterDef.svcName}.get`;
193+
194+
let docs = null;
195+
setups.push(async () => {
196+
docs = await broker.call(`${adapterDef.svcName}.find`);
197+
});
198+
199+
let c = 0;
200+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
201+
const entity = docs[Math.floor(Math.random() * docs.length)];
202+
return broker.call(actionName, { id: entity.id }).then(done).catch(err => console.error(err));
203+
});
204+
});
205+
})();
206+
207+
// --- ENTITY UPDATING ---
208+
(function () {
209+
const bench = benchmark.createSuite("Entity updating", {
210+
description: "This test calls the `users.update` service action to update a entity.",
211+
meta: {
212+
type: "update"
213+
}
214+
});
215+
suites.push(bench);
216+
const setups = [];
217+
bench.setup(setups);
218+
219+
Adapters.forEach(adapterDef => {
220+
const adapterName = adapterDef.name || adapterDef.type;
221+
const actionName = `${adapterDef.svcName}.update`;
222+
223+
let docs = null;
224+
setups.push(async () => {
225+
docs = await broker.call(`${adapterDef.svcName}.find`);
226+
});
227+
228+
let c = 0;
229+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
230+
const entity = docs[Math.floor(Math.random() * docs.length)];
231+
const newStatus = Math.round(Math.random());
232+
return broker.call(actionName, { id: entity.id, status: newStatus }).then(done).catch(err => console.error(err));
233+
});
234+
});
235+
})();
236+
237+
// --- ENTITY DELETING ---
238+
(function () {
239+
const bench = benchmark.createSuite("Entity deleting", {
240+
description: "This test calls the `users.remove` service action to delete a random entity.",
241+
meta: {
242+
type: "remove"
243+
}
244+
});
245+
suites.push(bench);
246+
const setups = [];
247+
bench.setup(setups);
248+
249+
Adapters.forEach(adapterDef => {
250+
const adapterName = adapterDef.name || adapterDef.type;
251+
const actionName = `${adapterDef.svcName}.remove`;
252+
253+
let docs = null;
254+
setups.push(async () => {
255+
docs = await broker.call(`${adapterDef.svcName}.find`);
256+
});
257+
258+
let c = 0;
259+
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
260+
const entity = docs[Math.floor(Math.random() * docs.length)];
261+
return broker.call(actionName, { id: entity.id }).catch(done).then(done).catch(err => console.error(err));
262+
});
263+
});
264+
})();
265+
266+
async function run() {
267+
await broker.start();
268+
try {
269+
console.log("Running suites...");
270+
await benchmark.run(suites);
271+
} finally {
272+
await broker.stop();
273+
}
274+
console.log("Done.");
275+
276+
process.exit(0);
277+
}
278+
279+
run();

0 commit comments

Comments
 (0)