From 60b819b9a49552df66fa422b240ce1d01e9ebb1a Mon Sep 17 00:00:00 2001 From: HorizonCode Date: Fri, 12 May 2023 10:16:26 +0200 Subject: [PATCH] massive performance fixes --- example/test.ts | 9 +++---- mod.ts | 72 +++++++++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/example/test.ts b/example/test.ts index 65d87f3..7fe26c2 100644 --- a/example/test.ts +++ b/example/test.ts @@ -5,12 +5,9 @@ import { HTTPServer } from "../mod.ts"; const httpServer = new HTTPServer(); httpServer.middleware(async (req, done) => { - const perStart = performance.now(); - console.log(`${req.method} - ${req.ip()} - ${req.path}`); - await done(); - const pt = performance.now() - perStart; - const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; - console.log(`Processed in ${prettyTime(hrArray)}`); + console.log(`${req.method} - ${req.remoteIpAddr} - ${req.path}`); + const processTime = await done(); + console.log(`Processed in ${prettyTime(processTime)}`); }); httpServer.error((req, _rep) => { diff --git a/mod.ts b/mod.ts index 8ae5657..30c9cad 100644 --- a/mod.ts +++ b/mod.ts @@ -4,6 +4,7 @@ import { } from "https://deno.land/std@0.186.0/http/http_status.ts"; import * as path from "https://deno.land/std@0.185.0/path/mod.ts"; import * as cookie from "https://deno.land/std@0.185.0/http/cookie.ts"; +import prettyTime from "npm:pretty-time"; type ListenOptions = { port: number; @@ -21,7 +22,7 @@ type RouteHandler = ( type RouteMiddlewareHandler = ( req: RouteRequest, - done: () => Promise, + done: () => Promise, ) => Promise; type RouteParam = { @@ -102,24 +103,26 @@ export class HTTPServer { const filepath = decodeURIComponent( "/" + requestEvent.request.url.split("/").slice(3).join("/"), ); + const request = requestEvent.request; + const url = request.url; const routeRequest = new RouteRequest( - requestEvent.request, + request, conn, filepath, - requestEvent.request.url, + url, ); const routeReply: RouteReply = new RouteReply(); - if (filepath.startsWith("/_static")) { + if (filepath.startsWith("/_static") || filepath.endsWith(".ico")) { this.handleNotFound(routeRequest, routeReply, requestEvent); continue; } - let resolveAction: (value?: unknown) => void = () => {}; + let resolveAction: (value: number[]) => void = () => {}; let middlewarePromise; - + const perStart = performance.now(); if (this.middlewareHandler) { - middlewarePromise = (): Promise => { + middlewarePromise = (): Promise => { return new Promise((resolve) => { resolveAction = resolve; }); @@ -138,14 +141,22 @@ export class HTTPServer { try { file = await Deno.open(pathLoc, { read: true }); } catch { - if (middlewarePromise) resolveAction(); + if (middlewarePromise) { + const pt = performance.now() - perStart; + const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; + resolveAction(hrArray); + } this.handleNotFound(routeRequest, routeReply, requestEvent); continue; } const readableStream = file.readable; const response = new Response(readableStream); - if (middlewarePromise) resolveAction(); + if (middlewarePromise) { + const pt = performance.now() - perStart; + const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; + resolveAction(hrArray); + } await requestEvent.respondWith(response); return; } @@ -163,7 +174,11 @@ export class HTTPServer { handler = JSON.stringify(handler, null, 2); } - if (middlewarePromise) resolveAction(); + if (middlewarePromise) { + const pt = performance.now() - perStart; + const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; + resolveAction(hrArray); + } await requestEvent.respondWith( new Response(handler as string, { status: routeReply.statusCode, @@ -195,7 +210,11 @@ export class HTTPServer { routeRequest, routeReply, ); - if (middlewarePromise) resolveAction(); + if (middlewarePromise) { + const pt = performance.now() - perStart; + const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; + resolveAction(hrArray); + } await requestEvent.respondWith( new Response(handler as string, { status: routeReply.statusCode, @@ -205,7 +224,11 @@ export class HTTPServer { ); continue; } - if (middlewarePromise) resolveAction(); + if (middlewarePromise) { + const pt = performance.now() - perStart; + const hrArray: number[] = [0, Math.trunc(pt * 1000000)]; + resolveAction(hrArray); + } this.handleNotFound(routeRequest, routeReply, requestEvent); } } @@ -297,7 +320,7 @@ export class RouteRequest { method: HTTPMethod; queryParams: { [key: string]: string }; pathParams: { [key: string]: string }; - private remoteIpAddr: string; + remoteIpAddr: string; constructor(request: Request, conn: Deno.Conn, path: string, url: string) { this.url = url; @@ -311,25 +334,10 @@ export class RouteRequest { : "127.0.0.1"; } - private paramsToObject(entries: IterableIterator<[string, string]>) { - const result: { [key: string]: string } = {}; - for (const [key, value] of entries) { - result[key] = value; - } - return result; - } - - ip() { - const cfConnectingIp: string = this.header("cf-connecting-ip") as string; - if (cfConnectingIp && cfConnectingIp.length > 0) return cfConnectingIp; - - const xRealIp: string = this.header("x-real-ip") as string; - if (xRealIp && xRealIp.length > 0) xRealIp; - - const xForwardedFor: string = this.header("x-forwarded-For") as string; - if (xForwardedFor && xForwardedFor.length > 0) return xForwardedFor; - - return this.remoteIpAddr; + private paramsToObject( + entries: IterableIterator<[string, string]>, + ): { [key: string]: string } { + return Object.fromEntries(entries); } header(name: string): unknown {