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

Initial use cases to cover #1

Open
benjamingr opened this issue Sep 20, 2023 · 12 comments
Open

Initial use cases to cover #1

benjamingr opened this issue Sep 20, 2023 · 12 comments

Comments

@benjamingr
Copy link
Member

Some use cases from nodejs/TSC#1439 :

  • User using the REPL
  • Uncaught error handler
  • Unhandled rejection

Inspiration for format: https://github.com/nodejs/promise-use-cases

@ljharb
Copy link
Member

ljharb commented Sep 20, 2023

  • Tests, for packages that want to be robust against userland monkeypatching
  • polyfills for standard functionality that, by spec, must be robust against userland monkeypatching

@benjamingr
Copy link
Member Author

@aduh95
Copy link

aduh95 commented Sep 22, 2023

Here's how I see things: primordials are a tool that fulfils the need of "I want to access the primordial value of a V8-provided method/object/value", with "primordial" being defined as a bound value for methods, and the original value for the rest. In Node.js core, it seems to me that need comes from the following set of requirements that we set for ourselves:

  • I want to minimize the influence of userland on core APIs and vice-versa. (for UX reasons)
  • I want to write JS (for DX reasons)
  • I want the code to run on the same Realm as userland. (for UX/perf reasons)

I think everyone would agree that the same JS code can be written with and without primordials, the version using primordials will be less affected by userland changes (better for UX) and less readable (worse for DX) – and vice versa for the version not using primordials. Note that both UX and DX are subjective things, it's not something we can measure and each of us probably has a different opinion depending on what part of the code base we're talking about.

IMO it's not "fair" to list what are the areas we want "UX over DX" (i.e. primordials), because that's the current status quo, so it applies by default everywhere. I think it would work better list the areas of the codebase where we would want "DX over UX" (e.g. Matteo was often using the example of node:http as an area of the codebase where the upsides of primordials do not really apply, I'm happy to his word for it).

@benjamingr
Copy link
Member Author

@aduh95 that's why I want to use this repo to write a list of use cases for "regular people" using Node.js rather than focusng on subsystems. Those could help put what areas benefit from from the robustness than the loss of velocity.

I think we can get consensus over "primordials in specific areas" (With added non-primordial related robustness like not assuming property access doesn't throw etc) like error handling and test that. In those areas we probably want to take any performance or DX losses for robustness.

I think we can also get consensus over "no primordials" in certain areas that are less impacted by robustness where the usage of userland package means robustness defense against e.g. the user changing Array.prototype.push would be very minimally useful anyway.

I think in order to figure out what each type of code is we need the use cases :)

@aduh95
Copy link

aduh95 commented Sep 22, 2023

I think we can also get consensus over "no primordials" in certain areas that are less impacted by robustness where the usage of userland package means robustness defense against

We will probably need to define what "no primordials" means, because I can forsee it being open to interpretation, but it's a discussion for another time :)

Another use case: nodejs/node#32361

Maybe we could try to remove all the primordials and run a CITGM to see if any other use case arises 🤔

@benjamingr
Copy link
Member Author

I'm not sure what the use case there is other than "I explicitly want to override Functon.prototype.bind" is though? I recall at some point a long time ago Chrome broke we override .apply :D

@ljharb
Copy link
Member

ljharb commented Sep 22, 2023

I think it'd be quite reasonable to decide that by opting in to a specific core module, that core module may not be robust against userland monkeypatching. However, if I have no requires or imports in my code, I would expect that nothing I do in JS can possibly break node.

Separately, some core modules should be robust against userland monkeypatching - fs, path, child_process, and anything else that can result in security issues or severe bugs if not trustworthy.

Obviously we'd need to come to consensus on the specific content of those lists, but hopefully the basic concept isn't controversial?

@benjamingr
Copy link
Member Author

I think the expectation " if I have no requires or imports in my code, I would expect that nothing I do in JS can possibly break node." is reasonable but I think that includes requiring fs or child_process. Conversely process.on("uncaughtException" should mostly still fire and the REPL should mostly still work.

@benjamingr
Copy link
Member Author

But I think specifics would be easier to discuss once we have consensus on use cases

@benjamingr
Copy link
Member Author

@legendecas
Copy link
Member

legendecas commented Oct 6, 2023

Primordials should also be preferred in the prepare stack trace callback and source map handlers, for the same reason of the uncaught error handler and unhandled rejection handler.

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