massive performance fixes

This commit is contained in:
HorizonCode 2023-05-12 10:16:26 +02:00
parent 42ae41ba87
commit 60b819b9a4
2 changed files with 43 additions and 38 deletions

View File

@ -5,12 +5,9 @@ import { HTTPServer } from "../mod.ts";
const httpServer = new HTTPServer(); const httpServer = new HTTPServer();
httpServer.middleware(async (req, done) => { httpServer.middleware(async (req, done) => {
const perStart = performance.now(); console.log(`${req.method} - ${req.remoteIpAddr} - ${req.path}`);
console.log(`${req.method} - ${req.ip()} - ${req.path}`); const processTime = await done();
await done(); console.log(`Processed in ${prettyTime(processTime)}`);
const pt = performance.now() - perStart;
const hrArray: number[] = [0, Math.trunc(pt * 1000000)];
console.log(`Processed in ${prettyTime(hrArray)}`);
}); });
httpServer.error((req, _rep) => { httpServer.error((req, _rep) => {

72
mod.ts
View File

@ -4,6 +4,7 @@ import {
} from "https://deno.land/std@0.186.0/http/http_status.ts"; } 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 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 * as cookie from "https://deno.land/std@0.185.0/http/cookie.ts";
import prettyTime from "npm:pretty-time";
type ListenOptions = { type ListenOptions = {
port: number; port: number;
@ -21,7 +22,7 @@ type RouteHandler = (
type RouteMiddlewareHandler = ( type RouteMiddlewareHandler = (
req: RouteRequest, req: RouteRequest,
done: () => Promise<unknown>, done: () => Promise<number[]>,
) => Promise<void>; ) => Promise<void>;
type RouteParam = { type RouteParam = {
@ -102,24 +103,26 @@ export class HTTPServer {
const filepath = decodeURIComponent( const filepath = decodeURIComponent(
"/" + requestEvent.request.url.split("/").slice(3).join("/"), "/" + requestEvent.request.url.split("/").slice(3).join("/"),
); );
const request = requestEvent.request;
const url = request.url;
const routeRequest = new RouteRequest( const routeRequest = new RouteRequest(
requestEvent.request, request,
conn, conn,
filepath, filepath,
requestEvent.request.url, url,
); );
const routeReply: RouteReply = new RouteReply(); const routeReply: RouteReply = new RouteReply();
if (filepath.startsWith("/_static")) { if (filepath.startsWith("/_static") || filepath.endsWith(".ico")) {
this.handleNotFound(routeRequest, routeReply, requestEvent); this.handleNotFound(routeRequest, routeReply, requestEvent);
continue; continue;
} }
let resolveAction: (value?: unknown) => void = () => {}; let resolveAction: (value: number[]) => void = () => {};
let middlewarePromise; let middlewarePromise;
const perStart = performance.now();
if (this.middlewareHandler) { if (this.middlewareHandler) {
middlewarePromise = (): Promise<unknown> => { middlewarePromise = (): Promise<number[]> => {
return new Promise((resolve) => { return new Promise((resolve) => {
resolveAction = resolve; resolveAction = resolve;
}); });
@ -138,14 +141,22 @@ export class HTTPServer {
try { try {
file = await Deno.open(pathLoc, { read: true }); file = await Deno.open(pathLoc, { read: true });
} catch { } 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); this.handleNotFound(routeRequest, routeReply, requestEvent);
continue; continue;
} }
const readableStream = file.readable; const readableStream = file.readable;
const response = new Response(readableStream); 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); await requestEvent.respondWith(response);
return; return;
} }
@ -163,7 +174,11 @@ export class HTTPServer {
handler = JSON.stringify(handler, null, 2); 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( await requestEvent.respondWith(
new Response(handler as string, { new Response(handler as string, {
status: routeReply.statusCode, status: routeReply.statusCode,
@ -195,7 +210,11 @@ export class HTTPServer {
routeRequest, routeRequest,
routeReply, routeReply,
); );
if (middlewarePromise) resolveAction(); if (middlewarePromise) {
const pt = performance.now() - perStart;
const hrArray: number[] = [0, Math.trunc(pt * 1000000)];
resolveAction(hrArray);
}
await requestEvent.respondWith( await requestEvent.respondWith(
new Response(handler as string, { new Response(handler as string, {
status: routeReply.statusCode, status: routeReply.statusCode,
@ -205,7 +224,11 @@ export class HTTPServer {
); );
continue; 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); this.handleNotFound(routeRequest, routeReply, requestEvent);
} }
} }
@ -297,7 +320,7 @@ export class RouteRequest {
method: HTTPMethod; method: HTTPMethod;
queryParams: { [key: string]: string }; queryParams: { [key: string]: string };
pathParams: { [key: string]: string }; pathParams: { [key: string]: string };
private remoteIpAddr: string; remoteIpAddr: string;
constructor(request: Request, conn: Deno.Conn, path: string, url: string) { constructor(request: Request, conn: Deno.Conn, path: string, url: string) {
this.url = url; this.url = url;
@ -311,25 +334,10 @@ export class RouteRequest {
: "127.0.0.1"; : "127.0.0.1";
} }
private paramsToObject(entries: IterableIterator<[string, string]>) { private paramsToObject(
const result: { [key: string]: string } = {}; entries: IterableIterator<[string, string]>,
for (const [key, value] of entries) { ): { [key: string]: string } {
result[key] = value; return Object.fromEntries(entries);
}
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;
} }
header(name: string): unknown { header(name: string): unknown {