質問: await conn.query(sql2, [msg]); } catch (err) { console.log(err); } console.log(row2[0].data); }); } if (cluster.isMaster) { master(); } else { child(); } ```
回答: 解決しました。 cluster.on('online')が今回期待通りの動きをしてくれなかったのがそもそもの原因でした。 自分はclusterモジュールでの親子間の会話が、どちらから始まるのかがわからなかったのですが、今回のケースだと子から始めるとうまくいくとわかりました。 onlineイベントハンドラは単純に子プロセスに繋がれば親に教えてくれるだけなので、子へメッセージを渡してくれません。 そこで子が親にどつかれて何か返事をすれば、親プロセスが子にメッセージを渡すという方法に変えました。 下のようなTABLEがあったとします。 ``` MariaDB [test]> select * from hoge; +----+-----------------+ | id | fuga | +----+-----------------+ | 1 | 福沢諭吉 | | 2 | 夏目漱石 | | 3 | 野口英世 | | 4 | 新渡戸稲造 | | 5 | 樋口一葉 | +----+-----------------+ ``` 長くなるのでtry catchは省略しました。 ``` 'use strict'; const mysql = require('mysql2/promise'); const cluster = require('cluster'); const CPUs = require('os').cpus().length; // MySQL接続 const mysqlConf = { host: 'localhost', user: 'root', password: '', database: 'test', }; // 親プロセス const master = (conn) => { // 子からメッセージを受け取ったらMySQL接続 cluster.on('message', async (worker, msg) => { if (msg == '__REPLY__') { const sql = `SELECT fuga FROM hoge WHERE id = 2`; const [row] = await conn.query(sql); await worker.send(row[0].fuga); // 子に結果を渡す } }); // CPUの数だけフォークする for (let i = 0; i < CPUs; i++) { cluster.fork(); }; }; // 子プロセス const child = async (conn) => { // まず子から親に話しかける await process.send('__REPLY__'); // 親から返事を受け取ったらMySQL接続 process.on('message', async (msg) => { const result = `SELECT id, fuga FROM hoge WHERE fuga = ?`; const [rowResult] = await conn.query(result, [msg]); console.log(rowResult[0].id, rowResult[0].fuga); }); }; const main = async () => { const conn = await mysql.createConnection(mysqlConf); if (cluster.isMaster) master(conn); else child(conn); }; main(); ``` 実行結果 ``` 2 '夏目漱石' 2 '夏目漱石' 2 '夏目漱石' ``` 上記コードは接続を切っていないので、子プロセスが処理をすべて終えたら接続を切る必要があると思います。