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

WeakRef and FinalizationRegistry example #75

Open
wants to merge 1 commit into
base: esr115
Choose a base branch
from

Conversation

ptomato
Copy link
Collaborator

@ptomato ptomato commented Aug 28, 2023

An embedding must call JS::ClearKeptObjects() and set a callback for the HostCleanupFinalizationRegistry operation in order for WeakRef and FinalizationRegistry to work properly. This example illustrates the minimum that an embedding should do.

Comment on lines 38 to 40
// FIXME: Is it really necessary to have a custom job queue in order to use
// WeakRef and FinalizationRegistry? (And if not, is it a good idea to have one
// anyway in this example because that's how most embeddings will use it?)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one thing I'm not really sure about. I guess we could just clear kept objects and run finalization registry cleanups in the gc() function and the example would still work?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the FinalizationRegistry is defined based on job, I think it's better having some kind of job queue, but yes, it doesn't have to be JS::JobQueue-based one, and just "running the cleanup functions at some time future" is only the requirement here.

Also, for the purpose of example, the regular promise job handling can be omitted (or maybe add some comment that m_queue handling is optional?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a good point. I decided to keep the integration with JS::JobQueue but added some comments about it not being necessary if you want a more minimal FinalizationRegistry queue.

JS::CallArgs args = JS::CallArgsFromVp(argc, vp);

// FIXME: Should ClearKeptObjects be called anywhere in runJobs()?
JS::ClearKeptObjects(cx);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is in the right place. Should this be called as part of the job queue also?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does 3 separate things, where they're supposed to happen in different timing in practice:

So, the "GC" name sounds misleading, and I think it's better having 3 separate functions (or 2 if (1) is done by js::RunJobs) for each and make it clearer why each of them are necessary in the example.

If step (2) and (3) above becomes separate function, if (weakRef.deref() !== undefined) throw new Error("WeakRef"); can be put between them, so that it also illustrates what happens at which point.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great advice. I understand it a lot better after your explanation. I made 2 separate functions (one that only calls js::RunJobs and one that only calls JS_GC) and added comments inside the snippet of JS code.

Copy link
Contributor

@arai-a arai-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding example for this!
The basic structure looks good, but splitting the testing function can make the example clearer (see below)

Comment on lines 38 to 40
// FIXME: Is it really necessary to have a custom job queue in order to use
// WeakRef and FinalizationRegistry? (And if not, is it a good idea to have one
// anyway in this example because that's how most embeddings will use it?)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the FinalizationRegistry is defined based on job, I think it's better having some kind of job queue, but yes, it doesn't have to be JS::JobQueue-based one, and just "running the cleanup functions at some time future" is only the requirement here.

Also, for the purpose of example, the regular promise job handling can be omitted (or maybe add some comment that m_queue handling is optional?)

JS::CallArgs args = JS::CallArgsFromVp(argc, vp);

// FIXME: Should ClearKeptObjects be called anywhere in runJobs()?
JS::ClearKeptObjects(cx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does 3 separate things, where they're supposed to happen in different timing in practice:

So, the "GC" name sounds misleading, and I think it's better having 3 separate functions (or 2 if (1) is done by js::RunJobs) for each and make it clearer why each of them are necessary in the example.

If step (2) and (3) above becomes separate function, if (weakRef.deref() !== undefined) throw new Error("WeakRef"); can be put between them, so that it also illustrates what happens at which point.

@ptomato
Copy link
Collaborator Author

ptomato commented Feb 14, 2024

@arai-a Thanks for the review, I think your suggestions really improved the example. Could you take another look at the updated version?

Copy link
Contributor

@arai-a arai-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! the code looks good.

some nits on the comments.

examples/weakref.cpp Outdated Show resolved Hide resolved
examples/weakref.cpp Outdated Show resolved Hide resolved
examples/weakref.cpp Outdated Show resolved Hide resolved
An embedding must call JS::ClearKeptObjects() and set a callback for the
HostCleanupFinalizationRegistry operation in order for WeakRef and
FinalizationRegistry to work properly. This example illustrates the
minimum that an embedding should do.
@ptomato
Copy link
Collaborator Author

ptomato commented Feb 19, 2024

@arai-a I think your feedback made the comments clearer, so thanks! Would you like to take another look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants