Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug or unexcepted usage with the thread pool #270

Closed
homura opened this issue Jun 26, 2020 · 3 comments · Fixed by #271
Closed

Bug or unexcepted usage with the thread pool #270

homura opened this issue Jun 26, 2020 · 3 comments · Fixed by #271
Labels

Comments

@homura
Copy link

homura commented Jun 26, 2020

// main.ts
import { Pool, spawn, Worker } from 'threads';

const pool = Pool(() => spawn(new Worker('./worker')), 1);

const task1 = pool.queue(function(x) {
  return x(1, 1);
});
const task2 = pool.queue(function(x) {
  return x(2, 2);
});
const task3 = pool.queue(function(x) {
  return x(3, 3);
});
const task4 = pool.queue(function(x) {
  return x(4, 5);
});

const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function main() {
  // uncomment follow `await`, and it will never be resolved if the `await` takes longer than tasks
  // await wait(1000);
  await task1.then(console.log);
  await task2.then(console.log);
  await task3.then(console.log);
  await task4.then(console.log);

  await pool.terminate();
}

main();
// worker.js
const { expose } = require("threads/worker");

const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function add(a, b) {
  // simulate a CPU calculation heavily
  await wait(50);
  return a + b;
}

expose(add);

To make it works as expected, I need to keep the Promise manually

// main.ts
import { Pool, spawn, Worker } from 'threads';

const pool = Pool(() => spawn(new Worker('./worker')), 1);

const task1 = pool.queue(function(x) {
  return x(1, 1);
}).then;
const task2 = pool.queue(function(x) {
  return x(2, 2);
}).then;
const task3 = pool.queue(function(x) {
  return x(3, 3);
}).then;
const task4 = pool.queue(function(x) {
  return x(4, 5);
}).then;

const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function main() {
  // now it works, but I can't cancel tasks anymore
  await wait(1000);
  await task1(console.log);
  await task2(console.log);
  await task3(console.log);
  await task4(console.log);

  await pool.terminate();
}

main();
andywer added a commit that referenced this issue Jun 26, 2020
Fixes #270. When you subscribed to a task's completion too late, it might have been resolved already, but the newly created promise would not know that and stay in a pending state forever.
@andywer andywer added the bug label Jun 26, 2020
@andywer
Copy link
Owner

andywer commented Jun 26, 2020

Hey @homura! Thanks for reporting.

Can you try to monkey-patch the fix I drafted in #271? Haven't had time to try it yet, but that should solve it.

@andywer
Copy link
Owner

andywer commented Jun 26, 2020

(The PR's tests are failing right now, because the error handling needs to be tweaked, but you should be able to check if that solves your particular issue)

@homura
Copy link
Author

homura commented Jun 26, 2020

Hey @homura! Thanks for reporting.

Can you try to monkey-patch the fix I drafted in #271? Haven't had time to try it yet, but that should solve it.

Yes, it resolved my problem now. Thanks for your quick fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants