-
Notifications
You must be signed in to change notification settings - Fork 67
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
Cross-realm invocation of async functions & generators #344
Comments
From a JS code observability POV, both async functions and generator functions are two-layers-deep contractual: a function that returns a thenable, a function that returns an iterator/generator.
There's no observable brand on syntactic async/generator functions today and it seems like this wrapping would depend on changing that (making non-syntactic realizations second-class as a consequence). For syntactic generator functions, there's also unique prototypes in play whose next/return/throw do not need to be the ancestral built-in methods. (Not sure if that would matter for a wrapper or not.) I'm not sure exactly what's possible here and may be misunderstanding something, but it's not clear to me how this mapping could be sound in the absence of a generic any-object membrane. |
The difference can be observed with Function toString, but without a full JS parser it’s not reliably determinable for every case. |
The callable boundary indeed prevents any function returning a non callable object from being wrapped transparently. Async and generator functions are a subset of functions that will indeed always fail when used through the boundary. In my mind, the current design of the callable boundary is not to be fully transparent, and thus they require the functions being passed across the boundary to be somewhat aware of the boundary primitive constraints. There are use cases that do not require a full membrane, such as a test runner environment setup. But if code interactions requires full transparency, then yes a membrane is likely required. |
It does seem reasonable to me to allow Promises for transferable values to themselves be transferred, tbh. |
In theory promises seem like a good candidate given their shape, but I have a concern: the implementation of cross realm promise resolution is fraught with issues, and there are currently cases where the realm leaks through. I'd be very worried about that complexity poking a hole into the strict callable boundary guarantees. |
This is accurate. I personally want to see a follow up to this proposal with a design that wraps the results of Async and/or Generator functions. The main use cases where this proposal is being applied to doesn't need that functionality, but I understand the ergonomics of wrapping thenables/promises and iterators can be good to a broader range of usage. The challenge is how we best design it, so that's why I'd love to explore this on its own pace, while the current implementation allows us to better see what ends we want to expand first. #336 is one of those ends we also need to explore. |
I think this is very important for the SSR use cases. More SSR implementations are moving to streaming by returning a sync or async iterable of strings. |
Are promises and iterators return values not something a lightweight user land abstraction could handle for now? I understand it's not straightforward to implement, but it should be a lot less complex than a full membrane. We only need one library that does this, then we can look into standardizing it. |
If an async function or generator is wrapped, their invocation will always throw an exception (due to returning a generator object or Promise) -- but this doesn't totally translate to how they're actually used in practice.
Would it make sense for async functions and generators to be wrappable, with wrapper Generator objects and wrapper Promises?
The text was updated successfully, but these errors were encountered: