00:21 | <James M Snell> | honestly had not considered it previously but yes, that makes sense |
00:27 | <Justin Ridgewell> | Yah, we need a similar feature |
02:17 | <Chengzhong Wu> | I would avoid introducing any exception routing mechanism in the proposal, as documented as non-goals. But yes, I agree that we should clarify the " async context" when running the unhandled rejection event listeners, which would be necessary to associate the event with appropriate context values. This probably can be documented in a section dedicated for host integrations, in which we can also visit other host integration topics. |
02:45 | <littledan> | Yeah I think mechanically this would involve a host integration (since that is how uncaught rejections are reported) but maybe we want saving the context to just be part of the main spec algorithm, rather than done by a host hook, to clarify that it is expected to be in common. Anyway that is an editorial question—the important thing is establishing the shared utility and getting this into multiple environments |
02:45 | <littledan> | I would love to hear from James and Justin how this affects use cases/environments that you have in mind |
02:49 | <littledan> | Another thing which is important for Bloomberg and definitely not in the spec is V8’s API for dealing with all this. I imagine this is important for many server environments. Maybe we could collaborate on proposing such an API as part of this project |
02:49 | <littledan> | For example, wrap would have to look pretty different (maybe more like what jridgewell was proposing…) in the C++ API |
02:50 | <littledan> | We would want to make sure there is a C++ API for creating AsyncContexts, and doing run and wrap and get |
02:51 | <Justin Ridgewell> | I don't know what's possible on the C++ side of JS engines, but I imagine they can create closures? |
02:52 | <Justin Ridgewell> | The AsyncResource and static wrap method are mostly equivalent in functionality, it's just whether we allocate an object or a closure |
02:52 | <littledan> | Yeah I am thinking we want an API that doesn’t use closures on the C++ side and instead reifies the stack |
02:52 | <littledan> | So more like AsyncResource |
02:52 | <Justin Ridgewell> | For the unhandledrejection , I think this is part of the Host implementation, for the reason you mentioned (it's not spec'd in TC39) |
02:54 | <Justin Ridgewell> | I actually prefer my Snapshot (AsyncResource ) API, because it's easier it's easier to use other callbacks without reverting into a HOF |
02:54 | <Justin Ridgewell> | (https://gist.github.com/jridgewell/3970a3078ebfb90e90cd9d0a36ab9c08#file-async-context-ts-L7-L20) |
02:54 | <littledan> | For the |
02:55 | <Justin Ridgewell> | Do we specify things that we don't actually use? |
02:55 | <Justin Ridgewell> | I know for JobRecord, we have a [[HostDefined]] slot: https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-jobcallback-records |
02:55 | <littledan> | I actually prefer my |
02:56 | <Justin Ridgewell> | But we don't define what's actually inside it. |
02:56 | <littledan> | Yeah so this is an editorial decision, but if we don’t do it this way in the spec, we should at least communicate the intent some other way so engines can do the appropriate thing |
02:57 | <Chengzhong Wu> | I think it is fine to make the JS and C++ API choices separately. |
02:57 | <Chengzhong Wu> | They doesn't necessarily align. |
03:22 | <Justin Ridgewell> | I would love to hear from James and Justin how this affects use cases/environments that you have in mind console.log , actually it is the console.log . We try to associate every log with the request that causes it, so that we can present a unified logging UI. But we don't have a good way to associate the unhandledrejection call with the request, and it's no fun to polyfill in userland (every user-created promise must create 2, and native-created promises aren't always possible to detect) |
03:42 | <littledan> | I don’t quite understand, how are unhandled observed in your system? |
03:46 | <littledan> | In Bloomberg’s environment, one thing we want to use AsyncContext for is running multiple logical applications in the same thread and Isolate. We need to understand who is the “current application”. In the case of unhandled rejections, we want to kill the application that created the unhandled promise rejection. I understand our use case is a bit idiosyncratic so I wanted to understand if the same comes up for others. |
03:47 | <Justin Ridgewell> | PromiseRejectionEvent gets the promise , so we need to map from Promise to Request, which isn't foolproof (fetch returns a native promise, and we can only detect if you chain a .then() , which isn't guaranteed, so we have to patch every native promise returning function). So we attempt to get the context from the promise instance, and if not, we fall back to whichever request was last triggered by this user |
03:48 | <littledan> | I am not asking what the mechanism is in spec terms but what the APIs are and how users observe any of this |
03:48 | <Justin Ridgewell> | It's not user observable |
03:48 | <Justin Ridgewell> | The user just console.log s |
03:48 | <littledan> | Or, system observable—what is it that shows up in the logs? |
03:49 | <Justin Ridgewell> | I don't understand |
03:49 | <Justin Ridgewell> | Logs are associated to a request, might as well be per-request file on a disk |
03:50 | <littledan> | Ah, Ok, it is used to decide which file to route the log message to, where you are logging the event that a promise was rejected and unhandled. Is that it? |
03:51 | <littledan> | Or, which logical log stream, might not be filed |
03:51 | <Justin Ridgewell> | So we need to restore the context in case the user calls console.log again |
03:51 | <littledan> | Where would they call it from? |
03:51 | <Justin Ridgewell> | unhandledrejection 's handler |
03:51 | <littledan> | Ah OK you expose that event |
03:52 | <littledan> | And when handling that event, you need to route log messages |
03:52 | <littledan> | Is this it? |
03:52 | <Justin Ridgewell> | I think so |
03:55 | <littledan> | Where can I find docs about how Vercel exposes this? Is it the web’s event, Node’s, or something else? |
03:57 | <Justin Ridgewell> | I don't know if that's explicitly documented |
03:58 | <Justin Ridgewell> | (And I actually don't now the difference between our many edge runtimes, /shrug) |
04:01 | <littledan> | Well, I think documenting what our systems do and what we want them to do will be useful in aligning the implementations to do it. (But it is a lot of work and not needed for Stage 1.) anyway I am happy to hear a lot in common between us here. |