From 17dd0b6f0c169cdb6f64868ab905257d4585af52 Mon Sep 17 00:00:00 2001 From: maxmcd Date: Sun, 30 Jun 2024 12:14:42 -0400 Subject: [PATCH 1/5] Add injectable spawn function --- src/DenoHTTPWorker.ts | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/DenoHTTPWorker.ts b/src/DenoHTTPWorker.ts index 1449890..7d3e2ea 100644 --- a/src/DenoHTTPWorker.ts +++ b/src/DenoHTTPWorker.ts @@ -20,6 +20,26 @@ interface OnExitListener { (exitCode: number, signal: string): void; } +interface MinimalChildProcess { + stdout: Readable | null; + stderr: Readable | null; + readonly pid?: number | undefined; + readonly exitCode: number | null; + kill(signal?: NodeJS.Signals | number): boolean; + on(event: string, listener: (...args: any[]) => void): this; + on( + event: "close", + listener: (code: number | null, signal: NodeJS.Signals | null) => void + ): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on( + event: "exit", + listener: (code: number | null, signal: NodeJS.Signals | null) => void + ): this; + on(event: "spawn", listener: () => void): this; +} + export interface DenoWorkerOptions { /** * The path to the executable that should be use when spawning the subprocess. @@ -66,7 +86,16 @@ export interface DenoWorkerOptions { /** * Callback that is called when the process is spawned. */ - onSpawn?: (process: ChildProcess) => void; + onSpawn?: (process: MinimalChildProcess) => void; + + /** + * Provide an alternative spawn functions. Defaults to child_process.spawn. + */ + spawnFunc: ( + command: string, + args: string[], + options: SpawnOptions + ) => MinimalChildProcess; } /** @@ -83,6 +112,7 @@ export const newDenoHTTPWorker = async ( printCommandAndArguments: false, spawnOptions: {}, printOutput: false, + spawnFunc: spawn, ...options, }; @@ -157,7 +187,7 @@ export const newDenoHTTPWorker = async ( console.log("Spawning deno process:", [command, ...args]); } - const process = spawn(command, args, _options.spawnOptions); + const process = _options.spawnFunc(command, args, _options.spawnOptions); let running = false; let exited = false; let worker: DenoHTTPWorker | undefined = undefined; @@ -251,7 +281,7 @@ export interface DenoHTTPWorker { class denoHTTPWorker { #onexitListeners: OnExitListener[]; - #process: ChildProcess; + #process: MinimalChildProcess; #socketFile: string; #stderr: Readable; #stdout: Readable; @@ -260,7 +290,7 @@ class denoHTTPWorker { constructor( socketFile: string, - process: ChildProcess, + process: MinimalChildProcess, stdout: Readable, stderr: Readable ) { From 89da3f13e5b2f99d1191527780ed3dcd8103b52b Mon Sep 17 00:00:00 2001 From: maxmcd Date: Sun, 30 Jun 2024 12:19:19 -0400 Subject: [PATCH 2/5] add test --- src/DenoHTTPWorker.test.ts | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/DenoHTTPWorker.test.ts b/src/DenoHTTPWorker.test.ts index 3c42f2c..b2ce70d 100644 --- a/src/DenoHTTPWorker.test.ts +++ b/src/DenoHTTPWorker.test.ts @@ -3,6 +3,8 @@ import { DenoHTTPWorker, newDenoHTTPWorker } from "./index.js"; import fs from "fs"; import path from "path"; import { Worker } from "worker_threads"; +import { SpawnOptions, spawn } from "child_process"; +import { aC } from "vitest/dist/reporters-LqC_WI4d.js"; // Uncomment this if you want to debug serial test execution // const it = _it.concurrent; @@ -71,6 +73,29 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => { worker.terminate(); }); + it("alternate spawnFunc can be provided", async () => { + let firstArg: string = ""; + const worker = await newDenoHTTPWorker( + ` + export default { async fetch (req: Request): Promise { + let headers = {}; + for (let [key, value] of req.headers.entries()) { + headers[key] = value; + } + return Response.json({ ok: req.url, headers: headers }) + } } + `, + { + spawnFunc: (command: string, args: string[], options: SpawnOptions) => { + firstArg = args[0] as string; + return spawn(command, args, options); + }, + } + ); + expect(firstArg).toEqual("run"); + worker.terminate(); + }); + it("dont crash on socket removal", async () => { const worker = await newDenoHTTPWorker( ` @@ -104,9 +129,13 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => { { printOutput: true } ); for (let i = 0; i < 10; i++) { - const json = await jsonRequest(worker, "https://localhost/hello?isee=you", { - headers: { accept: "application/json" }, - }); + const json = await jsonRequest( + worker, + "https://localhost/hello?isee=you", + { + headers: { accept: "application/json" }, + } + ); expect(json).toEqual({ ok: "https://localhost/hello?isee=you", headers: { accept: "application/json" }, From 2233b773745a4004c55ff3950f51eedd285d30f4 Mon Sep 17 00:00:00 2001 From: maxmcd Date: Sun, 30 Jun 2024 12:21:06 -0400 Subject: [PATCH 3/5] lint --- src/DenoHTTPWorker.test.ts | 1 - src/DenoHTTPWorker.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/DenoHTTPWorker.test.ts b/src/DenoHTTPWorker.test.ts index b2ce70d..e6e01ce 100644 --- a/src/DenoHTTPWorker.test.ts +++ b/src/DenoHTTPWorker.test.ts @@ -4,7 +4,6 @@ import fs from "fs"; import path from "path"; import { Worker } from "worker_threads"; import { SpawnOptions, spawn } from "child_process"; -import { aC } from "vitest/dist/reporters-LqC_WI4d.js"; // Uncomment this if you want to debug serial test execution // const it = _it.concurrent; diff --git a/src/DenoHTTPWorker.ts b/src/DenoHTTPWorker.ts index 7d3e2ea..f7e4cff 100644 --- a/src/DenoHTTPWorker.ts +++ b/src/DenoHTTPWorker.ts @@ -1,5 +1,5 @@ import path, { resolve } from "node:path"; -import { ChildProcess, spawn, SpawnOptions } from "node:child_process"; +import { spawn, SpawnOptions } from "node:child_process"; import { Readable } from "node:stream"; import readline from "node:readline"; import http from "node:http"; From 73a5debfa0ecd3f90a991939807d5f782409f9fd Mon Sep 17 00:00:00 2001 From: maxmcd Date: Sun, 30 Jun 2024 12:23:18 -0400 Subject: [PATCH 4/5] format --- src/DenoHTTPWorker.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DenoHTTPWorker.test.ts b/src/DenoHTTPWorker.test.ts index e6e01ce..794703a 100644 --- a/src/DenoHTTPWorker.test.ts +++ b/src/DenoHTTPWorker.test.ts @@ -131,9 +131,7 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => { const json = await jsonRequest( worker, "https://localhost/hello?isee=you", - { - headers: { accept: "application/json" }, - } + { headers: { accept: "application/json" } } ); expect(json).toEqual({ ok: "https://localhost/hello?isee=you", From 4d3c837222bbd9d0290f0a3c1077546d7be53afa Mon Sep 17 00:00:00 2001 From: maxmcd Date: Sun, 30 Jun 2024 12:24:09 -0400 Subject: [PATCH 5/5] 0.0.16 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 027b2d9..21acb28 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "deno-http-worker", - "version": "0.0.15", + "version": "0.0.16", "description": "", "main": "dist/index.js", "types": "./dist/index.d.ts", "scripts": { "test": "vitest run", "test:watch": "vitest", - "lint" : "eslint . && npm run lint:deno-bootstrap && npm run lint:deno-test-files", + "lint": "eslint . && npm run lint:deno-bootstrap && npm run lint:deno-test-files", "lint:deno-bootstrap": "cd deno-bootstrap && deno lint", "lint:deno-test-files": "cd src/test && deno lint", "build": "tsc --build",