Ensure no ubuntu-server process is running at startup. Fixes #6584
Signed-off-by: Pedro Pombeiro <pombeirp@users.noreply.github.com>
This commit is contained in:
parent
73ccb44663
commit
50200404ce
|
@ -130,6 +130,7 @@ CMakeCache.txt
|
|||
**/CMakeFiles/
|
||||
/StatusImPackage/*
|
||||
*.AppImage
|
||||
Status-Windows-x86_64.zip
|
||||
/desktop/bin/*
|
||||
/desktop/lib/*
|
||||
/desktop/modules/*
|
||||
|
|
150
desktop/main.cpp
150
desktop/main.cpp
|
@ -38,8 +38,9 @@ static QStringList consoleOutputStrings;
|
|||
static QMutex consoleOutputMutex;
|
||||
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
bool ubuntuServerStarted = false;
|
||||
QProcess *g_ubuntuServerProcess = nullptr;
|
||||
bool nodeJsServerStarted = false;
|
||||
QProcess *g_nodeJsServerProcess = nullptr;
|
||||
#define NODEJS_SERVER_NAME "ubuntu-server"
|
||||
#endif
|
||||
|
||||
const int MAIN_WINDOW_WIDTH = 1024;
|
||||
|
@ -54,12 +55,12 @@ const char *LOG_FILE_PATH_ENV_VAR_NAME = "STATUS_LOG_PATH";
|
|||
// TODO: some way to change while running
|
||||
class ReactNativeProperties : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool liveReload READ liveReload WRITE setLiveReload NOTIFY
|
||||
liveReloadChanged)
|
||||
Q_PROPERTY(QUrl codeLocation READ codeLocation WRITE setCodeLocation NOTIFY
|
||||
codeLocationChanged)
|
||||
Q_PROPERTY(QString pluginsPath READ pluginsPath WRITE setPluginsPath NOTIFY
|
||||
pluginsPathChanged)
|
||||
Q_PROPERTY(
|
||||
bool liveReload READ liveReload WRITE setLiveReload NOTIFY liveReloadChanged)
|
||||
Q_PROPERTY(
|
||||
QUrl codeLocation READ codeLocation WRITE setCodeLocation NOTIFY codeLocationChanged)
|
||||
Q_PROPERTY(
|
||||
QString pluginsPath READ pluginsPath WRITE setPluginsPath NOTIFY pluginsPathChanged)
|
||||
Q_PROPERTY(
|
||||
QString executor READ executor WRITE setExecutor NOTIFY executorChanged)
|
||||
public:
|
||||
|
@ -155,26 +156,29 @@ void writeSingleLineLogFromJSServer(const QString &msg);
|
|||
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
|
||||
void runUbuntuServer();
|
||||
void killZombieJsServer();
|
||||
bool runNodeJsServer();
|
||||
|
||||
#endif
|
||||
|
||||
void loadFontsFromResources() {
|
||||
|
||||
QDirIterator it(":", QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
QString resourceFile = it.next();
|
||||
if (resourceFile.endsWith(".otf", Qt::CaseInsensitive) ||
|
||||
resourceFile.endsWith(".ttf", Qt::CaseInsensitive)) {
|
||||
QFontDatabase::addApplicationFont(resourceFile);
|
||||
qint32 fontId = QFontDatabase::addApplicationFont(resourceFile);
|
||||
if (Q_UNLIKELY(fontId == -1)) {
|
||||
qCDebug(STATUS) << "Unable to install font" << resourceFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exceptionPostHandledCallback() {
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
if (g_ubuntuServerProcess) {
|
||||
g_ubuntuServerProcess->kill();
|
||||
if (g_nodeJsServerProcess) {
|
||||
g_nodeJsServerProcess->kill();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -199,7 +203,6 @@ QString getDataStoragePath() {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
|
@ -207,7 +210,9 @@ int main(int argc, char **argv) {
|
|||
|
||||
QString appPath = QCoreApplication::applicationDirPath();
|
||||
QString dataStoragePath = getDataStoragePath();
|
||||
#ifndef BUILD_FOR_BUNDLE
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
killZombieJsServer();
|
||||
#else
|
||||
appPath.append(CRASH_REPORT_EXECUTABLE_RELATIVE_PATH);
|
||||
dataStoragePath = "";
|
||||
#endif
|
||||
|
@ -227,7 +232,15 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
runUbuntuServer();
|
||||
if (!runNodeJsServer()) {
|
||||
if (g_nodeJsServerProcess->state() == QProcess::NotRunning) {
|
||||
// If we failed to start the Node.js server (happens on Windows if the Node.js server process was previously running), let's do a final attempt
|
||||
delete g_nodeJsServerProcess;
|
||||
if (!runNodeJsServer()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.setWindowIcon(QIcon(":/icon.png"));
|
||||
#endif
|
||||
|
@ -285,11 +298,11 @@ int main(int argc, char **argv) {
|
|||
QString getLogFilePath() {
|
||||
QString logFilePath;
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
logFilePath = getDataStoragePath() + "/Status.log";
|
||||
logFilePath = getDataStoragePath() + QDir::separator() + "Status.log";
|
||||
#else
|
||||
logFilePath = qEnvironmentVariable(LOG_FILE_PATH_ENV_VAR_NAME, "");
|
||||
if (logFilePath.isEmpty()) {
|
||||
logFilePath = getDataStoragePath() + "/StatusDev.log";
|
||||
logFilePath = getDataStoragePath() + QDir::separator() + "StatusDev.log";
|
||||
}
|
||||
#endif
|
||||
return logFilePath;
|
||||
|
@ -310,49 +323,112 @@ void writeLogsToFile() {
|
|||
}
|
||||
|
||||
#ifdef BUILD_FOR_BUNDLE
|
||||
void runUbuntuServer() {
|
||||
g_ubuntuServerProcess = new QProcess();
|
||||
g_ubuntuServerProcess->setWorkingDirectory(getDataStoragePath());
|
||||
g_ubuntuServerProcess->setProgram(QGuiApplication::applicationDirPath() +
|
||||
"/ubuntu-server");
|
||||
QObject::connect(g_ubuntuServerProcess, &QProcess::errorOccurred,
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
bool IsProcessRunning(const wchar_t *processName) {
|
||||
bool exists = false;
|
||||
PROCESSENTRY32 entry = { sizeof(PROCESSENTRY32) };
|
||||
|
||||
HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (snapshot != NULL) {
|
||||
if (::Process32First(snapshot, &entry)) {
|
||||
do {
|
||||
if (!wcsicmp(entry.szExeFile, processName)) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
} while (::Process32Next(snapshot, &entry));
|
||||
}
|
||||
|
||||
::CloseHandle(snapshot);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void killZombieJsServer() {
|
||||
// Ensure that a zombie Node.js server process is not still running in the background before we spawn a new one
|
||||
QString cmd;
|
||||
#ifdef Q_OS_LINUX
|
||||
cmd = QString("pkill -f %1").arg(NODEJS_SERVER_NAME);
|
||||
#elif defined(Q_OS_MAC)
|
||||
cmd = QString("killall -9 %1").arg(NODEJS_SERVER_NAME);
|
||||
#elif defined(Q_OS_WIN)
|
||||
#define _CAT(A, B) A##B
|
||||
#define _W(A) _CAT(L, #A)
|
||||
WCHAR exeName[_MAX_PATH];
|
||||
wsprintf(exeName, L"%s.exe", _W(NODEJS_SERVER_NAME));
|
||||
if (IsProcessRunning(exeName)) {
|
||||
qCDebug(STATUS) << NODEJS_SERVER_NAME << "is running, killing it";
|
||||
::ShellExecuteW(NULL, NULL, L"tskill", _W(NODEJS_SERVER_NAME), NULL, SW_HIDE);
|
||||
} else {
|
||||
qCDebug(STATUS) << NODEJS_SERVER_NAME << "is not running";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cmd.isEmpty()) {
|
||||
qCDebug(STATUS) << "Running " << cmd;
|
||||
QByteArray cmdArray = cmd.toLocal8Bit();
|
||||
system(cmdArray.data());
|
||||
}
|
||||
}
|
||||
|
||||
bool runNodeJsServer() {
|
||||
g_nodeJsServerProcess = new QProcess();
|
||||
g_nodeJsServerProcess->setWorkingDirectory(getDataStoragePath());
|
||||
g_nodeJsServerProcess->setProgram(QGuiApplication::applicationDirPath() + QDir::separator() + NODEJS_SERVER_NAME);
|
||||
QObject::connect(g_nodeJsServerProcess, &QProcess::errorOccurred,
|
||||
[=](QProcess::ProcessError) {
|
||||
qCWarning(JSSERVER) << "process name: "
|
||||
<< qUtf8Printable(g_ubuntuServerProcess->program());
|
||||
<< qUtf8Printable(g_nodeJsServerProcess->program());
|
||||
qCWarning(JSSERVER) << "process error: "
|
||||
<< qUtf8Printable(g_ubuntuServerProcess->errorString());
|
||||
<< qUtf8Printable(g_nodeJsServerProcess->errorString());
|
||||
});
|
||||
|
||||
QObject::connect(
|
||||
g_ubuntuServerProcess, &QProcess::readyReadStandardOutput, [=] {
|
||||
writeLogFromJSServer(g_ubuntuServerProcess->readAllStandardOutput().trimmed());
|
||||
g_nodeJsServerProcess, &QProcess::readyReadStandardOutput, [=] {
|
||||
writeLogFromJSServer(g_nodeJsServerProcess->readAllStandardOutput().trimmed());
|
||||
});
|
||||
QObject::connect(
|
||||
g_ubuntuServerProcess, &QProcess::readyReadStandardError, [=] {
|
||||
g_nodeJsServerProcess, &QProcess::readyReadStandardError, [=] {
|
||||
QString output =
|
||||
g_ubuntuServerProcess->readAllStandardError().trimmed();
|
||||
g_nodeJsServerProcess->readAllStandardError().trimmed();
|
||||
writeLogFromJSServer(output);
|
||||
if (output.contains("Server starting")) {
|
||||
ubuntuServerStarted = true;
|
||||
nodeJsServerStarted = true;
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(QGuiApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||
[=]() {
|
||||
qCDebug(STATUS) << "Kill ubuntu server";
|
||||
g_ubuntuServerProcess->kill();
|
||||
qCDebug(STATUS) << "Kill node.js server process";
|
||||
g_nodeJsServerProcess->kill();
|
||||
});
|
||||
|
||||
qCDebug(STATUS) << "starting ubuntu server...";
|
||||
g_ubuntuServerProcess->start();
|
||||
qCDebug(STATUS) << "starting node.js server process...";
|
||||
g_nodeJsServerProcess->start();
|
||||
qCDebug(STATUS) << "wait for started...";
|
||||
|
||||
while (!ubuntuServerStarted) {
|
||||
if (g_nodeJsServerProcess->waitForReadyRead(10000)) {
|
||||
// We know that the process started, now wait until it communicates that it has started
|
||||
while (!nodeJsServerStarted) {
|
||||
QGuiApplication::processEvents();
|
||||
}
|
||||
|
||||
qCDebug(STATUS) << "waiting finished";
|
||||
|
||||
return true;
|
||||
} else {
|
||||
qCDebug(STATUS) << "failed to start process";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void writeLogFromJSServer(const QString &msg) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Build
|
||||
|
||||
```
|
||||
``` shell
|
||||
docker-compose -f docker-build/docker-compose.yml build
|
||||
```
|
||||
|
||||
|
@ -8,7 +8,7 @@ This will install all the required sdks, depending on the connection will take s
|
|||
|
||||
# Run
|
||||
|
||||
```
|
||||
``` shell
|
||||
docker-compose -f docker-build/docker-compose.yml up
|
||||
```
|
||||
|
||||
|
@ -18,7 +18,7 @@ You need to connect your device and accept the key.
|
|||
|
||||
After the figwheel prompt you can install the application running:
|
||||
|
||||
```
|
||||
``` shell
|
||||
docker-compose -f docker-build/docker-compose.yml exec adbd make run-android
|
||||
```
|
||||
|
||||
|
|
|
@ -207,11 +207,12 @@ function compile() {
|
|||
-DJS_BUNDLE_PATH="$JS_BUNDLE_PATH" \
|
||||
-DCMAKE_CXX_FLAGS:='-DBUILD_FOR_BUNDLE=1' || exit 1
|
||||
fi
|
||||
make -j5 || exit 1
|
||||
make -S -j5 || exit 1
|
||||
popd
|
||||
}
|
||||
|
||||
function bundleWindows() {
|
||||
local buildType="$1"
|
||||
# TODO: Produce a setup program instead of a ZIP
|
||||
pushd $WORKFOLDER
|
||||
rm -rf Windows
|
||||
|
@ -227,9 +228,10 @@ function bundleWindows() {
|
|||
pushd Windows
|
||||
cp $STATUSREACTPATH/.env .
|
||||
mkdir -p assets/resources notifier
|
||||
cp $STATUSREACTPATH/node_modules/node-notifier/vendor/snoreToast/SnoreToast.exe \
|
||||
$STATUSREACTPATH/node_modules/node-notifier/vendor/notifu/*.exe \
|
||||
cp $STATUSREACTPATH/node_modules/node-notifier/vendor/notifu/*.exe \
|
||||
notifier/
|
||||
cp $STATUSREACTPATH/node_modules/node-notifier/vendor/snoreToast/SnoreToast.exe \
|
||||
.
|
||||
cp -r $STATUSREACTPATH/resources/fonts \
|
||||
$STATUSREACTPATH/resources/icons \
|
||||
$STATUSREACTPATH/resources/images \
|
||||
|
@ -237,7 +239,14 @@ function bundleWindows() {
|
|||
local _bin=$STATUSREACTPATH/desktop/bin
|
||||
rm -rf $_bin/cmake_install.cmake $_bin/Makefile $_bin/CMakeFiles $_bin/Status_autogen && \
|
||||
cp -r $_bin/* .
|
||||
zip -mr9 ../../Status-Windows-x86_64.zip .
|
||||
|
||||
local zipOptions="-mr9"
|
||||
if [ -z $buildType ]; then
|
||||
zipOptions="-mr1"
|
||||
elif [ "$buildType" = "pr" ]; then
|
||||
zipOptions="-mr2"
|
||||
fi
|
||||
zip $zipOptions ../../Status-Windows-x86_64.zip .
|
||||
popd
|
||||
rm -rf Windows
|
||||
popd
|
||||
|
|
Loading…
Reference in New Issue