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

JS: Use async generator instead of callbacks + add tests #1773

Merged
merged 4 commits into from
Oct 12, 2023

Conversation

yuvipanda
Copy link
Collaborator

@yuvipanda yuvipanda commented Oct 10, 2023

JS now also supports writing async code with Asnc Generators which work very much like how async code would in Python. This allows us to write code that flows better, is more familiar to python folks, and avoids messy callback hell.

This code is a straight port of the existing callback based code to use an Async Generator instead. The EventIterator library is a very helpful convenience function here, allowing us to translate the callbacks from EventSource into an async generator without having to write a queue of promises ourselves. The iterator is stopped exactly the same way the callbacks were earlier stopped (whenever .stop() is called).

All the callbacks have been switched over to a switch / case statement instead. We can get cleaner and use exceptions to handle failures, instead of the 'failure' case, but that can come in a later PR so this is a purely mechanical refactoring from one async method to another.

An appropriate test for this is also added. To fully test the EventSource flow, we create a temporary web server that will serve a real captured eventsource response, with 1ms gaps between lines to fully simulate how this would work in reality. This gives us much more confidence about how this would work than mocking.

With this, @jupyterhub/binder-client now has 100% unit test coverage!

Ref #774

Here is a video of me testing this. I tested both something that worked, and an image that is known to fail (RStudio on ARM).

Screen.Recording.2023-10-10.at.12.40.52.AM.mov

JS now also supports writing async code with [Asnc
Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator)
which work very much like how async code would in Python. This
allows us to write code that flows better, is more familiar to
python folks, and avoids messy callback hell.

This code is a *straight* port of the existing callback
based code to use an Async Generator instead. The EventIterator
library is a very helpful convenience function here, allowing us
to translate the callbacks from EventSource into an async
generator without having to write a queue of promises ourselves.
The iterator is stopped exactly the same way the callbacks were
earlier stopped (whenever .stop() is called).

All the callbacks have been switched over to a switch / case
statement instead. We can get cleaner and use exceptions to handle failures,
instead of the 'failure' case, but that can come in a later PR so
this is a purely mechanical refactoring from one async method to
another.

An appropriate test for this is also added. To fully test the
EventSource flow, we create a temporary web server that will serve
a real captured eventsource response, with 1ms gaps between lines
to fully simulate how this would work in reality. This gives us
much more confidence about how this would work than mocking.

With this, @jupyterhub/binder-client now has 100% unit test
coverage!

Ref jupyterhub#774
@yuvipanda
Copy link
Collaborator Author

I added a screen recording of me testing this as well.

@consideRatio consideRatio added maintenance Under the hood improvements and fixes code:html/js/css html/js/css changes. code:js-binderhub-client js changes to binderhub-client labels Oct 10, 2023
@consideRatio
Copy link
Member

I'm not soo comfortable reviewing the JS code, but I think this makes sense and I didn't spot any issues are carefully going through this PR.

Thank you @yuvipanda for working this! This seems great!!

@consideRatio
Copy link
Member

I think its a good call to opt for a merge at this point even though I'm not so confident reviewing this, it helps with Yuvi's contribution momentum and we aren't introducing new API or similar that we commit to long term in this PR either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code:html/js/css html/js/css changes. code:js-binderhub-client js changes to binderhub-client maintenance Under the hood improvements and fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants