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

Support for terminating workers? #33

Closed
JamesLMilner opened this issue May 26, 2018 · 5 comments
Closed

Support for terminating workers? #33

JamesLMilner opened this issue May 26, 2018 · 5 comments

Comments

@JamesLMilner
Copy link

JamesLMilner commented May 26, 2018

At the moment it doesn't appear greenlet supports terminating threads. From my experimentation it appears that even if workers are not referenced they do not seem to be destroyed:

spectacle b18024

After about 20 threads the client will become unresponsive / crash.

Being able to do something like:

import greenlet from 'greenlet'

let getName = greenlet( async username => {
    let url = `https://api.github.com/users/${username}`
    let res = await fetch(url)
    let profile = await res.json()
    return profile.name
})

console.log(await getName('developit'))
getName.terminate(); // Not sure if that's actually possible with the current setup

Would potentially help with the Web Worker lifecycle management.

@developit
Copy link
Owner

developit commented May 29, 2018

Hmm - the idea is that you should never be reexecuting greenlet() more than once per function. Creating threads in a loop is going to be bad for performance whether they get cleaned up or not.

FWIW it should be possible to create self-destruction workers using close():

const foo = greenlet(async () => {
  setTimeout(() => close());

  return 'hello'
});

@pixelbucket-dev
Copy link

pixelbucket-dev commented May 24, 2019

Where does close() come from?

Wouldn't it be good to expose a terminate function from greenlet?

So WRT to the Readme example something like:

import greenlet from 'greenlet'

let {postMessage: getName, terminate} = greenlet( async username => {
    let url = `https://api.github.com/users/${username}`
    let res = await fetch(url)
    let profile = await res.json()
    return profile.name
})

console.log(await getName('developit'))
terminate();

@pixelbucket-dev
Copy link

pixelbucket-dev commented May 24, 2019

What I found is to only instantiate greenlet on the module level, never inside a class/component. This avoids re-instantiation and therefore memory leaks. This should probably be documented because it is very important.

@developit
Copy link
Owner

developit commented Oct 1, 2019

@NudelSieb yes, that's exactly right. I've added a section in the readme that clarifies this. Dynamic instantiation of workers for a task is rarely a good idea.

@dwaltrip
Copy link

dwaltrip commented Feb 4, 2022

First, thanks for developing and sharing this library! It looks great, and seems to make things much more ergonomic for many common use cases.

I have an expensive computation I'm doing: runExpensiveCalc(userInput). If the user changes the inputs while it is computing, then the old computation is no longer valid, and I need to re-run it with the new inputs.

This is my first time using Web Workers, but using vanilla workers, it looks like I can do this by calling terminate on the first worker and then start a second worker that receives the new user inputs. Without terminate, the first worker would needlessly continue working on its computation, which is now irrelevant.

Is there another way of doing this without terminate? Or is greenlet not intended for long-running computations that may need to be stopped?

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

No branches or pull requests

4 participants