Skip to content

Feature/add package for benchmark #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
if: ${{ matrix.node == 16 }}
run: yarn doc
- name: publish npm
if: ${{ matrix.node == 16 }}
if: ${{ matrix.node == 14 }}
run: bash scripts/publish.sh
env:
SHA: ${{ github.event.after }}
6 changes: 6 additions & 0 deletions packages/benchmark/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.cache
node_modules

lib/

report.cjs.html
91 changes: 91 additions & 0 deletions packages/benchmark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
[![Join the chat at https://gitter.im/scalecube-js/Lobby](https://badges.gitter.im/scalecube-js/Lobby.svg)](https://gitter.im/scalecube-js/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

> This is part of [scalecube-js](https://github.com/scalecube/scalecube-js) project, see more at <https://github.com/scalecube/scalecube-js>
> [Full documentation](https://scalecube.github.io/javascript-docs)

# Microservices-browser

This package provides Scalecube's solution with default setting for working in node.

### Usage

`yarn add @scalecube/node` or `npm i @scalecube/node`

```typescript
import { createMicroservice, ASYNC_MODEL_TYPES } from '@scalecube/node';
```

**create a seed**

```typescript
export const MySeedAddress: 'ws://localhost:8000';

// Create a service
createMicroservice({
address : MySeedAddress
});
```

**Create a service**

```typescript
// Create service definition
export const greetingServiceDefinition = {
serviceName: 'GreetingService',
methods: {
hello: {
asyncModel: ASYNC_MODEL_TYPES.REQUEST_RESPONSE,
}
},
};
// Create a service
createMicroservice({
service : [{
definition: greetingServiceDefinition,
reference: {
hello : (name) => `Hello ${name}`
},
}],
seedAddress : MySeedAddress,
address : 'ws://localhost:8001'
});
```

**Use a service**

```typescript
const microservice = createMicroservice({
seedAddress : MySeedAddress,
address : 'ws://localhost:8002'
})

// With proxy
const greetingService = microservice.createProxy({
serviceDefinition: greetingServiceDefinition
});

greetingService.hello('ME').then(console.log) // Hello ME
```

**Dependency Injection**

```typescript
createMicroservice({
seedAddress : MySeedAddress,
address : 'ws://localhost:8003',
services: [
{
definition: serviceB,
reference: ({ createProxy, createServiceCall }) => {
const greetingService = createProxy({serviceDefinition: greetingServiceDefinition });

return new ServiceB(greetingService);
}
}
]
})
```

## documentation

please [Read](https://scalecube.github.io/javascript-docs) before starting to work with scalecube.
28 changes: 28 additions & 0 deletions packages/benchmark/benchmark.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "benchmark name",
"server": [
{
"start": "echo start",
"warmup": "echo warm",
"stop": "echo stop"
}
],
"benchmark": [
{
"name": "variant 1",
"client": {
"command": "echo '{\"1\": 5}'",
"repeat": 3,
"delay": 0
}
},
{
"name": "variant 2",
"client": {
"command": "echo '{\"3\": 5}'",
"repeat": 3,
"delay": 0
}
}
]
}
4 changes: 4 additions & 0 deletions packages/benchmark/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node

const { run } = require('./lib/index');
run(process.argv[2]).then(() => console.log('done'));
9 changes: 9 additions & 0 deletions packages/benchmark/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
transform: {
'.(ts|tsx)': 'ts-jest',
},
testRegex: '(\\.|/)spec\\.ts$',
testPathIgnorePatterns: ['<rootDir>/es/', '<rootDir>/lib/', '<rootDir>/node_modules/'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'node'],
moduleDirectories: ['node_modules', '<rootDir>/src', '<rootDir>/node_modules/'],
};
33 changes: 33 additions & 0 deletions packages/benchmark/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@scalecube/benchmark",
"version": "0.2.11",
"private": false,
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"license": "MIT",
"bin": {
"benchmark": "./index.js"
},
"scripts": {
"clean": "rimraf node_modules && rimraf .cache && rimraf lib",
"build": "rimraf .cache && yarn build:cjs",
"build:cjs": "rimraf lib && rollup -c rollup.cjs.config.js",
"lint": "tslint '{src,tests}/**/*.{ts,tsx}' --fix",
"prettier": "prettier --write '{src,tests}/**/*.{ts,tsx}'",
"test": "jest --config jest.config.js --forceExit"
},
"author": "Scalecube (https://github.com/scalecube/scalecube-js)",
"devDependencies": {
"rollup": "^1.27.4",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-filesize": "^6.1.1",
"rollup-plugin-typescript2": "^0.21.1",
"rollup-plugin-visualizer": "^2.6.0",
"tslint": "^5.11.0",
"typescript": "^3.2.4"
},
"dependencies": {}
}
35 changes: 35 additions & 0 deletions packages/benchmark/rollup.cjs.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import visualizer from 'rollup-plugin-visualizer';
import typescript from 'rollup-plugin-typescript2';
import tscompile from 'typescript';
import filesize from 'rollup-plugin-filesize';
import commonjs from 'rollup-plugin-commonjs';
import pkg from './package.json';

export default {
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs',
sourcemap: false,
},
],
external: ['rxjs'],
plugins: [
commonjs({
include: /node_modules/,
namedExports: {
'rsocket-types': ['CONNECTION_STATUS'],
},
}),
visualizer({
filename: 'report.cjs.html',
title: 'Node - cjs',
}),
typescript({
typescript: tscompile,
clean: true,
}),
filesize(),
],
};
35 changes: 35 additions & 0 deletions packages/benchmark/src/collect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Buckets } from './index';

