Processes handling improvements

- added remained .tmp files removing before launcher closes
- improved `Process.run()`, fixed its work with AppImages
  also now it finds the real process id by the `pgrep -P` command
  which is a lot faster and better
This commit is contained in:
Observer KRypt0n_ 2022-01-04 22:49:30 +02:00
parent 34a48ed6a9
commit e244bca62b
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
2 changed files with 54 additions and 27 deletions

View file

@ -16,6 +16,7 @@
import Debug from './ts/core/Debug'; import Debug from './ts/core/Debug';
import Downloader from './ts/core/Downloader'; import Downloader from './ts/core/Downloader';
import IPC from './ts/core/IPC'; import IPC from './ts/core/IPC';
import Process from './ts/neutralino/Process';
import Gear from './assets/images/gear.png'; import Gear from './assets/images/gear.png';
import GearActive from './assets/images/gear-active.png'; import GearActive from './assets/images/gear-active.png';
@ -45,11 +46,17 @@
constants.paths.launcherDir.then(async (path) => { constants.paths.launcherDir.then(async (path) => {
const time = new Date; const time = new Date;
// Remove IPC file
await IPC.purge(); await IPC.purge();
// Turn off Discord RPC
if (launcher.rpc) if (launcher.rpc)
await launcher.rpc.stop(true); await launcher.rpc.stop(true);
// Remove .tmp files from the launcher folder
Neutralino.os.execCommand(`rm -f "${Process.addSlashes(`${path}/*.tmp`)}"`);
// Create logs folder if it doesn't exist
Neutralino.filesystem.getStats(`${path}/logs`) Neutralino.filesystem.getStats(`${path}/logs`)
.then(() => saveLog()) .then(() => saveLog())
.catch(async () => { .catch(async () => {
@ -58,12 +65,14 @@
saveLog(); saveLog();
}); });
// Save logs
const saveLog = async () => { const saveLog = async () => {
const log = Debug.get().join("\r\n"); const log = Debug.get().join("\r\n");
if (log != '') if (log != '')
await Neutralino.filesystem.writeFile(`${path}/logs/${time.getDate()}-${time.getMonth() + 1}-${time.getFullYear()}-${time.getHours()}-${time.getMinutes()}-${time.getSeconds()}.log`, log); await Neutralino.filesystem.writeFile(`${path}/logs/${time.getDate()}-${time.getMonth() + 1}-${time.getFullYear()}-${time.getHours()}-${time.getMinutes()}-${time.getSeconds()}.log`, log);
// And close the launcher when they was saved
Neutralino.app.exit(); Neutralino.app.exit();
}; };
}); });

View file

@ -5,8 +5,22 @@ declare const Neutralino;
declare const NL_CWD; declare const NL_CWD;
type ProcessOptions = { type ProcessOptions = {
/**
* Environment variables
*/
env?: object; env?: object;
/**
* Current working directory for the running process
*/
cwd?: string; cwd?: string;
/**
* Interval between tries to find started process id
*
* @default 50
*/
childInterval?: number;
}; };
class Process class Process
@ -180,7 +194,6 @@ class Process
{ {
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const tmpFile = `${await constants.paths.launcherDir}/${10000 + Math.round(Math.random() * 89999)}.tmp`; const tmpFile = `${await constants.paths.launcherDir}/${10000 + Math.round(Math.random() * 89999)}.tmp`;
const originalCommand = command.replaceAll(/\\|"|'/gm, '');
// Set env variables // Set env variables
if (options.env) if (options.env)
@ -191,40 +204,45 @@ class Process
} }
// Set output redirection to the temp file // Set output redirection to the temp file
command = `${command} > "${this.addSlashes(tmpFile)}" 2>&1 &`; command = `${command} > "${this.addSlashes(tmpFile)}" 2>&1`;
// Set current working directory // Set current working directory
if (options.cwd) if (options.cwd)
command = `cd "${this.addSlashes(options.cwd)}" && ${command}`; command = `cd "${this.addSlashes(options.cwd)}" && ${command}`;
// And run the command // And run the command
const process = await Neutralino.os.execCommand(command); const process = await Neutralino.os.execCommand(command, {
background: true
// Because we're redirecting process output to the file
// it creates another process and our process.pid is not correct
// so we need to find real process id
const processes = ((await Neutralino.os.execCommand('ps -a -S')).stdOut as string).split(/\r\n|\r|\n/);
let processId = process.pid;
for (const line of processes)
if (line.replaceAll(/\\|"|'/gm, '').includes(originalCommand))
{
processId = parseInt(line.split(' ').filter((word) => word != '')[0]);
break;
}
Debug.log({
function: 'Process.run',
message: {
'running command': command,
'cwd': options.cwd,
...options.env
}
}); });
resolve(new Process(processId, tmpFile)); const childFinder = async () => {
const childProcess = await Neutralino.os.execCommand(`pgrep -P ${process.pid}`);
// Child wasn't found
if (childProcess.stdOut == '')
setTimeout(childFinder, options.childInterval ?? 50);
// Otherwise return its id
else
{
const processId = parseInt(childProcess.stdOut.substring(0, childProcess.stdOut.length - 1));
Debug.log({
function: 'Process.run',
message: {
'running command': command,
'cwd': options.cwd,
'initial process id': process.pid,
'real process id': processId,
...options.env
}
});
resolve(new Process(processId, tmpFile));
}
};
setTimeout(childFinder, options.childInterval ?? 50);
}); });
} }