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

Improve Channels & Goroutines implementation #78

Open
1 of 2 tasks
matthewmueller opened this issue Dec 16, 2017 · 3 comments
Open
1 of 2 tasks

Improve Channels & Goroutines implementation #78

matthewmueller opened this issue Dec 16, 2017 · 3 comments

Comments

@matthewmueller
Copy link
Owner

matthewmueller commented Dec 16, 2017

Originally we were planning on converting async/await into generators. However, as explained by @FlorianUekermann in #56, there's a good chance the async/await or generator implementation won't be enough:

If you are wondering why someone may want to use non-async event listeners in the first place, consider that JS has a well defined event flow (https://www.w3.org/TR/DOM-Level-3-Events/#event-flow), which gives you a lot of useful guarantees to work with (serial execution of event listeners, ordering of event listeners, bubbling, cancellation, etc.). All of that goes out the window once you are start using async.

Next steps:

  • Create a test case where async/await event handlers produce out of order events

UPDATE Alrighty yep, as suggested by @FlorianUekermann, the problem can be illustrated here: http://jsbin.com/ximexelepa/1/edit?html,js,output

  • Learn more about how gopherjs does it's scheduling
@FlorianUekermann
Copy link

FlorianUekermann commented Dec 16, 2017

Edit: Nevermind. Your example is more fun :-). Me posting and your edit overlapped.

function receiveFromChannel() {
  return new Promise(resolve => setTimeout(() => resolve(" 2 "), 1));
}
var b = document.querySelector("button");
var p = document.querySelector("p");
b.addEventListener("click", async e => {
  p.textContent = " 1 ";
  var val = await receiveFromChannel(1);
  p.textContent += val;
});
b.addEventListener("click", async e => {
  p.textContent += " 3 ";
});

https://codepen.io/anon/pen/RxWBed/
Prints 1 3 2 for me instead of 1 2 3.

And just to demonstrate how quickly things get really messy without serial execution:
Replace lines 8 and 9 with this:

p.textContent += await receiveFromChannel(1);;

https://codepen.io/anon/pen/rpOroG
Prints 1 2

@FlorianUekermann
Copy link

Regarding GopherJS scheduling. Here is the scheduler logic in case you are looking for it: https://github.com/gopherjs/gopherjs/blob/444abdf920945de5d4a977b572bcc6c674d1e4eb/compiler/prelude/goroutines.go#L228
That part is pretty straightforward. Saving go routine state may be a bit more involved, I haven't had to look at that stuff yet.

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

No branches or pull requests

2 participants