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

During testing the GC will run after every test. #173

Merged
merged 1 commit into from
Nov 18, 2022

Conversation

Warfields
Copy link
Contributor

Automatically run garbage collection after each EW test to catch kj::Own/IoOwn issues.

@@ -77,6 +77,9 @@ class IsolateBase {
// Immediately cancels JavaScript execution in this isolate, causing an uncatchable exception to
// be thrown. Safe to call across threads, without holding the lock.

void requestGcForTesting() const;
Copy link
Member

Choose a reason for hiding this comment

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

I'd put this method on jsg::Lock rather than IsolateBase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do. Just curious, what is your reasoning on putting it on the jsg::Lock instead of IsolateBase

Copy link
Member

Choose a reason for hiding this comment

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

It makes your code simpler as you don't have to do IsolateBase::from().

In general jsg::Lock is the place for all general JavaScript runtime functionality that isn't connected to a specific object.

Copy link
Member

Choose a reason for hiding this comment

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

I'd put this method on jsg::Lock rather than IsolateBase.

hmm.. really? I'd prefer it not be too visible on an API that is more generally used. Too easy for someone to see and abuse/misuse at some point.

I'm quite happy hiding this away on something somewhere it's less visible.

Copy link
Member

Choose a reason for hiding this comment

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

Too easy for someone to see and abuse/misuse at some point.

The name makes clear this is only for testing, and the implementation will not work if it's not in test mode. People "abusing" this isn't a real risk, but if it were, adding superficial road blocks doesn't seem like the right way to stop them. It just makes the code ugly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a fairly large warning on the definition in the header file. But I could see how it might be an issue, someone could use it intending that it run outside of tests and all of our testing would pass. But, the second it rolls out it would cause fatal crashes out in the wild. I do think that the name would steer people away from it, but it might be a good idea to rename to requestGcForTestingOnly so that it sticks out like a sore thumb in future code reviews if someone uses it.

Copy link
Member

Choose a reason for hiding this comment

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

You make a really good point, actually... the problem with throwing an exception when called outside of tests is that it'll pass tests and fail in prod.

This might argue for changing the logic so it merely logs an error and returns (without actually running a GC) if executed in production. At least then we'll see it in Sentry.

Another possibility is to use #ifdef KJ_DEBUG around the whole thing and all call sites, so that the method isn't even defined in release builds. Then if the release build compiles at all we know it's not using this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that the log and return w/o executing is the cleanest way of doing this. That way we don't have to maintain an implicit contract to call #ifdef KJ_DEBUG all over the place. Having Sentry ping the team is actually a really good way to ensure that the function is used correctly even if someone accidentally slips it into a PR that makes it past review.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to logging an error and returning before running the GC.

@Warfields
Copy link
Contributor Author

Warfields commented Nov 16, 2022 via email

@Warfields Warfields force-pushed the swarfield/testingGc branch 2 times, most recently from d97de85 to 35743b4 Compare November 16, 2022 19:51
@Warfields
Copy link
Contributor Author

Added the GC to all entry points now that the jsg::Lock call has solidified

src/workerd/jsg/setup.c++ Outdated Show resolved Hide resolved
src/workerd/jsg/jsg.h Outdated Show resolved Hide resolved
src/workerd/jsg/jsg.c++ Outdated Show resolved Hide resolved
src/workerd/jsg/jsg.h Outdated Show resolved Hide resolved
@Warfields Warfields force-pushed the swarfield/testingGc branch 3 times, most recently from 6837370 to af8f5d6 Compare November 17, 2022 23:58
@Warfields
Copy link
Contributor Author

Merge conflict fixed

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

LGTM once @kentonv is happy with it.

KJ_LOG(ERROR, "Test GC used while not in a test");
return;
}
IsolateBase::from(v8Isolate).requestGcForTesting();
Copy link
Member

Choose a reason for hiding this comment

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

You can just do v8Isolate->RequestGarbageCollectionForTesting(...) here and delete the method from IsolateBase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -5,9 +5,11 @@
#include "worker-entrypoint.h"
#include <capnp/message.h>
#include <workerd/jsg/jsg.h>
#include <workerd/jsg/setup.h>
Copy link
Member

Choose a reason for hiding this comment

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

I think this include is no longer used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@kentonv
Copy link
Member

kentonv commented Nov 18, 2022

Just a couple trivial nitpicks left. I'm about to head to the airport but James can merge when those are fixed.

@Warfields Warfields force-pushed the swarfield/testingGc branch 2 times, most recently from abced7c to 1d520cd Compare November 18, 2022 20:31
@Warfields Warfields merged commit 1f8a561 into main Nov 18, 2022
@Warfields Warfields deleted the swarfield/testingGc branch November 18, 2022 22:05
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

Successfully merging this pull request may close these issues.

4 participants