MCPcopy Index your code
hub / github.com/nodejs/node / makeAsyncRequest

Method makeAsyncRequest

lib/internal/modules/esm/hooks.js:567–613  ·  view source on GitHub ↗

* Invoke a remote method asynchronously. * @param {string} method Method to invoke * @param {any[]} [transferList] Objects in `args` to be transferred * @param {any[]} args Arguments to pass to `method` * @returns {Promise }

(method, transferList, ...args)

Source from the content-addressed store, hash-verified

565 * @returns {Promise<any>}
566 */
567 async makeAsyncRequest(method, transferList, ...args) {
568 this.waitForWorker();
569
570 MessageChannel ??= require('internal/worker/io').MessageChannel;
571 const asyncCommChannel = new MessageChannel();
572
573 // Pass work to the worker.
574 debug('post async message to worker', { method, args, transferList });
575 const finalTransferList = [asyncCommChannel.port2];
576 if (transferList) {
577 ArrayPrototypePushApply(finalTransferList, transferList);
578 }
579 this.#worker.postMessage({
580 __proto__: null,
581 method, args,
582 port: asyncCommChannel.port2,
583 }, finalTransferList);
584
585 if (this.#numberOfPendingAsyncResponses++ === 0) {
586 // On the next lines, the main thread will await a response from the worker thread that might
587 // come AFTER the last task in the event loop has run its course and there would be nothing
588 // left keeping the thread alive (and once the main thread dies, the whole process stops).
589 // However we want to keep the process alive until the worker thread responds (or until the
590 // event loop of the worker thread is also empty), so we ref the worker until we get all the
591 // responses back.
592 this.#worker.ref();
593 }
594
595 let response;
596 do {
597 debug('wait for async response from worker', { method, args });
598 await AtomicsWaitAsync(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, this.#workerNotificationLastId).value;
599 this.#workerNotificationLastId = AtomicsLoad(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);
600
601 response = receiveMessageOnPort(asyncCommChannel.port1);
602 } while (response == null);
603 debug('got async response from worker', { method, args }, this.#lock);
604
605 if (--this.#numberOfPendingAsyncResponses === 0) {
606 // We got all the responses from the worker, its job is done (until next time).
607 this.#worker.unref();
608 }
609
610 const body = this.#unwrapMessage(response);
611 asyncCommChannel.port1.close();
612 return body;
613 }
614
615 /**
616 * Invoke a remote method synchronously.

Callers 2

resolveMethod · 0.80
loadMethod · 0.80

Calls 9

waitForWorkerMethod · 0.95
#unwrapMessageMethod · 0.95
receiveMessageOnPortFunction · 0.85
refMethod · 0.65
closeMethod · 0.65
requireFunction · 0.50
debugFunction · 0.50
postMessageMethod · 0.45
unrefMethod · 0.45

Tested by

no test coverage detected