MCPcopy Index your code
hub / github.com/microsoft/vscode-cpptools / dispatch

Function dispatch

Extension/src/Utility/Eventing/dispatcher.ts:58–139  ·  view source on GitHub ↗

dispatch the applicable handlers for an event

(event: Event<any, TResult>)

Source from the content-addressed store, hash-verified

56
57/** dispatch the applicable handlers for an event */
58async function dispatch<TResult>(event: Event<any, TResult>): Promise<void> {
59 // check the sync handlers first
60 let resultValue: EventStatus | TResult | undefined = Continue;
61
62 // sync handlers run and await one at a time
63 // technically, it's possible for other events to run while a sync handler is running
64 // but that doesn't make any difference; the sync handler will still run to completion
65 // before the next handler is dispatched.
66 for (const [callback, captures] of getHandlers(event, syncHandlers)) {
67 try {
68 // keep track of which handlers are currently running
69 current.add(callback);
70
71 // call the callback, collate the result.
72 let r = callback(event as EventData, ...captures);
73 r = is.promise(r) ? await r.catch(e => {
74 console.error(e);
75 return undefined;
76 }) : r;
77
78 // if it is an event/request (as opposed to a notification), then process it.
79 if (is.promise(event.completed)) {
80 // if they returned some kind of value, then use that as the result, otherwise, use the default
81 resultValue = r as TResult | EventStatus;
82
83 if (is.cancelled(resultValue)) {
84 return event.completed.resolve(resultValue); // the event has been cancelled
85 }
86 }
87 } catch (e: any) {
88 console.error(e);
89 // if the handler throws, it isn't a reason to cancel the event
90 } finally {
91 // clear the callback from the current set
92 current.delete(callback);
93 }
94 }
95
96 // then the async handlers (for events with possible result handling)
97
98 if (!is.promise(event.completed)) {
99 // no event.completed, which means this is a notifier
100 // since notifiers are not cancellable, we can run them all in parallel
101 // and they don't need to worry about reentrancy
102 for (const [callback, captures] of getHandlers(event, asyncHandlers)) {
103 // call the event handler, but don't await it
104 // we don't care about the result, and we don't want to block
105 // (if the handler throws, too bad)
106 try { void callback(event as EventData, ...captures); } catch (e: any) {
107 console.error(e);
108 /* ignore */
109 }
110 }
111 return;
112 }
113 // this is an event/request (supports a result or cancellation)
114 // when these are called, they are permitted to work in parallel, and we await them all at the end
115 // the first one to respond with a non-Continue result will be the result of the event

Callers 3

drainFunction · 0.85
emitNowFunction · 0.85
notifyNowFunction · 0.85

Calls 11

getHandlersFunction · 0.85
promiseMethod · 0.80
errorMethod · 0.80
cancelledMethod · 0.80
deleteMethod · 0.80
pushMethod · 0.80
resolveMethod · 0.65
allMethod · 0.65
addMethod · 0.45
catchMethod · 0.45
finallyMethod · 0.45

Tested by

no test coverage detected