Skip to content

Could the goroutines support be accomplished with generators? #107

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

Closed
getify opened this issue Oct 16, 2014 · 10 comments
Closed

Could the goroutines support be accomplished with generators? #107

getify opened this issue Oct 16, 2014 · 10 comments

Comments

@getify
Copy link

getify commented Oct 16, 2014

Apologies for not knowing much about the internals of how this works, but I was just curious when reading the discussion about how goroutines look for blocking calls and process them, etc... would it be possible to support go-style CSP goroutines more directly, using generators and a channels API, similarl to how libs like these work:

@andrewchambers
Copy link

Is yield actually implemented in all major browsers and enabled by default?

@getify
Copy link
Author

getify commented Oct 17, 2014

Generators are enabled by default in both Chrome and FF... but of course there will be some browsers people want to target that don't yet have such support.

So if you wanted to pursue generators as the compilation target for goroutines, the optional step you could also provide is one of any number of generators transpilers, which allows generator code to converted to ES5 code.

My suggestion would be this goroutine stuff could be handled in two stages:

  1. Transpile Go goroutines to the ES6 generators equivalents, naturally... would remove the need to parse code to infer which things needed special handling.
  2. (Optional) Allow another transpilation of the generators' code to ES5 equivalent, for those who want to target other browsers besides Chrome and FF.

@neelance
Copy link
Member

I looked into generators some time ago and the main problem of using them for goroutines is that yield needs to be inside of the generator function. It can't be in some other function called from the generator. For example this snippet does not work:

function* test1(){
  yield 0;
  test2();
  yield 2;
}

function test2() {
  yield 1;
}

var gen = test1();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

But I am open to suggestions!

@getify
Copy link
Author

getify commented Oct 19, 2014

JS generators are shallow continuations, not deep continuations, so yield can't just be buried and have that unroll the entire call stack. But there is yield* yield-delegation, so this would work:

function* test1(){
  yield 0;
  yield* test2();   // <-- notice `yield*` yield delegation
  yield 2;
}

function* test2() { // <-- this has to be a `function*` generator, too
  yield 1;
}

var gen = test1();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

@neelance
Copy link
Member

That's interesting. I did not know about yield*. Thanks for bringing that to my attention, I will definitely take a deeper look at this option.

@getify
Copy link
Author

getify commented Oct 19, 2014

For my own academic purposes, since i've implemented a goroutine-style CSP layer in my own async flow lib, I'd love to know if there end up being any cases where goroutines couldn't be transpiled to generators. cheers! :)

@liamcurry
Copy link

This isn't related to generators, but could goroutines be implemented using WebWorkers and Data URIs? See this question on StackOverflow and this example on jsfiddle.

@getify
Copy link
Author

getify commented Dec 23, 2014

@liamcurry FYI: I am actually working on a PoC for a CSP channel that's backed by non-local connections, like WebSockets, WebWorkers, etc. My goal then would be to have a CSP process running in the main thread, and communicating via channels to either a Worker or a server where another CSP process was running, paired with that channel. Not sure if that's exactly what you're getting at, but just figured I'd mention it.

@andrewchambers
Copy link

Goroutines have no concept of identity, but any code is allowed in a go routine. All "system calls" would need to be serialized and run in the main browser thread which complicates things.

@dmitshur dmitshur mentioned this issue Sep 1, 2015
@neelance
Copy link
Member

I just looked into https://github.com/google/traceur-compiler and http://facebook.github.io/regenerator/ and they both seem to use closures to create scopes for local variables. This also was my first approach for implementing goroutines, but it proved to be very slow for code that may block but in practice does not block very often (or at all). This is why I switched to a different method that has a low cost when not blocking and a higher cost for switching goroutines when code blocks. This improves the overall performance a lot.
Thus, using yield or await and a JS transpiler for browser compatibility will not lead to good performance. We can revisit this approach when those JS features have reached widespread support, but this will probably still take a while. For now, I'd like to close this issue since there is no further action I can take, except one of you has a good follow-up idea.

@flimzy flimzy mentioned this issue Jan 29, 2019
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