1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00
anytype-ts/electron/js/server.js
Andrew Simachev d05d46d5d8
fixes
2025-02-27 16:34:53 +01:00

140 lines
3.6 KiB
JavaScript

'use strict';
const path = require('path');
const childProcess = require('child_process');
const fs = require('fs');
const stdoutWebProxyPrefix = 'gRPC Web proxy started at: ';
const { app, dialog, shell } = require('electron');
const Util = require('./util.js');
let maxStdErrChunksBuffer = 10;
const winShutdownStdinMessage = 'shutdown\n';
class Server {
start (binPath, workingDir) {
console.log('[Server] start', binPath, workingDir);
const logPath = Util.logPath();
const env = process.env;
return new Promise((resolve, reject) => {
// stop will resolve immediately in case child process is not running
this.stop().then(() => {
this.isRunning = false;
try {
if (!process.stdout.isTTY) {
env['GOLOG_FILE'] = path.join(logPath, `anytype_${Util.dateForFile()}.log`);
};
this.cp = childProcess.spawn(binPath, [ '127.0.0.1:0', '127.0.0.1:0' ], { windowsHide: false, env });
} catch (err) {
console.error('[Server] Process start error: ', err.toString());
reject(err);
};
this.cp.on('error', err => {
this.isRunning = false;
console.error('[Server] Failed to start server: ', err.toString());
reject(err);
});
this.cp.stdout.on('data', data => {
const str = data.toString();
if (!this.isRunning && str && (str.indexOf(stdoutWebProxyPrefix) >= 0)) {
const regex = new RegExp(stdoutWebProxyPrefix + '([^\n^\s]+)');
this.address = 'http://' + regex.exec(str)[1];
this.isRunning = true;
resolve(true);
};
// Do not delete
console.log(str);
});
this.cp.stderr.on('data', data => {
const chunk = data.toString();
// max chunk size is 8192 bytes
// https://github.com/nodejs/node/issues/12921
// https://nodejs.org/api/buffer.html#buffer_class_property_buffer_poolsize
if (chunk.length > 8000) {
// in case we've got a crash lets change the max buffer to collect the whole stack trace
maxStdErrChunksBuffer = 1024; // 1024x8192 = 8 Mb max
};
if (!this.lastErrors) {
this.lastErrors = [];
} else
if (this.lastErrors.length >= maxStdErrChunksBuffer) {
this.lastErrors.shift();
};
this.lastErrors.push(chunk);
console.log(chunk);
});
this.cp.on('exit', () => {
if (this.stopTriggered) {
return;
};
this.isRunning = false;
const log = path.join(logPath, `crash_${Util.dateForFile()}.log`);
try {
fs.writeFileSync(log, this.lastErrors.join('\n'), 'utf-8');
} catch(e) {
console.log('[Server] Failed to save log file', log);
};
dialog.showErrorBox('Anytype helper crashed', 'You will be redirected to the crash log file. You can send it to Anytype developers by creating issue at https://community.anytype.io');
shell.showItemInFolder(log);
app.exit(0);
});
});
});
};
stop (signal) {
signal = String(signal || 'SIGTERM');
return new Promise((resolve, reject) => {
if (this.cp && this.isRunning) {
this.cp.on('exit', () => {
resolve(true);
this.isRunning = false;
this.cp = null;
});
this.stopTriggered = true;
if (process.platform === 'win32') {
// it is not possible to handle os signals on windows, so we can't do graceful shutdown on go side
this.cp.stdin.write(winShutdownStdinMessage);
} else {
this.cp.kill(signal);
};
} else {
resolve();
};
});
};
getAddress () {
return this.address;
};
setAddress (address) {
this.address = address;
};
};
module.exports = new Server();