Skip to content

Commit

Permalink
test of threading
Browse files Browse the repository at this point in the history
  • Loading branch information
mimiMonads committed Dec 14, 2024
1 parent eec3775 commit a962c7f
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 0 deletions.
72 changes: 72 additions & 0 deletions experimental/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { wrap } from "../main.ts";
import { bjscript } from "./multi.ts";
import { bench, run } from "mitata";

const serve = await wrap({
cyclePlugin: {
bjscript,
},
})()
.get({
path: "/",
f: ({ bjscript }) => {
return bjscript;
},
})
.get({
path: "/hi",
f: () => "Hi",
})
.compose();

const settings = {
algorithm: "argon2id", // "argon2id" | "argon2i" | "argon2d"
memoryCost: 4, // memory usage in kibibytes
timeCost: 3, // the number of iterations
};

const serve2 = await wrap()()
.get({
path: "/",
f: async ({ req }) => {
return await Bun.password.hash(req.url, settings);
},
})
.get({
path: "/hi",
f: () => "Hi",
})
.get({
path: "/hi2",
f: () => "Hi2",
})
.compose();

const req = new Request("http://localhost/");
const hi = new Request("http://localhost/hi");
const hi2 = new Request("http://localhost/hi2");

// await Promise.resolve(serve(req))
// .then(async r => await r.text())
// .then(console.log)

// await Promise.resolve(serve2(req))
// .then(async r => await r.text())
// .then(console.log)

const select =
((reqs: Request[]) => (n = 0) => n === 2 ? reqs[n = 0] : reqs[n = n + 1])([
req,
hi,
hi2,
]);

bench("latency with thread", async () => {
await serve(select());
});

bench("latency without thread", async () => {
await serve2(select());
});

await run();
67 changes: 67 additions & 0 deletions experimental/multi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { plugins } from "../main.ts";
import { isMainThread, parentPort, Worker } from "node:worker_threads";

const workerUrl = new URL(import.meta.url);

// We'll store the resolver in the same scope so the on('message') handler can see it.
let globalMessageResolver: ((value: string) => void) | null = null;

const createWorker = () => {
const worker = new Worker(workerUrl, { type: "module" });

// When the worker sends a message, resolve the promise if we have a resolver waiting.
worker.on("message", (msg) => {
if (globalMessageResolver) {
globalMessageResolver(msg);
globalMessageResolver = null;
}
});

return worker;
};

if (!isMainThread) {
if (parentPort === null) {
throw Error("Missing parentPort in worker thread");
}

const settings = {
algorithm: "argon2id", // "argon2id" | "argon2i" | "argon2d"
memoryCost: 4, // memory usage in kibibytes
timeCost: 3, // the number of iterations
};
parentPort.on("message", async (data) => {
const hash = await Bun.password.hash(data, settings);

parentPort.postMessage(hash);
});
}

const sealedwork = (w: Worker) => {
// Returns a function that sends a message to `w` and awaits the response
return async (msg: string) => {
return new Promise<string>((resolve) => {
// Tie the "globalMessageResolver" to *this* call's `resolve`.
globalMessageResolver = resolve;
w.postMessage(msg);
});
};
};

export const bjscript = plugins.type({
name: Symbol.for("hello"),
isFunction: false,
isAsync: true,
type: {} as string,
f: async () => {
// Create the worker once
const work = createWorker();
// Generate an async function that sends a message
const message = sealedwork(work);

// Return a function that, when called, sends "hi" and awaits response
return async (request) => {
return await message(request.url);
};
},
});
50 changes: 50 additions & 0 deletions experimental/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// A recursive type that attempts to represent all structured-clone-friendly values.
type StructuredCloneable =
// Primitives
| null
| undefined
| boolean
| number
| string
// Objects and arrays of cloneable types
| { [key: string]: StructuredCloneable }
| StructuredCloneable[]
// Maps and Sets of cloneable values
| Map<StructuredCloneable, StructuredCloneable>
| Set<StructuredCloneable>
// Date and RegExp
| Date
| RegExp
// Error objects (cloned with name/message only)
| Error
| EvalError
| RangeError
| ReferenceError
| SyntaxError
| TypeError
| URIError
// Binary / File types
| ArrayBuffer
| DataView
| Int8Array
| Uint8Array
| Uint8ClampedArray
| Int16Array
| Uint16Array
| Int32Array
| Uint32Array
| Float32Array
| Float64Array
// Potential big integer arrays if supported
// | BigInt64Array | BigUint64Array (if your environment supports them)
| Blob
| File
| FileList
// Image-related
| ImageData
| ImageBitmap
// OffscreenCanvas if supported by your environment
| OffscreenCanvas; // Streams (if supported) - this is highly environment-dependent
// | ReadableStream<any> | WritableStream<any> | TransformStream<any>
// WebAssembly modules (if supported)
// | WebAssembly.Module | WebAssembly.Instance

0 comments on commit a962c7f

Please sign in to comment.