-
Notifications
You must be signed in to change notification settings - Fork 343
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
Enable FinalizationRegistry #3560
base: main
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,15 @@ | |
|
||
#include "io-context.h" | ||
|
||
#include "libplatform/libplatform.h" | ||
#include "v8-platform.h" // NOLINT(build/include_directory) | ||
#include "v8config.h" // NOLINT(build/include_directory) | ||
#include <workerd/io/io-gate.h> | ||
#include <workerd/io/worker.h> | ||
#include <workerd/jsg/jsg.h> | ||
#include <workerd/util/sentry.h> | ||
#include <workerd/util/uncaught-exception-source.h> | ||
#include <workerd/jsg/setup.h> | ||
|
||
#include <kj/debug.h> | ||
|
||
|
@@ -1155,6 +1159,17 @@ void IoContext::runImpl(Runnable& runnable, | |
} | ||
} | ||
}); | ||
|
||
if (!isCurrentNull()) { | ||
KJ_LOG(ERROR, "IoContext not-null before running PumpMessageLoop()"); | ||
} else { | ||
worker->runInLockScope(lockType, [&](Worker::Lock& lock) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taking a new lock here, immediately after releasing the previous one, is expensive. You should find a way to run PumpMessageLoop() just before releasing the previous lock instead. |
||
jsg::Lock& js = lock; | ||
auto& system = const_cast<jsg::V8System&>(js.getV8System()); | ||
KJ_DBG(js.v8Isolate); | ||
while (v8::platform::PumpMessageLoop(&system.getDefaultPlatform(), js.v8Isolate, v8::platform::MessageLoopBehavior::kDoNotWait)) {} | ||
jasnell marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels wrong for this code to be aware of the v8::Platform. Knowledge of how the platform is set up (and even the fact that we use the default platform) should be encapsulated inside JSG. To that end, perhaps There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this actually the right time to call PumpMessageLoop -- at the end of every single Arguably it might be preferable if we invoked There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that we likely need to find a better place for this. We can end up running ctx.run quite a few times during a request. |
||
}); | ||
} | ||
} | ||
|
||
static constexpr auto kAsyncIoErrorMessage = | ||
|
@@ -1182,6 +1197,10 @@ bool IoContext::hasCurrent() { | |
return threadLocalRequest != nullptr; | ||
} | ||
|
||
bool IoContext::isCurrentNull() { | ||
return threadLocalRequest == nullptr; | ||
} | ||
ketanhwr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
bool IoContext::isCurrent() { | ||
return this == threadLocalRequest; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2276,6 +2276,8 @@ class ExternalMemoryAdjustment final { | |
// Isolate<TypeWrapper>::Lock. Usually this is only done in top-level code, and the Lock is | ||
// passed down to everyone else from there. See setup.h for details. | ||
|
||
class V8System; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should be exposing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I agree. |
||
|
||
class Lock { | ||
public: | ||
// The underlying V8 isolate, useful for directly calling V8 APIs. Hopefully, this is rarely | ||
|
@@ -2288,6 +2290,8 @@ class Lock { | |
return context; | ||
} | ||
|
||
virtual const V8System& getV8System() = 0; | ||
|
||
// Get the current Lock for the given V8 isolate. Segfaults if the isolate is not locked. | ||
// | ||
// This method is intended to be used in callbacks from V8 that pass an isolate pointer but | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1431,7 +1431,7 @@ class ResourceWrapper { | |
// We do not allow use of WeakRef or FinalizationRegistry because they introduce | ||
// non-deterministic behavior. | ||
check(global->Delete(context, v8StrIntern(isolate, "WeakRef"_kj))); | ||
check(global->Delete(context, v8StrIntern(isolate, "FinalizationRegistry"_kj))); | ||
//check(global->Delete(context, v8StrIntern(isolate, "FinalizationRegistry"_kj))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'd be enabling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current plan is to only enable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there actually anything more needed to enable WeakRef? If it's just a matter of removing the line above, I think we should do it in this change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes it should work by just removing the line, although @harrishancock was concerned about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My concern isn't immediate notification, but lack of control over when notifications occur. With FinalizationRegistry, we can control exactly when finalization callbacks are scheduled. With WeakRef, we have no control over when they appear empty -- that's entirely up to the GC. So, if controlling the timing of GC observation is important for risk mitigation, then enabling WeakRef is strictly higher risk than enabling FinalizationRegistry. That said, I'd love to just accept the risk and enable WeakRef and be done with it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm good with accepting the risk as I thinks it is likely quite minimal. @kentonv ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably needs a compat flag as I suspect there are people that check for the existence of these APIs and use them if they are available -- making them suddenly available would therefore cause such workers to start taking a new code path which could end up being broken. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that was something on my mind as well, had a brief discussion with @mikenomitch about placing this behind a compat date/flag. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes me sad, but yes, compat flag absolutely needed. I've seen such checks in the wild a few times now. |
||
|
||
// Store a pointer to this object in slot 1, to be extracted in callbacks. | ||
context->SetAlignedPointerInEmbedderData(1, ptr.get()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to revert this sample back to its original state when this is done. Most likely it would make sense to have this as a separate example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like more of a test. Should it be converted to a
wd-test
?