- YouTube recording
- Hangouts Event
- issue for this meeting
- Google Doc for meeting notes
- previous meeting - none
- @pmuellr - Patrick Mueller (NodeSource)
- @stefanmb - Stefan Budeanu (IBM)
- @mhdawson - Michael Dawson (IBM)
- @orangemocha - Alexis Campailla (MS)
- @obastemur - Oguz Bastemur (JxCore)
- @Fishrock123 - Jeremiah Senkpiel (NodeSource)
- @Qard - Stephen Belanger (AppNeta)
- @No9 - Anton Whalley ()
- @trevnorris - Trevor Norris (NodeSource)
Note that this agenda was added to the issue for the meeting, but was not followed very closely during the meeting.
Goals
- JavaScript Engine API
- Currently Node C++ API leaks V8 and libuv internals, how do we abstract them?
- JXcore already provides a C++ JS engine abstraction layer1 can this work be reused, if so to what extent?
- Performance impact of abstracting JS engine.
- Practical limitations of abstracting the API. Much libuv/v8 specific functionality is currently in use by module authors. What is absolutely impossible to do in the abstraction?
- Internal Module API
- Define use cases for APIs at C/C++ vs. JS layers
- Native API
- JavaScript API
- What is the goal and scope of the JavaScript API? Are we standardizing existing Node API2 or providing a new, lower-level API (cf. "libuv.js" discussion3)?
- General Patterns4
- How is Node’s current architecture (Module -> Wrapper -> Native [libuv + others]) affected?
- List planned APIs in order of priority
- Standard Data Types needed for (1) and (2)
- Review proposed data types5
- API Definition
- C vs. C++ API
- Do we want the API to be C or C++?
- Is it even possible to wrap the JS engine with a C API (e.g. abstract V8’s handles)?
- WebAssembly Considerations6
- Threading7 (spawning, access thread, context, etc. information8 for each API interaction)
- Others (Impact assessment)
Actionable Items
- Define common data types (in progress)
- Pick a high-priority sub-API and create Proof of Concept
- Native layer PoC
- JS layer PoC
1 https://github.com/jxcore/jxcore/tree/master/src/jx/Proxy
2 https://nodejs.org/api/
3 https://github.com/nodejs/api/issues/1#issuecomment115851184
4 https://github.com/nodejs/api/blob/master/js/general_patterns.md
5 https://github.com/nodejs/api/blob/master/native/data_types.md
6 #3
7 WebAssembly/design#104
8 https://github.com/nodejs/api/issues/2#issuecomment119563867
(collected by Stefan Budeanu, thank you very much!)
Q: Is this working group ‘chartered’?
A: No, this is an informal work group. When a WG reaches a certain point they can receive authority over certain issues from the TSC. The area of authority may be too broad.
Q: Should we rename the repo to ‘api-wg’?
A: The name is strange, “nodejs-api” is not clearly indicative of the intent of this WG.
Q: What is the mission statement of this wg? Why is this interesting and relevant?
A: (Multiple)
Trevor: On the JavaScript side one issue being faced is that more and more features are being added and people want things to work in specific ways (e.g. async). They require that our API return “this thing”, but it’s impossible for us to support all APIs out there. The purpose of the JavaScript API is to remove as much abstraction as possible and use the fastest methods that V8 gives us to achieve that. Anyone that wants to attach their own API to Node’s internals can then do so using this performant API. It’s also important to be able to test easily, since companies like Oracle want clear-cut separation between JavaScript and V8 parts. Right now this is impossible to do. Certain things are just not tested right now, for example certain types of type coercions.
Alexis: API is constantly changing.
Patrick: How can we get to the point of running existing JavaScript Node.js on top of other JS engines? Distinction between API and “Service Provider Interface” (Michael). How does this fit in with existing APIs of Node today? We also have to cover ABI issues. This mission is very broad, but will lead to some well separated pieces of work.
Michael:
Internal APIs that we can use when building a service with Node.
Lower level API between Node.js and libuv / V8.
Trevor: Some features may not be available on all platforms, for example, SpiderMonkey cannot provide hooks for object resurrection on GC, whereas V8 may be able to. Certain APIs cannot be used.
Michael: Abstraction layer at the Node level and module level.
Trevor: We could probably abstract the current Node API for module authors, that doesn’t depend on many V8 internals. But the layer used between Node internal libs and V8 APIs cannot be abstracted between all platforms.
Alexis: Is it possible to isolate individual features that will not be available on certain platforms?
Trevor: For example, GC and object resurrection is used by the VM module. If you do not have this capability, you cannot use the VM module.
Michael: Even if you continue to use V8, if you abstract that layer you may also gain the ability to abstract between versions of V8, and once the API is defined, the specific incompatibilities would stand out, and we would have a clear view of what can and cannot be implemented on other JS engines.
Trevor: It would be possible to implement the entire existing node/lib API to sit on top of a new lower-level JavaScript API and if we were to abstract V8 itself from that as well, then we would not be Node anymore. Then Node is just the lib folder in the current repository. Abstraction of the module API will be a fair amount of work, since there are so many opinions of how it should be done. The abstraction of V8 and the JS API itself will be tremendous, it makes sense to build a lower-level API.
Alexis: You’re suggesting starting from scratch.
Trevor: That is essentially what we’re doing, and once the abstractions are done we can write the lib folder to sit on top of it, and then write the hooks on V8.
Alexis: What about JXcore’s approach?
Oguz: We have V8, chakra, and SpiderMonkey all sharing the same interface by using different proxies. The only tricky parts we are having are about the native types. We could have some sort of shimming approach, but due to differences in rooting among engines it’s very tricky to do. This is why we depend on macros extensively. I’m not sure if this is a good starting point or not. we can look at the source and discuss, but I am open to do it from scratch.
Alexis: Maybe the two approaches are not entirely exclusive. It may be possible to maintain a single codebase and use compile time switches.
Oguz: After proxying three different engines I don’t think it’s possible to have a stable long term ABI. But I think it’s a better goal to have a stable API. There are lots of native modules around and each new Node.js release some people expect module developers to update to latest Node.js/V8 API, and sometimes that’s not possible.
Alexis: In the worst case you could encapsulate the native engine types. But this may impose a cost of some performance.
Patrick: I think it’s clear that we don’t have a stable ABI for Node on V8 because V8 changes so much, so the only way we can have this is if we create it ourselves with adapter layers for various JavaScript engines. The question is how long would we want the ABI to unbreaking?
Michael: Java ABI has been unbreaking up until 9.
Trevor: Nan was able to temporarily achieve API compatibility.
Alexis: It may be a good idea to use a Foreign Function Interface. This would be much easier to implement using FFI as a native module interface.
Patrick: In Smalltalk we had a similar API to V8 API but we also had FFI. And therefore no one used the internal API since FFI was so much easier. I think this is actually a great idea, but this is not the way Node module authors think. We don’t have an FFI in Node 4 yet.
Jeremiah: FFI in Node.js will almost certainly end up being too slow (referring to node-ffi).
Alexis: Someone prototyped an FFI solution that doesn’t have to be much slower at all.
Trevor: Disagrees, no matter what you do it’s an order of magnitude slower. The type cohersions and object munching are so crazy expensive. Maybe another engine can do the conversions faster, but V8 is just too slow here. Doing a single object operation is too slow.
Alexis: But you wouldn’t be marshalling complex objects.
Patrick: FFI has ability to deal with pointers and structures, so it can get rich. I’m sure the perf is bad, as Trevor pointed out. Is someone already handling FFI?
Trevor: There’s been a discussion and a PR on this, and the implementation in the PR was scattered, so we decided if FFI is implemented it would have to be localized to just the FFI module due to the amount of exploits available. To simplify things for enterprise customers, they could just delete the FFI module, exposing it in JavaScript gives a huge amount of access. No one followed on this PR.
Jeremiah: The other thing is that FFI cannot be our only option, people have low power machines, and some of these Robotics style applications cannot accommodate FFI.
Alexis: Modules like Node inspector require a different interface.
Trevor: Right now we expose a lot of stuff to get information from Node about the process itself. If we allowed this abstraction, we just
Patrick: A debugging API may be another thing that we may want to look at, a bridge for some of the diagnostic introspective APIs that we have today in userland which probably don’t belong there.
Trevor: We very well might be bringing in V8 Inspector, it will be pulled out of Chromium, and it will be a self-contained module, that way we can send out all the debugging information using standard API.
Oguz: If V8 has a certain feature that is not shared by other engines, if Node.js for some reason would like to introduce some feature, what will we do on the API side? This is the breaking change.
Trevor: SpiderMonkey for example introduces many experimental features. What about modules that use features on one engine that cannot be supported on another?
Michael: It may be necessary to code to the lowest common denominator.
Trevor: Part of the reason for targeting the JS layer first is to be able to show that we can run all JS modules on whatever implementation. Native modules will be a much tougher nut to crack.
Alexis: Reducing the surface of the engine can only help this effort.
Trevor: In the worst case scenario there are many modules out there that are or use other native modules, the likelihood of them switching to the new API is low. We would depend on new modules to do so.
Alexis: I am working on a module build service to ease the pain of transitioning native modules. This would be a short term solution and API improvement would be the long term solution.
Patrick: We’re running out of time, so we should decide when we want to meet again - do we want to have another meeting and then coming up with a list of action items?
Once a month is the preferable option. Fit a meeting either before Thanksgiving or very early December.
Oguz: Interested in proving/disproving if FFI is a good approach.
Patrick & Oguz: The output may be a Node-compatible thing, but not Node itself.
Trevor: I’m not opposed to replacing all the internals, but this would be a years long task.
Oguz: This would also be a breaking change for NAN, if used, since it does not do anything for types.
Trevor: The team for Charka wrote a compatibility shim for Node, it would be interested to hear their feedback.
Alexis: I will try to pull them in as much as possible.
- action items? Not right now, creating issues!
- next meeting? In a month? No nays, so, schedule a meeting in Nov.
- every two weeks if action items to discuss
- issue/doodle for next meeting in a new issue
- None yet