From c552309febf53578b10bcf9cb09c87d5c390adc0 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Thu, 21 Mar 2024 09:36:51 +0900 Subject: [PATCH 1/4] Changed the start-up file to launch daemon process --- packages/gui/src/util/chiaEnvironment.js | 40 ++++++------------------ 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/packages/gui/src/util/chiaEnvironment.js b/packages/gui/src/util/chiaEnvironment.js index 158b451014..f05db7ecb3 100644 --- a/packages/gui/src/util/chiaEnvironment.js +++ b/packages/gui/src/util/chiaEnvironment.js @@ -8,9 +8,9 @@ const path = require('path'); const PY_MAC_DIST_FOLDER = '../../../app.asar.unpacked/daemon'; const PY_WIN_DIST_FOLDER = '../../../app.asar.unpacked/daemon'; -const PY_DIST_FILE = 'daemon'; -const PY_FOLDER = '../../../chia/daemon'; -const PY_MODULE = 'server'; // without .py suffix +const PY_DIST_FILE = 'chia'; +const PY_FOLDER = '../../../chia/cmds'; +const PY_MODULE = 'chia'; // without .py suffix let pyProc = null; let haveCert = null; @@ -67,26 +67,6 @@ const getChiaVersion = () => { return version; }; -const spawnChildProcess = (command, args = [], options = undefined) => { - // As of Feb 11 2024, there is a bug in Electron that prevents electron from exiting when a child process is spawned and detached. - // This is a workaround for that bug. - if (process.platform === 'linux') { - // https://github.com/electron/electron/issues/34808#issuecomment-1275530924 - return childProcess.spawn( - '/bin/bash', - [ - '-c', - 'for fd in $(ls /proc/$$/fd); do case "$fd" in 0|1|2|255) ;; *) eval "exec $fd<&-" ;; esac; done; exec "$@"', - '--', - command, - ...args, - ], - options, - ); - } - return childProcess.spawn(command, args, options); -}; - const startChiaDaemon = () => { const script = getScriptPath(PY_DIST_FILE); const processOptions = {}; @@ -103,7 +83,7 @@ const startChiaDaemon = () => { processOptions.shell = true; } else { processOptions.detached = true; - processOptions.stdio = 'ignore'; + // processOptions.stdio = 'ignore'; processOptions.windowsHide = true; } pyProc = null; @@ -111,26 +91,26 @@ const startChiaDaemon = () => { try { console.info('Running python executable: '); if (processOptions.stdio === 'ignore') { - const subProcess = spawnChildProcess(script, ['--wait-for-unlock'], processOptions); + const subProcess = childProcess.spawn(script, ['start', 'daemon'], processOptions); subProcess.unref(); } else { const Process = childProcess.spawn; - pyProc = new Process(script, ['--wait-for-unlock'], processOptions); + pyProc = new Process(script, ['start', 'daemon'], processOptions); } } catch (e) { console.info('Running python executable: Error: '); - console.info(`Script ${script}`); + console.info(`Script: ${script} start daemon`); } } else { console.info('Running python script'); - console.info(`Script ${script}`); + console.info(`Script: python ${script} start daemon`); if (processOptions.stdio === 'ignore') { - const subProcess = spawnChildProcess('python', [script, '--wait-for-unlock'], processOptions); + const subProcess = childProcess.spawn('python', [script, 'start', 'daemon'], processOptions); subProcess.unref(); } else { const Process = childProcess.spawn; - pyProc = new Process('python', [script, '--wait-for-unlock'], processOptions); + pyProc = new Process('python', [script, 'start', 'daemon'], processOptions); } } if (pyProc != null && processOptions.stdio !== 'ignore') { From d8045643ff9c5b862f9cb622a0b481960aeb3979 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Thu, 21 Mar 2024 20:28:58 +0900 Subject: [PATCH 2/4] Made the code more readable --- packages/gui/src/util/chiaEnvironment.js | 120 ++++++++++++----------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/packages/gui/src/util/chiaEnvironment.js b/packages/gui/src/util/chiaEnvironment.js index f05db7ecb3..8c62876d73 100644 --- a/packages/gui/src/util/chiaEnvironment.js +++ b/packages/gui/src/util/chiaEnvironment.js @@ -8,9 +8,11 @@ const path = require('path'); const PY_MAC_DIST_FOLDER = '../../../app.asar.unpacked/daemon'; const PY_WIN_DIST_FOLDER = '../../../app.asar.unpacked/daemon'; -const PY_DIST_FILE = 'chia'; -const PY_FOLDER = '../../../chia/cmds'; -const PY_MODULE = 'chia'; // without .py suffix +const PY_DIST_EXECUTABLE = 'chia'; +const PY_DIST_EXEC_ARGS = Object.freeze(['start', 'daemon']); + +const PY_DEV_EXECUTABLE = '../../../chia/cmds/main.py'; +const PY_DEV_EXEC_ARGS = Object.freeze([PY_DEV_EXECUTABLE, 'start', 'daemon']); let pyProc = null; let haveCert = null; @@ -34,13 +36,6 @@ const getExecutablePath = (dist_file) => { return path.join(__dirname, PY_MAC_DIST_FOLDER, dist_file); }; -const getScriptPath = (dist_file) => { - if (!guessPackaged()) { - return path.join(PY_FOLDER, `${PY_MODULE}.py`); - } - return getExecutablePath(dist_file); -}; - const getChiaVersion = () => { let version = null; const exePath = getExecutablePath('chia'); @@ -68,7 +63,6 @@ const getChiaVersion = () => { }; const startChiaDaemon = () => { - const script = getScriptPath(PY_DIST_FILE); const processOptions = {}; if (process.platform === 'win32') { // We want to detach child daemon process from parent GUI process. @@ -86,81 +80,91 @@ const startChiaDaemon = () => { // processOptions.stdio = 'ignore'; processOptions.windowsHide = true; } + pyProc = null; + if (guessPackaged()) { + const executablePath = getExecutablePath(PY_DIST_EXECUTABLE); + console.info('Running python executable: '); + try { - console.info('Running python executable: '); if (processOptions.stdio === 'ignore') { - const subProcess = childProcess.spawn(script, ['start', 'daemon'], processOptions); + const subProcess = childProcess.spawn(executablePath, PY_DIST_EXEC_ARGS, processOptions); subProcess.unref(); } else { const Process = childProcess.spawn; - pyProc = new Process(script, ['start', 'daemon'], processOptions); + pyProc = new Process(executablePath, PY_DIST_EXEC_ARGS, processOptions); } } catch (e) { console.info('Running python executable: Error: '); - console.info(`Script: ${script} start daemon`); + console.info(`Script: ${executablePath} ${PY_DIST_EXEC_ARGS.join(' ')}`); } } else { console.info('Running python script'); - console.info(`Script: python ${script} start daemon`); + console.info(`Script: python ${PY_DEV_EXEC_ARGS.join(' ')}`); if (processOptions.stdio === 'ignore') { - const subProcess = childProcess.spawn('python', [script, 'start', 'daemon'], processOptions); + const subProcess = childProcess.spawn('python', PY_DEV_EXEC_ARGS, processOptions); subProcess.unref(); } else { const Process = childProcess.spawn; - pyProc = new Process('python', [script, 'start', 'daemon'], processOptions); + pyProc = new Process('python', PY_DEV_EXEC_ARGS, processOptions); } } - if (pyProc != null && processOptions.stdio !== 'ignore') { - pyProc.stdout.setEncoding('utf8'); - - pyProc.stdout.on('data', (data) => { - if (!haveCert) { - process.stdout.write('No cert\n'); - // listen for ssl path message - try { - const strArr = data.toString().split('\n'); - for (let i = 0; i < strArr.length; i++) { - const str = strArr[i]; - try { - const json = JSON.parse(str); - global.cert_path = json.cert; - global.key_path = json.key; - // TODO Zlatko: cert_path and key_path were undefined. Prefixed them with global, which changes functionality. - // Do they even need to be globals? - if (global.cert_path && global.key_path) { - haveCert = true; - process.stdout.write('Have cert\n'); - return; - } - } catch (e) { - // Do nothing + + if (!pyProc) { + throw new Error('Failed to start chia daemon'); + } + + if (processOptions.stdio === 'ignore') { + return; + } + + pyProc.stdout.setEncoding('utf8'); + + pyProc.stdout.on('data', (data) => { + if (!haveCert) { + process.stdout.write('No cert\n'); + // listen for ssl path message + try { + const strArr = data.toString().split('\n'); + for (let i = 0; i < strArr.length; i++) { + const str = strArr[i]; + try { + const json = JSON.parse(str); + global.cert_path = json.cert; + global.key_path = json.key; + // TODO Zlatko: cert_path and key_path were undefined. Prefixed them with global, which changes functionality. + // Do they even need to be globals? + if (global.cert_path && global.key_path) { + haveCert = true; + process.stdout.write('Have cert\n'); + return; } + } catch (e) { + // Do nothing } - } catch (e) { - // Do nothing } + } catch (e) { + // Do nothing } + } - process.stdout.write(data.toString()); - }); + process.stdout.write(data.toString()); + }); - pyProc.stderr.setEncoding('utf8'); - pyProc.stderr.on('data', (data) => { - // Here is where the error output goes - process.stdout.write(`stderr: ${data.toString()}`); - }); + pyProc.stderr.setEncoding('utf8'); + pyProc.stderr.on('data', (data) => { + // Here is where the error output goes + process.stdout.write(`stderr: ${data.toString()}`); + }); - pyProc.on('close', (code) => { - // Here you can get the exit code of the script - console.info(`closing code: ${code}`); - }); + pyProc.on('close', (code) => { + // Here you can get the exit code of the script + console.info(`closing code: ${code}`); + }); - console.info('child process success'); - } - // pyProc.unref(); + console.info('child process success'); }; module.exports = { From 7e5482ee26389b33e27b6841d3cefd8c1a84a957 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Fri, 22 Mar 2024 00:12:05 +0900 Subject: [PATCH 3/4] Updated `PY_DEV_EXECUTABLE` --- packages/gui/src/util/chiaEnvironment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gui/src/util/chiaEnvironment.js b/packages/gui/src/util/chiaEnvironment.js index 8c62876d73..1781fcb35c 100644 --- a/packages/gui/src/util/chiaEnvironment.js +++ b/packages/gui/src/util/chiaEnvironment.js @@ -11,7 +11,7 @@ const PY_WIN_DIST_FOLDER = '../../../app.asar.unpacked/daemon'; const PY_DIST_EXECUTABLE = 'chia'; const PY_DIST_EXEC_ARGS = Object.freeze(['start', 'daemon']); -const PY_DEV_EXECUTABLE = '../../../chia/cmds/main.py'; +const PY_DEV_EXECUTABLE = `../../../venv/${process.platform === 'win32' ? 'Scripts/chia.exe' : 'bin/chia'}`; const PY_DEV_EXEC_ARGS = Object.freeze([PY_DEV_EXECUTABLE, 'start', 'daemon']); let pyProc = null; From 1e69fd5db219b9f0260017821785fbe14831f034 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Fri, 22 Mar 2024 00:41:10 +0900 Subject: [PATCH 4/4] Removed procOptions --- packages/gui/src/util/chiaEnvironment.js | 40 +++--------------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/packages/gui/src/util/chiaEnvironment.js b/packages/gui/src/util/chiaEnvironment.js index 1781fcb35c..22531e958c 100644 --- a/packages/gui/src/util/chiaEnvironment.js +++ b/packages/gui/src/util/chiaEnvironment.js @@ -63,24 +63,6 @@ const getChiaVersion = () => { }; const startChiaDaemon = () => { - const processOptions = {}; - if (process.platform === 'win32') { - // We want to detach child daemon process from parent GUI process. - // You may think `detached: true` will do but it shows blank terminal on Windows. - // In order to hide the blank terminal while detaching child process, - // {detached: false, windowsHide: false, shell: true} works which is exact opposite of what we expect - // Please see the comment below for more details. - // https://github.com/nodejs/node/issues/21825#issuecomment-503766781 - processOptions.detached = false; - processOptions.stdio = 'ignore'; - processOptions.windowsHide = false; - processOptions.shell = true; - } else { - processOptions.detached = true; - // processOptions.stdio = 'ignore'; - processOptions.windowsHide = true; - } - pyProc = null; if (guessPackaged()) { @@ -88,13 +70,8 @@ const startChiaDaemon = () => { console.info('Running python executable: '); try { - if (processOptions.stdio === 'ignore') { - const subProcess = childProcess.spawn(executablePath, PY_DIST_EXEC_ARGS, processOptions); - subProcess.unref(); - } else { - const Process = childProcess.spawn; - pyProc = new Process(executablePath, PY_DIST_EXEC_ARGS, processOptions); - } + const Process = childProcess.spawn; + pyProc = new Process(executablePath, PY_DIST_EXEC_ARGS); } catch (e) { console.info('Running python executable: Error: '); console.info(`Script: ${executablePath} ${PY_DIST_EXEC_ARGS.join(' ')}`); @@ -103,23 +80,14 @@ const startChiaDaemon = () => { console.info('Running python script'); console.info(`Script: python ${PY_DEV_EXEC_ARGS.join(' ')}`); - if (processOptions.stdio === 'ignore') { - const subProcess = childProcess.spawn('python', PY_DEV_EXEC_ARGS, processOptions); - subProcess.unref(); - } else { - const Process = childProcess.spawn; - pyProc = new Process('python', PY_DEV_EXEC_ARGS, processOptions); - } + const Process = childProcess.spawn; + pyProc = new Process('python', PY_DEV_EXEC_ARGS); } if (!pyProc) { throw new Error('Failed to start chia daemon'); } - if (processOptions.stdio === 'ignore') { - return; - } - pyProc.stdout.setEncoding('utf8'); pyProc.stdout.on('data', (data) => {