前提
Node.jsでは難しい処理をGoで実装してもらい、それをDLLで呼び出せるようになっているのですがそれを呼び出すためにnode-ffiを使用しており非同期的に大量に処理を行いたいのですが何かPythonで非同期処理内にブロッキングされる同期処理を含めた時のようなプログラム全体が一時停止するような挙動が起こっています。
これを改善する方法はNode.jsにありますか?Pythonなどではプロセスやスレッドを分けることで解決することが出来ると思うのですが
実現したいこと
DLL内の関数を呼び出してる間も他の処理を続行させたい
発生している問題・エラーメッセージ
Goで書かれたDLL内の関数にはウェブリクエストを行うものがありそれらをPromise.allなどで大量に関数を呼び出し待機したいのですがaxiosなどの全てJavaScriptで書かれたコードよりも著しく低速かつ一斉に処理が完了するためDLL内の関数の処理が順番に行われている気がします。
DLLの処理がJavaScriptを止め、その処理が終わり次第JavaScriptの処理が始まり一斉に結果がconsole.logされることからそうではないかと思っております。
またほかにもDiscord.jsなどで他の処理を行いながら呼び出すとBotが停止することなどからブロッキングされていると考えました
該当のソースコード
全てのコードを載せることが難しいため問題であると思われる処理のみを参考程度に書き直し抜粋して記載します。
javascript
1import ffi from 'ffi-napi'; 2 3const library = ffi.Library('example.dll', { 4 request: ['string', ['string']] 5}); 6 7const a = async() => { 8 const r = library.request('nanika'); //ここでブロッキングされている(おそらく) 9 console.log(r); //上の処理が実行されている間はここにたどり着けない 10} 11 12new Array(1000).fill(0).forEach(() => a());
試したこと
そもそもほぼすべてがCallbackやAsync的な言語のためブロッキングすること自体を初めて知り記事などでもほぼ解説されていないため言語仕様的な物から説明していただけると助かります。
Pythonは同期がメインになっているだけで非同期が使用できる、全てが非同期に出来るわけではなくスレッドなどを活用する必要があるように、JavaScriptも非同期がメインになっているだけで同期処理も使用でき、同じように同期処理を実行している間は他の処理なども全て停止させるのかなど認識が甘いところがありました
今思えばfs.readFileSyncなども同期処理でただファイル読み込みには大した時間がかからないから気になっていないだけなのかなと思い、そういった場合だと大量にファイルを読み込んだ場合にはもちろんブロックする時間が長くなりパフォーマンスに多大な影響を与える場合があります。
こういった説明はあまりされておらずただトップレベルawaitが出来ない環境で順番に処理を実行するにはとても有効なものだと思っていました、ですがそうではないのでしょうか?
補足情報(FW/ツールのバージョンなど)
Node.js v18.12.1
追記
https://nodejs.org/ja/docs/guides/blocking-vs-non-blocking/
公式でこのようなブログがありました
認識は間違ってなさそうです、私が甘いようです
ですが、これならばSyncは完全にすべての処理を停止させますがasync/awaitの場合は確かに順番に処理をさせることが出来ますが他の処理は止まりません
この場合、async/awaitを同期化と呼ぶのはいかがなものなのでしょうか?
syncとasync/awaitでは意味が全然違いますが両方とも同期処理と呼ばれてしまっては混同してしまいます。
私はasync/awaitはあくまでも非同期処理で待機をすることが出来るものであって他の処理まで止めるものではないという認識がありました、それに対しSyncは完全にその処理中にそのスレッド、プロセスごと停止させるのだと思います。
これらを一括りにして同期化と呼ばれるとSyncはブロッキングしないものかと思ってしまっていました
回答3件
あなたの回答
tips
プレビュー