in packages/dubbo-node/src/node-universal-client.ts [470:529]
function createSentinel(signal?: AbortSignal): Sentinel {
let res: (() => void) | undefined;
let rej: ((reason: ConnectError | unknown) => void) | undefined;
let resolved = false;
let rejected = false;
const p = new Promise<void>((resolve, reject) => {
res = resolve;
rej = reject;
});
const c: Pick<
Sentinel,
"resolve" | "isResolved" | "reject" | "isRejected" | "race"
> = {
resolve(): void {
if (!resolved && !rejected) {
resolved = true;
res?.();
}
},
isResolved() {
return resolved;
},
reject(reason): void {
if (!resolved && !rejected) {
rejected = true;
rej?.(connectErrorFromNodeReason(reason));
}
},
isRejected() {
return rejected;
},
async race<T>(promise: PromiseLike<T>): Promise<Awaited<T>> {
const r = await Promise.race([promise, p]);
if (r === undefined && resolved) {
throw new ConnectError("sentinel completed early", Code.Internal);
}
return r as Awaited<T>;
},
};
const s = Object.assign(p, c);
function onSignalAbort(this: AbortSignal) {
c.reject(getAbortSignalReason(this));
}
if (signal) {
if (signal.aborted) {
c.reject(getAbortSignalReason(signal));
} else {
signal.addEventListener("abort", onSignalAbort);
}
p.finally(() => signal.removeEventListener("abort", onSignalAbort)).catch(
() => {
// We intentionally swallow sentinel rejection - errors must
// propagate through the request or response iterables.
}
);
}
return s;
}