Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
thib3113 committed Dec 16, 2023
2 parents 515fcfb + 072f1b6 commit 47f0357
Show file tree
Hide file tree
Showing 27 changed files with 20,694 additions and 20,035 deletions.
23 changes: 21 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"program": "${workspaceRoot}/dev",
"cwd": "${workspaceRoot}",
"args": [
"moleculer-db-adapter-mongo",
"issue"
"moleculer-db-adapter-mongoose",
"simple"
]
},
{
Expand All @@ -28,6 +28,25 @@
"stopOnEntry": true

},
{
"type": "node",
"request": "launch",
"name": "Launch benchmark",
"program": "${workspaceRoot}/benchmark/index.js",
"cwd": "${workspaceRoot}",
"args": [
"common"
]
},
{
"name": "Attach by Benchmark",
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"type": "node",
"request": "launch",
Expand Down
25 changes: 25 additions & 0 deletions benchmark/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
env: {
node: true,
commonjs: true,
es6: true
},
extends: ["eslint:recommended"],
parserOptions: {
sourceType: "module",
ecmaVersion: 2017,
ecmaFeatures: {
experimentalObjectRestSpread: true
}
},
rules: {
indent: ["warn", "tab", { SwitchCase: 1 }],
quotes: ["warn", "double"],
semi: ["error", "always"],
"no-var": ["warn"],
"no-console": ["off"],
"no-unused-vars": ["off"],
"no-trailing-spaces": ["error"],
"security/detect-possible-timing-attacks": ["off"]
}
};
3 changes: 3 additions & 0 deletions benchmark/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";

require("./suites/" + (process.argv[2] || "common"));
1 change: 1 addition & 0 deletions benchmark/suites/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tmp/
279 changes: 279 additions & 0 deletions benchmark/suites/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
"use strict";

const path = require("path");
const fs = require("fs");
const { makeDirs } = require("moleculer").Utils;

const Benchmarkify = require("benchmarkify");
const _ = require("lodash");
const { ServiceBroker } = require("moleculer");
const DbService = require("../../packages/moleculer-db/index");
const SequelizeAdapter = require("../../packages/moleculer-db-adapter-sequelize/index");
const Sequelize = require("sequelize");

const Fakerator = require("fakerator");
const fakerator = new Fakerator();

const COUNT = 1000;

makeDirs(path.join(__dirname, "tmp"));

const neDBFileName = path.join(__dirname, "tmp", "common.db");
const sqliteFilename = path.join(__dirname, "tmp", "common.sqlite3");

const Adapters = [
//{ name: "NeDB (memory)", type: "NeDB", adapter: new DbService.MemoryAdapter(), ref: true },
{ name: "NeDB (file)", type: "NeDB", adapter: new DbService.MemoryAdapter({ filename: neDBFileName }) },
{ name: "SQLite (memory)", type: "Sequelize", adapter: new SequelizeAdapter("sqlite://:memory:", { logging: false }) },
// { name: "SQLite (file)", type: "Sequelize", adapter: new SequelizeAdapter("sqlite://benchmark/suites/tmp/common.sqlite3", { logging: false }) },
];

const benchmark = new Benchmarkify("Moleculer Database benchmark - Common");

const suites = [];

const UserServiceSchema = (serviceName, adapterDef) => {
return {
name: serviceName,
mixins: [DbService],
adapter: adapterDef.adapter,
model: {
name: "post",
define: {
firstName: Sequelize.STRING,
lastName: Sequelize.STRING,
userName: Sequelize.STRING,
email: Sequelize.STRING,
password: Sequelize.STRING,
status: Sequelize.BOOLEAN
},
options: {

}
},
settings: {
idField: "id",
fields: ["id", "firstName", "lastName", "userName", "email", "password", "status"],
},
async started() {
await this.adapter.clear();
}
};
};

const USERS = fakerator.times(fakerator.entity.user, COUNT * 5).map(user => {
return _.pick(user, ["firstName", "lastName", "userName", "email", "password", "status"]);
});

const broker = new ServiceBroker({ logger: false });
Adapters.forEach((adapterDef, i) => {
// const adapterName = adapterDef.name || adapterDef.type;
const serviceName = `users-${i}`;
adapterDef.svcName = serviceName;
adapterDef.svc = broker.createService(UserServiceSchema(serviceName, adapterDef));
});

// --- ENTITY CREATION ---
(function () {
const bench = benchmark.createSuite("Entity creation", {
description: "This test calls the `create` action to create an entity.",
meta: {
type: "create"
}
});
suites.push(bench);
const tearDowns = [];
bench.tearDown(tearDowns);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const svc = adapterDef.svc;
const actionName = `${adapterDef.svcName}.create`;

const len = USERS.length;
let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
broker.call(actionName, USERS[c++ % len]).then(done).catch(err => console.error(err));
});

// Clear all entities and create only the specified count.
tearDowns.push(async () => {
try {
await svc.adapter.clear();
await svc.adapter.insertMany(USERS.slice(0, COUNT));
} catch(err) {
console.error(err);
}
});
});
})();

// --- ENTITY FINDING ---
(function () {
const bench = benchmark.createSuite("Entity finding", {
description: "This test calls the `find` action to get random 20 entities.",
meta: {
type: "find"
}
});
suites.push(bench);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.find`;

let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
const offset = Math.floor(Math.random() * (COUNT - 20));
broker.call(actionName, { offset, limit: 20 }).then(done).catch(err => console.error(err));
});
});
})();

// --- ENTITY LISTING ---
(function () {
const bench = benchmark.createSuite("Entity listing", {
description: "This test calls the `users.list` service action to random 20 entities.",
meta: {
type: "list"
}
});
suites.push(bench);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.list`;

const maxPage = COUNT / 20 - 2;
let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
const page = Math.floor(Math.random() * maxPage) + 1;
broker.call(actionName, { page, pageSize: 20 }).then(done).catch(err => console.error(err));
});
});
})();

// --- ENTITY COUNTING ---
(function () {
const bench = benchmark.createSuite("Entity counting", {
description:
"This test calls the `users.count` service action to get the number of entities.",
meta: {
type: "count"
}
});
suites.push(bench);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.count`;

let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
broker.call(actionName).then(done).catch(err => console.error(err));
});
});
})();

// --- ENTITY GETTING ---
(function () {
const bench = benchmark.createSuite("Entity getting", {
description: "This test calls the `users.get` service action to get a random entity.",
meta: {
type: "get"
}
});
suites.push(bench);
const setups = [];
bench.setup(setups);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.get`;

let docs = null;
setups.push(async () => {
docs = await broker.call(`${adapterDef.svcName}.find`);
});

let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
const entity = docs[Math.floor(Math.random() * docs.length)];
return broker.call(actionName, { id: entity.id }).then(done).catch(err => console.error(err));
});
});
})();

// --- ENTITY UPDATING ---
(function () {
const bench = benchmark.createSuite("Entity updating", {
description: "This test calls the `users.update` service action to update a entity.",
meta: {
type: "update"
}
});
suites.push(bench);
const setups = [];
bench.setup(setups);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.update`;

let docs = null;
setups.push(async () => {
docs = await broker.call(`${adapterDef.svcName}.find`);
});

let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
const entity = docs[Math.floor(Math.random() * docs.length)];
const newStatus = Math.round(Math.random());
return broker.call(actionName, { id: entity.id, status: newStatus }).then(done).catch(err => console.error(err));
});
});
})();

// --- ENTITY DELETING ---
(function () {
const bench = benchmark.createSuite("Entity deleting", {
description: "This test calls the `users.remove` service action to delete a random entity.",
meta: {
type: "remove"
}
});
suites.push(bench);
const setups = [];
bench.setup(setups);

Adapters.forEach(adapterDef => {
const adapterName = adapterDef.name || adapterDef.type;
const actionName = `${adapterDef.svcName}.remove`;

let docs = null;
setups.push(async () => {
docs = await broker.call(`${adapterDef.svcName}.find`);
});

let c = 0;
bench[adapterDef.ref ? "ref" : "add"](adapterName, done => {
const entity = docs[Math.floor(Math.random() * docs.length)];
return broker.call(actionName, { id: entity.id }).catch(done).then(done).catch(err => console.error(err));
});
});
})();

async function run() {
await broker.start();
try {
console.log("Running suites...");
await benchmark.run(suites);
} finally {
await broker.stop();
}
console.log("Done.");

process.exit(0);
}

run();
Loading

0 comments on commit 47f0357

Please sign in to comment.