-
Notifications
You must be signed in to change notification settings - Fork 14
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
AsyncContext.{Snapshot,Variable}.prototype.run leave no room to specify receiver #80
Comments
Can you say more about what exactly those reservations are? What use case are you worried about ruling out here? |
Well, it is conceivable that the future evolution of the language will lead to a place where heavy use of receivers is commonplace. The existing primary indirect invocation facilities— From my perspective, the correct framing is not "what is lost by omitting a thisArg parameter?", but rather "what benefits justify its omission as something other than a gratuitous deviation?". |
A few points:
I don't think it's common to need to change the context, and when an object's context needs to be carried over to a method I'd much rather to see a dev write |
AsyncLocalStorage not taking a receiver is generally considered to be a mistake, which is why other related things like diagnostics_channel do take receivers. |
Is there a thread on that? |
We discussed this in today's meeting. No one voiced support for adding |
So the main reason for it is to enable store.run(...) to universally be able to replace a call without additional closures. For example, foo(bar, bar) can directly become store.run(context, foo, bar, bar). With instance methods we need to do something like store.run(context, instance.method.bind(instance), ...) which is a bit cumbersome but honestly not a huge deal. The one downside to not doing it though is that optimizations could likely be made to combine the call/apply that needs to happen with the context change. Could also probably do some magic to avoid dealing with iterators since arguments are passed positionally, just offset by two from the context object and function reference--might be able to do something like forwarding an offset pointer as args into the given function or things like that. My thinking with context runs has always been to treat it like a special case of function call/apply. |
In cases where code wants to invoke a method on an object, I'd much rather see I was the only one supportive of using variadic arg style for run, because I practice static functions as my default coding style. Everyone else just said to use an arrow closure. |
If this does come up, I'd prefer to address it by adding a |
For what's worth, my feeling is that most non-APM uses of AsyncContext don't see |
Yes, it is the case that often closures will be used by users, but they're also expensive if the run happens in a hot-path so I think we should consider offering tools that are at least capable of avoiding closure use. Having separate methods is perfectly reasonable to me, so long as the capability exists and we have an interface which can be optimized well for those that care about performance. |
Some discussion happened in Matrix yesterday. The other delegates agree with my opinions that supporting
I think "call-bound call" ( // Imagine this already exists
Reflect.call = Function.call.bind(Function.call);
snapshot.run(Reflect.call, obj.method, obj, arg1, arg2);
Very much agree.
This is a good point that I hadn't fully considered. I like seeing |
Passing in Reflect.call seems reasonable to me, so long as we keep the argument pass-through so we can avoid a closure wrap or a bind-and-then-call when we care about performance. My primary concern is that run be fast enough that we can use it liberally. Us APM vendors are going to be calling this all the time to store our current spans and other observability data so performance is absolutely critical to us. Random side thought: could a decorator transform any form of existing call (bare function, method call, etc.) in a way that V8 could apply the context around it without additional function bind/call/apply? That could be another interesting way to wrap an existing call in a context with minimal extra cost. 🤔 |
For the record, color me convinced. |
(originally posted by @gibson042 in tc39/proposal-promise-try#15 (comment))
The text was updated successfully, but these errors were encountered: