Skip to content

Instantly share code, notes, and snippets.

@developit
Last active January 29, 2021 08:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developit/db59a1b6930242efd8f142722edbe4ab to your computer and use it in GitHub Desktop.
Save developit/db59a1b6930242efd8f142722edbe4ab to your computer and use it in GitHub Desktop.

Greenlet for Node worker_threads

Works with ESM and CommonJS.

import greenlet from 'greenlet-node';

const add = greenlet(async (a, b) => {
  return a + b;
});

await add(1, 2);

Example 2:

import greenlet from 'greenlet-node';

const add = greenlet(async (a, b) => {
  const someLib = require('some-lib');
  return someLib.add(a, b);
});

await add(1, 2);
const { Worker } = require('worker_threads');
/** @template {(...a:any)=>any} T @type {(fn: T) => (...args: Parameters<T>) => Promise<ReturnType<T>>} */
module.exports = function greenlet(fn) {
let w,
ids = 0;
return (...args) =>
new Promise((resolve, reject) => {
if (!w) {
w = new Worker(
`((p, fn) => p.on('message',async([id,args]) => {
try { p.postMessage([id, true, await fn.apply(null, args)]) }
catch (e) { p.postMessage([id, false, String(e && e.stack || e)]) }
}))(require('worker_threads').parentPort, ${fn})`,
{ eval: true }
);
}
let id = ++ids;
w.on('message', function h([rid, success, result]) {
if (rid == id) w.removeListener('message', h), (success ? resolve : reject)(result);
});
w.postMessage([id, args]);
});
}
import greenlet from './greenlet-node.js';
export default greenlet;
{
"name": "greenlet-node",
"version": "0.0.1",
"main": "./greenlet-node.js",
"exports": {
"import": "./greenlet-node.mjs",
"default": "./greenlet-node.js"
}
}
@winston0410
Copy link

Hi it seems like that this package is not published yet, can I help and publish this as a package for my own use? I think it will be more appropriate if you would publish it or I try to make a pull request to greenlet and make it usable in both browser and node?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment