From e9f2a823d7fa2a640210089adbb42f437ffdb3af Mon Sep 17 00:00:00 2001 From: Mike Ratcliffe Date: Tue, 17 Sep 2024 12:03:10 +0100 Subject: [PATCH] fix: Properly close `adb` and `rclone` on exit Fixes #34 Cleanly closes `adb` and `rclone` connections when the application exits, ensuring resources are freed and preventing potential issues. This addresses a previous oversight where these connections weren't properly closed, potentially leading to resource leaks and unexpected behavior. Even though we free up the adb connection we don't close the server because other programs may be using the connection. The changes introduce a `destroy()` function in `tools.js` that handles the cleanup. This function is called when the application receives the "will-quit" event, ensuring that resources are freed before the application terminates. This change enhances the application's reliability and stability by preventing resource leaks and ensuring a clean exit. --- main.js | 5 +++++ tools.js | 47 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/main.js b/main.js index e75412d..a384169 100644 --- a/main.js +++ b/main.js @@ -538,6 +538,11 @@ async function startApp() { app.quit(); } }); + + app.on("will-quit", async () => { + console.log("will-quit"); + await tools.destroy(); + }); } startApp(); diff --git a/tools.js b/tools.js index c83b74e..c0d6511 100644 --- a/tools.js +++ b/tools.js @@ -30,7 +30,7 @@ const l = 32; const configLocationOld = path.join(global.homedir, "sidenoder-config.json"); const configLocation = path.join(global.sidenoderHome, "config.json"); -let agentOculus, agentSteam, agentSQ; +let agentOculus, agentSteam, agentSQ, tracker; init(); @@ -63,6 +63,7 @@ module.exports = { trackDevices, checkDeps, checkMount, + destroy, mount, killRClone, getDir, @@ -908,7 +909,7 @@ async function trackDevices() { await getDeviceSync(); try { - const tracker = await adb.trackDevices(); + tracker = await adb.trackDevices(); tracker.on("add", async (device) => { console.log("Device was plugged in", device.id); // await getDeviceSync(); @@ -926,8 +927,7 @@ async function trackDevices() { }); tracker.on("end", () => { - console.error("Tracking stopped"); - trackDevices(); + console.log("Tracking stopped"); }); } catch (err) { console.error("Something went wrong:", err.stack); @@ -935,6 +935,17 @@ async function trackDevices() { } } +async function destroy() { + try { + await killRClone(); + } catch (_err) { + console.log("rclone not started"); + } + + tracker.end(); + tracker = null; +} + async function appInfo(args) { const { res, pkg } = args; const app = KMETAS[pkg]; @@ -1495,7 +1506,7 @@ async function killRClone() { platform == "win" ? `taskkill.exe /F /T /IM rclone.exe` : `killall -9 rclone`; - console.log("try kill rclone"); + console.log("killing rclone"); return new Promise((res, rej) => { exec(killCmd, (error, stdout, stderr) => { if (error) { @@ -1624,17 +1635,23 @@ async function mount() { exec( `"${rcloneCmd}" ${mountCmd} --read-only --rc --rc-no-auth --config="${global.currentConfiguration.rcloneConf}" ${global.currentConfiguration.cfgSection}: "${global.mountFolder}"`, (error, stdout, stderr) => { - if (error) { - console.error("rclone error:", error); - if (RCLONE_ID != myId) error = false; - console.log({ RCLONE_ID, myId }); - win.webContents.send("check_mount", { success: false, error }); - // checkMount(); - /*if (error.message.search('transport endpoint is not connected')) { - console.log('GEVONDE'); - }*/ + try { + // We need to use a try/catch here because the callback may have been + // called after rclone has been closed. + if (error) { + if (!tracker) { + // Window is closing + return; + } + console.error("rclone error:", error); + if (RCLONE_ID != myId) error = false; + console.log({ RCLONE_ID, myId }); + win.webContents.send("check_mount", { success: false, error }); - return; + return; + } + } catch (e) { + // Do nothing } if (stderr) {