-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
feat: expose setPromiseHook support #8209
Conversation
@bartlomieju I've changed the code to use the same machinery as js_recv_cb (I hope) and it works. Would you mind taking a look and making sure I understood it correctly? (to be clear: none of this is urgent) |
Question: I noticed I can't find references to other Deno.core stuff in the docs - where (at all?) should this be documented? |
d79f6dc
to
a6c056b
Compare
@benjamingr yeah, looks great! |
|
After a comment by @Flarna I am convinced the correct behaviour here is to allow multiple consumers - so I will replace the |
Also, on second thought I don't think it makes sense to unit test the behaviour in various cases I mentioned - but rather just our API surface (that is, test multiple consumers but not the exact promise-hook behaviour of promise subclasses for example) since it's tested on the V8 side. I would like to (eventually) see an integration test (with a complex promise context tracking use case) added but I think the tests I've added probably cover the basic cases. |
Ok, this is about ready for review now @bartlomieju thanks for the help! I feel strongly that this should be documented somewhere though, even if it just points to the V8 docs. I will happily write docs for it if you tell me where to put them :] |
@benjamingr @bartlomieju my opinion on the documentation is that we should move |
b22121c
to
0e0977a
Compare
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.
LGTM insofar I'm able to judge deno_core changes.
There's no mechanism to remove a promise hook again. Personally, I'm fine with leaving that out for now but I thought I'd mention it anyway.
for (i, hook_name) in | ||
["INIT", "RESOLVE", "BEFORE", "AFTER"].iter().enumerate() |
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.
for (i, hook_name) in | |
["INIT", "RESOLVE", "BEFORE", "AFTER"].iter().enumerate() | |
use v8::PromiseHookType as Ty; | |
for (hook_name, value) in | |
[("INIT", Ty::Init), ("RESOLVE", Ty::Resolve), ("BEFORE", Ty::Before), ("AFTER", Ty::After)].iter() |
(and maybe sort them)
If the original name is good enough you can also do:
for v in [Ty::After, Ty::Before, Ty::Init, Ty::Resolve].iter() {
let name = format!("{:?}", v);
// ...
}
let msg = v8::String::new(scope, "Invalid argument").unwrap(); | ||
let exception = v8::Exception::type_error(scope, msg); | ||
scope.throw_exception(exception); | ||
return; |
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.
For a future PR: consider moving this into a helper function. I count 5 or 6 other instances of the exact same pattern.
for js_promise_hook_cb_handle in state_rc.borrow().js_promise_hook_cb.iter() { | ||
js_promise_hook_cb_handle | ||
.get(scope) | ||
.call(scope, global.into(), &[hook_type, promise.into(), parent]) |
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.
Maybe use v8::undefined().into()
instead of global.into()
? Passing global
is not wrong and it seems to be the predominant pattern in deno_core but it's marginally less efficient.
js_promise_hook_cb_handle | ||
.get(scope) | ||
.call(scope, global.into(), &[hook_type, promise.into(), parent]) | ||
.unwrap(); |
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.
You should probably not unwrap here unless you want exceptions from the promise hook to terminate the process (with a fairly opaque error message.)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
Any news on this? (I'm interested in porting https://github.com/reframejs/wildcard-api to Deno but for that I need async hooks.) |
I am unfortunately in the process of switching jobs and moving houses and working on kids so I won't be able to work on this soon - other people are welcome to pick this up in the meantime. |
Ok I see, thanks for the update. |
@bnoordhuis @benjamingr maybe we should wait for the |
It most likely should |
Great, I'll close this PR for now, as it became stale. Once |
That sounds correct. |
Yes, I believe it is |
@benjamingr are you still interested in this functionality? I think we could try to tackle this once more with the API linked above. |
@bartlomieju I think Deno isn't actually production-ready until this API exists because it means it is impossible to write performance monitoring and analysis tools - it means users don't actually know where their production apps are spending time reliably which is a must for big real-world apps in my experience. So yes - since I would like to see Deno used for production apps I am interested in this :) I've had Deno apps running "in production" since 2018 but I haven't been able to use it for anything substantial because of the lack of monitoring capabilities. That said, I don't have time to work on this and I think your best approach to get this ready quickly would be to talk to APM vendors like New Relic or Elasticsearch and ask them to implement this. It's probably a good idea to have a discussion with APM vendors since they're the ones likely to eventually use this API the most. Alternatively Deno can choose not to expose this functionality to end-users directly and provide its own APM offering which is also fine probably. |
This is a draft PR to expose promise hooks enabling APMs.
My rust is bad, I haven't used it in ±2 years, any criticism and feedback about the code below is very appreciated.
Still missing and need to do:
Deno.core.setPromiseHook
then
ablesNice to have in the future but out of scope:
async_hooks
using this in deno_std