export async function collect(buckets: Promise<string[]>, name: string) {
const data = await buckets;
const merged: any = {};
let total = 0;
let mean = 0;
let sum = 0;
let stdev = 0;
data.forEach((str) => {
const obj: Buckets = JSON.parse(str);
Object.keys(obj).forEach((c) => {
const ms = Number(c);
merged[c] = { x: ms, value: (merged?.[c]?.value || 0) + obj[c] };
for (let i = 0; i < obj[c]; i++) {
total += 1;
const delta = ms - mean;
mean += delta / total;
const delta2 = ms - mean;
sum += delta * delta2;
}
});
});
if (total > 1) {
stdev = sum / total;
}

return {
name,
total,
mean,
stdev,
data: Object.values(merged),
};
}
48 changes: 48 additions & 0 deletions packages/benchmark/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { getConf, showHelp, exec, print, execDelayed } from './util';
import * as reporters from 'reporters';
import { collect } from './collect';

export interface Buckets {
[ms: string]: number;
}
function report(data: any[], name: string) {
reporters.json(data, name);
reporters.html(data, name);
}

export async function run(path: string) {
const conf = getConf(path);

if (!conf) {
showHelp();
return;
}
const servers = conf.server || [];
const benchmarks = conf.benchmark || [];
const parallel = servers.length > 0 ? servers.length : 1;
const runningServers = [];

for (const server of servers) {
runningServers.push(exec(server.start).then(() => print('server is closed')));
if (server.warmup) {
await exec(server.warmup);
}
}
const result = [];
const running = 0;
while (benchmarks.length) {
if (running === parallel) {
await Promise.race(result);
}
const setting = benchmarks.pop();
const p = [];
for (let i = 0; i < setting.client.repeat; i++) {
p.push(execDelayed(setting.client.command, i * setting.client.delay));
}
result.push(collect(Promise.all(p) as Promise<string[]>, setting.name));
}

report((await Promise.all(result)) as any, conf.name);

// running_servers.forEach(p => p.c)
}
75 changes: 75 additions & 0 deletions packages/benchmark/src/reporters/html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import fs from 'fs';
import { Buckets } from '../index';
export function html(data: any[], name: string) {
const report = {
name,
series: data.map((s) => ({
data: s.data,
name: `${s.name}, total: ${s.total}, mean: ${s.mean}, stdev: ${s.stdev}`,
})),
};
const f = tmpl(JSON.stringify(report));
fs.writeFileSync(name.replace(/[^a-z0-9]/gi, '_').toLowerCase() + '.html', f, { encoding: 'utf8' });
}

const tmpl = (data: string) => `
<div id="anychart-embed-samples-wd-data-from-json-04" class="anychart-embed anychart-embed-samples-wd-data-from-json-04">
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js?hcode=a0c21fc77e1449cc86299c5faa067dc4"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-exports.min.js?hcode=a0c21fc77e1449cc86299c5faa067dc4"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-ui.min.js?hcode=a0c21fc77e1449cc86299c5faa067dc4"></script>
<div id="ac_style_samples-wd-data-from-json-04" style="display:none;">
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</div>
<script>(function(){
function ac_add_to_head(el){
\tvar head = document.getElementsByTagName('head')[0];
\thead.insertBefore(el,head.firstChild);
}
function ac_add_link(url){
\tvar el = document.createElement('link');
\tel.rel='stylesheet';el.type='text/css';el.media='all';el.href=url;
\tac_add_to_head(el);
}
function ac_add_style(css){
\tvar ac_style = document.createElement('style');
\tif (ac_style.styleSheet) ac_style.styleSheet.cssText = css;
\telse ac_style.appendChild(document.createTextNode(css));
\tac_add_to_head(ac_style);
}
ac_add_link('https://cdn.anychart.com/releases/8.11.0/css/anychart-ui.min.css?hcode=a0c21fc77e1449cc86299c5faa067dc4');
ac_add_style(document.getElementById("ac_style_samples-wd-data-from-json-04").innerHTML);
ac_add_style(".anychart-embed-samples-wd-data-from-json-04{width:100%;height:90%;}");
})();</script>
<div id="container"></div>
<script>
anychart.onDocumentReady(function () {
const data = ${data};
// JSON data
var json = {
// chart settings
"chart": {
// chart type
"type": "column",
// set chart title
"title": \`\${data.name}\`,
// series settings
"series": data.series,
// chart container
"container": "container"
}
};

// get JSON data
var chart = anychart.fromJson(json);
chart.legend(true)
// draw chart
chart.draw();
});
</script>
</div>
`;
2 changes: 2 additions & 0 deletions packages/benchmark/src/reporters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { json } from './json';
export { html } from './html';
11 changes: 11 additions & 0 deletions packages/benchmark/src/reporters/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import fs from 'fs';
import { Buckets } from '../index';
export function json(data: any[], name: string) {
const report = {
name,
series: data,
};
fs.writeFileSync(name.replace(/[^a-z0-9]/gi, '_').toLowerCase() + '.json', JSON.stringify(report), {
encoding: 'utf8',
});
}
Loading