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

GC integration question #213

Closed
guybedford opened this issue Jan 24, 2024 · 2 comments
Closed

GC integration question #213

guybedford opened this issue Jan 24, 2024 · 2 comments

Comments

@guybedford
Copy link

For implementors of APIs that create objects that are expected to be explicitly disposed, the consumer of that API is under no obligation to actually use the using syntax, because it is not enforced.

If they don't use the using syntax, there is still a risk the user does not dispose the resource, in which case having a GC finalizer can be beneficial.

As an API creator, I would ideally want one of the following guarantees:

  1. My users must use the using syntax so that they must dispose the resource.
  2. My API can be used optionally with explicit resource management, by also supporting GC integration.

I think otherwise this risks APIs intended to be consumed in this way to be vulnerable to a memory leak footgun by consumers.

If the GC integration is done manually, this involves manual tracking of the dispose state in Symbol.dispose in conjunction with a finalization registration.

Has there been much discussion around improving this common scenario?

@rbuckton
Copy link
Collaborator

Yes, #203, #195, #187, #160, #159, and #49 all touch on this in various ways. Per #195, I'm mostly interested in pursuing enforcement as a follow-on proposal if it seems like it is necessary. With using and await using shipping in TypeScript, we have the opportunity to gather feedback from real-world use of using. My hope is that such enforcement could ideally happen via a linter or type checker, as opposed to the runtime, and that new APIs could also lean on documentation and examples as guidance for acceptable use.

There are a large number of pre-exiting APIs across both the DOM and NodeJS that could readily adopt using/Symbol.dispose, but could never adopt an enforcement model without breaking existing callers. And there is little reason to bifurcate existing APIs for these cases when both would essentially produce the same value as that would just be moving the goalposts for enforcement.

So, for additional discussion on (1) above, I would suggest you follow up in #195. There are also examples of potential mitigations that require no additional follow-up, such as making [Symbol.dispose] into a getter which sets a flag indicating whether the disposer was captured before the object can continue to be used.

For (2) above, I brought up GC integration via FinalizationRegistry as a possible recommendation for APIs that wrap native handles, but the committee consensus was not to provide any such recommendation.

Closing as a duplicate of #195 and #159.

@rbuckton rbuckton closed this as not planned Won't fix, can't repro, duplicate, stale Jan 25, 2024
@yw662
Copy link

yw662 commented Jan 27, 2024

For the My API can be used optionally with explicit resource management part,
You can use FinalizationRegistry as a backup. Eg. let the returned Disposable be a proxy to the real result, let Symbol.dispose inform the real resource to dispose, and then let the FinalizationRegistry of the returned disposables to do the same.

This is for now the best you can have.

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

3 participants