Skip to content

Commit

Permalink
feat(ditsmod): upgrade npm packages and added bun integration. (#9213)
Browse files Browse the repository at this point in the history
  • Loading branch information
KostyaTretyak authored Aug 14, 2024
1 parent 61ebc14 commit a3ff927
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 16 deletions.
132 changes: 132 additions & 0 deletions frameworks/TypeScript/ditsmod/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,138 @@
"display_name": "ditsmod [mysql & simplified use of di]",
"notes": "Simplified use of Dependency Injection (no request level injector).",
"versus": "nodejs"
},
"bun": {
"dockerfile": "ditsmod-bun.dockerfile",
"json_url": "/json",
"plaintext_url": "/plaintext",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "None",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "None",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "Ditsmod on bun",
"notes": "",
"versus": "bun"
},
"simplified-di-bun": {
"dockerfile": "ditsmod-bun.dockerfile",
"json_url": "/json2",
"plaintext_url": "/plaintext2",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "None",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "None",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "ditsmod on bun [simplified use of di]",
"notes": "Simplified use of Dependency Injection (no request level injector).",
"versus": "bun"
},
"postgres-bun": {
"dockerfile": "ditsmod-bun-postgres.dockerfile",
"db_url": "/db",
"query_url": "/queries?queries=",
"update_url": "/updates?queries=",
"cached_query_url": "/cached-queries?count=",
"fortune_url": "/fortunes",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "Postgres",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "Raw",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "ditsmod on bun [postgres]",
"notes": "",
"versus": "bun"
},
"mysql-bun": {
"dockerfile": "ditsmod-bun-mysql.dockerfile",
"db_url": "/db",
"query_url": "/queries?queries=",
"update_url": "/updates?queries=",
"cached_query_url": "/cached-queries?count=",
"fortune_url": "/fortunes",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "MySQL",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "Raw",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "ditsmod on bun [mysql]",
"notes": "",
"versus": "bun"
},
"postgres2-bun": {
"dockerfile": "ditsmod-bun-postgres.dockerfile",
"db_url": "/db2",
"query_url": "/queries2?queries=",
"update_url": "/updates2?queries=",
"cached_query_url": "/cached-queries2?count=",
"fortune_url": "/fortunes2",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "Postgres",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "Raw",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "ditsmod on bun [postgres & simplified use of di]",
"notes": "Simplified use of Dependency Injection (no request level injector).",
"versus": "bun"
},
"mysql2-bun": {
"dockerfile": "ditsmod-bun-mysql.dockerfile",
"db_url": "/db2",
"query_url": "/queries2?queries=",
"update_url": "/updates2?queries=",
"cached_query_url": "/cached-queries2?count=",
"fortune_url": "/fortunes2",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "MySQL",
"framework": "Ditsmod",
"language": "TypeScript",
"flavor": "None",
"orm": "Raw",
"platform": "bun",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "ditsmod on bun [mysql & simplified use of di]",
"notes": "Simplified use of Dependency Injection (no request level injector).",
"versus": "bun"
}
}
]
Expand Down
Binary file added frameworks/TypeScript/ditsmod/bun.lockb
Binary file not shown.
17 changes: 17 additions & 0 deletions frameworks/TypeScript/ditsmod/ditsmod-bun-mysql.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM oven/bun:1.1

COPY ./ ./

RUN bun install
RUN bun run build

ENV NODE_ENV production
ENV IS_BUN true
ENV DATABASE mysql
ENV MYSQL_HOST tfb-database
ENV MYSQL_USER benchmarkdbuser
ENV MYSQL_PSWD benchmarkdbpass
ENV MYSQL_DBNAME hello_world

EXPOSE 8080
CMD rm node_modules/@ditsmod/*/tsconfig.json && bun src/app/bun-integration/spawn.ts
17 changes: 17 additions & 0 deletions frameworks/TypeScript/ditsmod/ditsmod-bun-postgres.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM oven/bun:1.1

COPY ./ ./

RUN bun install
RUN bun run build

ENV NODE_ENV production
ENV IS_BUN true
ENV DATABASE postgres
ENV PG_HOST tfb-database
ENV PG_USER benchmarkdbuser
ENV PG_PSWD benchmarkdbpass
ENV PG_DBNAME hello_world

EXPOSE 8080
CMD rm node_modules/@ditsmod/*/tsconfig.json && bun src/app/bun-integration/spawn.ts
12 changes: 12 additions & 0 deletions frameworks/TypeScript/ditsmod/ditsmod-bun.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM oven/bun:1.1

COPY ./ ./

RUN bun install
RUN bun run build

ENV NODE_ENV production
ENV IS_BUN true

EXPOSE 8080
CMD rm node_modules/@ditsmod/*/tsconfig.json && bun src/app/bun-integration/spawn.ts
2 changes: 1 addition & 1 deletion frameworks/TypeScript/ditsmod/ditsmod-mysql.dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18.17.1-slim
FROM node:20.16-slim

COPY ./ ./

Expand Down
2 changes: 1 addition & 1 deletion frameworks/TypeScript/ditsmod/ditsmod-postgres.dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18.17.1-slim
FROM node:20.16-slim

COPY ./ ./

Expand Down
2 changes: 1 addition & 1 deletion frameworks/TypeScript/ditsmod/ditsmod.dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18.17.1-slim
FROM node:20.16-slim

COPY ./ ./

Expand Down
11 changes: 6 additions & 5 deletions frameworks/TypeScript/ditsmod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@
"author": "Костя Третяк",
"license": "MIT",
"dependencies": {
"@ditsmod/core": "~2.51.1",
"@ditsmod/routing": "~2.1.0",
"@ditsmod/core": "~2.54.2",
"@ditsmod/routing": "~2.3.0",
"handlebars": "^4.7.8",
"lru-cache": "^10.0.1",
"mariadb": "^3.2.1",
"postgres": "^3.3.5"
"lru-cache": "^11.0.0",
"mariadb": "^3.3.1",
"postgres": "^3.4.4"
},
"devDependencies": {
"@types/eslint": "^8.44.2",
"@types/node": "^20.5.7",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"bun-types": "^1.1.22",
"eslint": "^8.48.0",
"prettier": "^3.0.2",
"typescript": "^5.2.2"
Expand Down
9 changes: 7 additions & 2 deletions frameworks/TypeScript/ditsmod/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { Providers, rootModule } from '@ditsmod/core';
import { PreRouter, rootModule } from '@ditsmod/core';

import { SimpleModule } from '#routed/simple/simple.module.js';
import { BunPreRouter } from './bun-integration/pre-router.js';
import { BunProviders } from './bun-integration/bun-providers.js';

@rootModule({
appends: [SimpleModule],
providersPerApp: [...new Providers().useLogConfig({ level: 'off' })],
providersPerApp: [
...new BunProviders().useLogConfig({ level: 'off' }).if(process.env.IS_BUN).useClass(PreRouter, BunPreRouter),
],
})
export class AppModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AnyFn, AppInitializer, Application } from '@ditsmod/core';
import { Serve, Server } from 'bun';

export class BunApplication extends Application {
protected override createServer(requestListener: any): any {
const serveOptions = this.appOptions.serverOptions as Serve;
serveOptions.fetch ??= (req) => requestListener(req);
return Bun.serve(serveOptions);
}

protected override async createServerAndBindToListening(appInitializer: AppInitializer, resolve: AnyFn) {
this.flushLogs();
const server = (await this.createServer(appInitializer.requestListener)) as Server;
this.systemLogMediator.serverListen(this, server.hostname, server.port);
resolve({ server });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Providers, Class } from '@ditsmod/core';

export class BunProviders extends Providers {
protected setCondition?: boolean;
protected ifCondition?: boolean;

if(condition: any) {
this.setCondition = true;
this.ifCondition = condition;
return this;
}

override useClass<A extends Class, B extends A>(token: A, useClass: B, multi?: boolean): this {
if (!this.setCondition || this.ifCondition) {
this.pushProvider({ token, useClass }, multi);
}
this.setCondition = undefined;
this.ifCondition = undefined;
return this;
}
}
61 changes: 61 additions & 0 deletions frameworks/TypeScript/ditsmod/src/app/bun-integration/node-res.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Writable } from 'node:stream';

export class NodeRes extends Writable {
#chunks: Buffer[] = [];
#resolve: (body: string) => void;
status: number = 200;
headers = {} as HeadersInit;
body = new Promise<any>((resolve) => (this.#resolve = resolve));
headersSent?: boolean;
statusText?: string;

set statusCode(statusCode: number) {
this.status = statusCode;
}

getHeader(name: string) {
return this.headers[name as keyof HeadersInit];
}

getHeaders() {
return this.headers;
}

setHeader(name: string, value: number | string | readonly string[]) {
this.headers = { ...this.headers, [name]: value } as HeadersInit;
return this;
}

writeHead(statusCode: number, headers?: HeadersInit): this;
writeHead(statusCode: number, statusMessage: string, headers?: HeadersInit): this;
writeHead(statusCode: number, statusMsgOrHeaders?: string | HeadersInit, headers?: HeadersInit): this {
this.status = statusCode;
if (typeof statusMsgOrHeaders == 'object') {
this.mergeHeaders(statusMsgOrHeaders);
} else {
this.statusText = statusMsgOrHeaders;
this.mergeHeaders(headers);
}
return this;
}

override _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void {
this.#chunks.push(Buffer.from(chunk));
callback();
}

override _final(callback: (error?: Error | null) => void): void {
const finalData = Buffer.concat(this.#chunks);
this.headersSent = true;
this.#resolve(finalData.toString());
callback();
}

protected mergeHeaders(headers: HeadersInit = {}) {
if (Array.isArray(headers)) {
headers.forEach(([key, val]) => ((this.headers as any)[key] = val));
} else {
this.headers = { ...this.headers, ...headers };
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { PreRouter } from '@ditsmod/core';
import { NodeRes } from './node-res.js';

export class BunPreRouter extends PreRouter {
override requestListener: any = async (req: Request) => {
const nodeReq = req as any;
const nodeRes = new NodeRes();

const url = new URL(req.url);
const uri = url.pathname;
const queryString = url.search.slice(1);
const { handle, params } = this.router.find(req.method as any, uri);
if (!handle) {
this.sendNotImplemented(nodeRes as any);
const body = await nodeRes.body;
return new Response(body, nodeRes);
}

await handle(nodeReq, nodeRes as any, params!, queryString).catch((err) => {
this.sendInternalServerError(nodeRes as any, err);
});

const body = await nodeRes.body;
return new Response(body, nodeRes);
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os from 'node:os';

const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
Bun.spawn(['bun', 'dist/main.bun.js'], {
stdio: ['inherit', 'inherit', 'inherit'],
env: { ...process.env },
});
}
12 changes: 12 additions & 0 deletions frameworks/TypeScript/ditsmod/src/main.bun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Serve, Server } from 'bun';

import { AppModule } from './app/app.module.js';
import { BunApplication } from './app/bun-integration/bun-application.js';

const reusePort = process.env.NODE_ENV == 'production';
const serverOptions = { port: 8080, hostname: '0.0.0.0', reusePort } as Serve;
const { server } = await new BunApplication().bootstrap(AppModule, {
serverOptions: serverOptions as any,
});

const bunServer = server as unknown as Server;
Loading

0 comments on commit a3ff927

Please sign in to comment.